libpurple/protocols/gg/multilogon.c

changeset 35144
3590ceb242b5
parent 35139
c30787ce6256
child 35149
7804dd798227
--- a/libpurple/protocols/gg/multilogon.c	Tue Jan 07 18:53:13 2014 +0100
+++ b/libpurple/protocols/gg/multilogon.c	Tue Jan 07 19:02:19 2014 +0100
@@ -32,12 +32,25 @@
 #include <debug.h>
 
 #include "gg.h"
+#include "keymapper.h"
 #include "utils.h"
 #include "message-prpl.h"
 
+typedef struct
+{
+	uint64_t id;
+	uint32_t remote_addr;
+	gchar *name;
+	time_t logon_time;
+} ggp_multilogon_session_info;
+
 struct _ggp_multilogon_session_data
 {
 	int session_count;
+	ggp_multilogon_session_info *sessions;
+	PurpleRequestDatasheet *sheet_handle;
+	gpointer dialog_handle;
+	ggp_keymapper *sid_mapper;
 };
 
 static inline ggp_multilogon_session_data *
@@ -52,41 +65,192 @@
 	return accdata->multilogon_data;
 }
 
-void ggp_multilogon_setup(PurpleConnection *gc)
+void
+ggp_multilogon_setup(PurpleConnection *gc)
 {
 	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	
+
 	ggp_multilogon_session_data *mldata =
 		g_new0(ggp_multilogon_session_data, 1);
 	accdata->multilogon_data = mldata;
+
+	mldata->sid_mapper = ggp_keymapper_new();
 }
 
-void ggp_multilogon_cleanup(PurpleConnection *gc)
+static void
+ggp_multilogon_free_sessions(PurpleConnection *gc)
 {
 	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
+	int i;
+
+	for (i = 0; i < mldata->session_count; i++)
+		g_free(mldata->sessions[i].name);
+	g_free(mldata->sessions);
+
+	mldata->sessions = NULL;
+	mldata->session_count = 0;
+}
+
+void
+ggp_multilogon_cleanup(PurpleConnection *gc)
+{
+	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
+
+	if (mldata->dialog_handle) {
+		purple_request_close(PURPLE_REQUEST_FIELDS,
+			mldata->dialog_handle);
+		mldata->dialog_handle = NULL;
+	}
+
+	ggp_multilogon_free_sessions(gc);
+	ggp_keymapper_free(mldata->sid_mapper);
 	g_free(mldata);
 }
 
