/pidgin/main: 3590ceb242b5: Gadu-Gadu: multilogon / other sessio...
Tomasz Wasilczyk
twasilczyk at pidgin.im
Tue Jan 7 13:02:29 EST 2014
Changeset: 3590ceb242b51c40cf0f6ed78b66b5ff880d04b4
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-01-07 19:02 +0100
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/3590ceb242b5
Description:
Gadu-Gadu: multilogon / other sessions dialog implementation. Refs #14366
diffstat:
libpurple/protocols/gg/Makefile.am | 2 +
libpurple/protocols/gg/Makefile.mingw | 1 +
libpurple/protocols/gg/gg.c | 9 +
libpurple/protocols/gg/keymapper.c | 79 +++++++++++++
libpurple/protocols/gg/keymapper.h | 21 +++
libpurple/protocols/gg/multilogon.c | 194 +++++++++++++++++++++++++++++++--
libpurple/protocols/gg/multilogon.h | 2 +-
libpurple/protocols/gg/utils.c | 14 ++
libpurple/protocols/gg/utils.h | 2 +
9 files changed, 308 insertions(+), 16 deletions(-)
diffs (truncated from 443 to 300 lines):
diff --git a/libpurple/protocols/gg/Makefile.am b/libpurple/protocols/gg/Makefile.am
--- a/libpurple/protocols/gg/Makefile.am
+++ b/libpurple/protocols/gg/Makefile.am
@@ -73,6 +73,8 @@ GGSOURCES = \
html.h \
image.c \
image.h \
+ keymapper.c \
+ keymapper.h \
libgadu-events.c \
libgadu-events.h \
libgaduw.c \
diff --git a/libpurple/protocols/gg/Makefile.mingw b/libpurple/protocols/gg/Makefile.mingw
--- a/libpurple/protocols/gg/Makefile.mingw
+++ b/libpurple/protocols/gg/Makefile.mingw
@@ -55,6 +55,7 @@ C_SRC = \
gg.c \
html.c \
image.c \
+ keymapper.c \
libgadu-events.c \
libgaduw.c \
message-prpl.c \
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -888,6 +888,11 @@ static void ggp_keepalive(PurpleConnecti
}
}
+static void ggp_action_multilogon(PurplePluginAction *action)
+{
+ ggp_multilogon_dialog((PurpleConnection *)action->context);
+}
+
static void ggp_action_chpass(PurplePluginAction *action)
{
ggp_account_chpass((PurpleConnection *)action->context);
@@ -917,6 +922,10 @@ static GList *ggp_actions(PurplePlugin *
ggp_action_chpass);
m = g_list_append(m, act);
+ act = purple_plugin_action_new(_("Show other sessions"),
+ ggp_action_multilogon);
+ m = g_list_append(m, act);
+
act = purple_plugin_action_new(_("Show status only for buddies"),
ggp_action_status_broadcasting);
m = g_list_append(m, act);
diff --git a/libpurple/protocols/gg/keymapper.c b/libpurple/protocols/gg/keymapper.c
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/keymapper.c
@@ -0,0 +1,79 @@
+#include "keymapper.h"
+
+/* The problem: we want to convert 64-bit unique integers into unique gpointer
+ * keys (that may be 32-bit or 64-bit, or whatever else). We also want to
+ * convert it back.
+ *
+ * The idea: let's store every value in our internal memory. Then, its address
+ * can be also an unique key. We also need a map, to quickly figure out the
+ * address for any previously stored value.
+ *
+ * The naming problem: values becames the keys and vice-versa.
+ */
+
+/* TODO
+ * For a 64-bit gpointer, keymapper could just do nothing and return the value
+ * as a key. But it have to be figured out at a compile time.
+ */
+
+struct _ggp_keymapper
+{
+ /* Table keys: pointers to 64-bit mapped *values*.
+ * Table values: keys (gpointers) corresponding to mapped values.
+ *
+ * Ultimately, both keys and values are the same pointers.
+ *
+ * Yes, it's hard to comment it well enough.
+ */
+ GHashTable *val_to_key;
+};
+
+ggp_keymapper *
+ggp_keymapper_new(void)
+{
+ ggp_keymapper *km;
+
+ km = g_new0(ggp_keymapper, 1);
+ km->val_to_key = g_hash_table_new_full(g_int64_hash, g_int64_equal,
+ g_free, NULL);
+
+ return km;
+}
+
+void
+ggp_keymapper_free(ggp_keymapper *km)
+{
+ if (km == NULL)
+ return;
+
+ g_hash_table_destroy(km->val_to_key);
+ g_free(km);
+}
+
+gpointer
+ggp_keymapper_to_key(ggp_keymapper *km, uint64_t val)
+{
+ uint64_t *key;
+
+ g_return_val_if_fail(km != NULL, NULL);
+
+ key = g_hash_table_lookup(km->val_to_key, &val);
+ if (key)
+ return key;
+
+ key = g_new(uint64_t, 1);
+ *key = val;
+
+ g_hash_table_insert(km->val_to_key, key, key);
+
+ return key;
+}
+
+uint64_t
+ggp_keymapper_from_key(ggp_keymapper *km, gpointer key)
+{
+ g_return_val_if_fail(km != NULL, 0);
+ g_return_val_if_fail(key != NULL, 0);
+
+ return *((uint64_t*)key);
+}
diff --git a/libpurple/protocols/gg/keymapper.h b/libpurple/protocols/gg/keymapper.h
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/keymapper.h
@@ -0,0 +1,21 @@
+#ifndef _GGP_KEYMAPPER_H
+#define _GGP_KEYMAPPER_H
+
+typedef struct _ggp_keymapper ggp_keymapper;
+
+#include <purple.h>
+
+ggp_keymapper *
+ggp_keymapper_new(void);
+
+void
+ggp_keymapper_free(ggp_keymapper *km);
+
+gpointer
+ggp_keymapper_to_key(ggp_keymapper *km, uint64_t val);
+
+/* The key have to be valid. */
+uint64_t
+ggp_keymapper_from_key(ggp_keymapper *km, gpointer key);
+
+#endif /* _GGP_KEYMAPPER_H */
diff --git a/libpurple/protocols/gg/multilogon.c b/libpurple/protocols/gg/multilogon.c
--- a/libpurple/protocols/gg/multilogon.c
+++ b/libpurple/protocols/gg/multilogon.c
@@ -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 @@ ggp_multilogon_get_mldata(PurpleConnecti
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);
More information about the Commits
mailing list