-void ggp_multilogon_info(PurpleConnection *gc,
-	struct gg_event_multilogon_info *info)
+static uint64_t
+ggp_multilogon_sid_from_libgadu(gg_multilogon_id_t lsid)
+{
+	uint64_t sid;
+
+	memcpy(&sid, lsid.id, sizeof(uint64_t));
+
+	return sid;
+}
+
+static gg_multilogon_id_t
+ggp_multilogon_sid_to_libgadu(uint64_t sid)
+{
+	gg_multilogon_id_t lsid;
+
+	memcpy(lsid.id, &sid, sizeof(uint64_t));
+
+	return lsid;
+}
+
+void
+ggp_multilogon_fill_sessions(PurpleRequestDatasheet *sheet,
+	PurpleConnection *gc)
+{
+	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
+	ggp_keymapper *km = mldata->sid_mapper;
+	int i;
+
+	purple_request_datasheet_record_mark_all_for_rem(sheet);
+
+	for (i = 0; i < mldata->session_count; i++) {
+		ggp_multilogon_session_info *sess = &mldata->sessions[i];
+		PurpleRequestDatasheetRecord *rec;
+
+		rec = purple_request_datasheet_record_add(sheet,
+			ggp_keymapper_to_key(km, sess->id));
+
+		purple_request_datasheet_record_set_string_data(rec, 0,
+			ggp_ipv4_to_str(sess->remote_addr));
+		purple_request_datasheet_record_set_string_data(rec, 1,
+			purple_date_format_full(localtime(&sess->logon_time)));
+		purple_request_datasheet_record_set_string_data(rec, 2,
+			sess->name);
+	}
+
+	purple_request_datasheet_record_remove_marked(sheet);
+}
+
+void
+ggp_multilogon_info(PurpleConnection *gc, struct gg_event_multilogon_info *info)
 {
 	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
 	int i;
-	
-	purple_debug_info("gg", "ggp_multilogon_info: session list changed\n");
-	for (i = 0; i < info->count; i++)
-	{
-		purple_debug_misc("gg", "ggp_multilogon_info: "
-			"session [%s] logged in at %lu\n",
-			info->sessions[i].name,
-			(unsigned long)info->sessions[i].logon_time);
+
+	ggp_multilogon_free_sessions(gc);
+
+	purple_debug_info("gg", "ggp_multilogon_info: session list changed "
+		"(count now: %d)\n", info->count);
+
+	mldata->sessions = g_new(ggp_multilogon_session_info, info->count);
+	for (i = 0; i < info->count; i++) {
+		struct gg_multilogon_session *lsess = &info->sessions[i];
+		ggp_multilogon_session_info *psess = &mldata->sessions[i];
+
+		psess->id = ggp_multilogon_sid_from_libgadu(lsess->id);
+		psess->remote_addr = lsess->remote_addr;
+		psess->name = g_strdup(lsess->name);
+		psess->logon_time = lsess->logon_time;
 	}
 
 	mldata->session_count = info->count;
+
+	if (mldata->sheet_handle != NULL)
+		ggp_multilogon_fill_sessions(mldata->sheet_handle, gc);
+}
+
+void
+ggp_multilogon_disconnect(PurpleRequestDatasheetRecord *rec, gpointer _gc)
+{
+	PurpleConnection *gc = _gc;
+	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
+	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
+	uint64_t sid;
+	gpointer key;
+
+	key = purple_request_datasheet_record_get_key(rec);
+	sid = ggp_keymapper_from_key(mldata->sid_mapper, key);
+
+	gg_multilogon_disconnect(accdata->session,
+		ggp_multilogon_sid_to_libgadu(sid));
+
+	purple_request_datasheet_record_remove(
+		purple_request_datasheet_record_get_datasheet(rec), key);
 }
 
-int ggp_multilogon_get_session_count(PurpleConnection *gc)
+void
+ggp_multilogon_dialog(PurpleConnection *gc)
 {
 	ggp_multilogon_session_data *mldata = ggp_multilogon_get_mldata(gc);
-	return mldata->session_count;
+	PurpleRequestField *field;
+	PurpleRequestFields *fields;
+	PurpleRequestFieldGroup *group;
+	PurpleRequestCommonParameters *cpar;
+	PurpleRequestDatasheet *sheet;
+	PurpleRequestDatasheetAction *action;
+	gpointer dialog_handle;
+
+	if (mldata->dialog_handle != NULL)
+		return;
+
+	fields = purple_request_fields_new();
+	group = purple_request_field_group_new(NULL);
+	purple_request_fields_add_group(fields, group);
+
+	sheet = purple_request_datasheet_new();
+	purple_request_datasheet_add_column(sheet,
+		PURPLE_REQUEST_DATASHEET_COLUMN_STRING, _("IP"));
+	purple_request_datasheet_add_column(sheet,
+		PURPLE_REQUEST_DATASHEET_COLUMN_STRING, _("Logon time"));
+	purple_request_datasheet_add_column(sheet,
+		PURPLE_REQUEST_DATASHEET_COLUMN_STRING, _("Session"));
+
+	action = purple_request_datasheet_action_new();
+	purple_request_datasheet_action_set_label(action, _("Disconnect"));
+	purple_request_datasheet_action_set_cb(action,
+		ggp_multilogon_disconnect, gc);
+	purple_request_datasheet_add_action(sheet, action);
+	ggp_multilogon_fill_sessions(sheet, gc);
+
+	field = purple_request_field_datasheet_new("sessions", NULL, sheet);
+	purple_request_field_group_add_field(group, field);
+
+	cpar = purple_request_cpar_new();
+	purple_request_cpar_set_icon(cpar, PURPLE_REQUEST_ICON_DIALOG);
+
+	dialog_handle = purple_request_fields(gc,
+		_("Other Gadu-Gadu sessions"), NULL, NULL, fields,
+		NULL, NULL, _("Close"), NULL,
+		cpar, NULL);
+	mldata->sheet_handle = sheet;
+	mldata->dialog_handle = dialog_handle;
+
+	purple_request_add_close_notify(dialog_handle,
+		purple_callback_set_zero, &mldata->sheet_handle);
+	purple_request_add_close_notify(dialog_handle,
+		purple_callback_set_zero, &mldata->dialog_handle);
 }

mercurial