Refactored oscar to use the new protocol API soc.2013.gobjectification.plugins

Wed, 28 Aug 2013 03:37:22 +0530

author
Ankit Vani <a@nevitus.org>
date
Wed, 28 Aug 2013 03:37:22 +0530
branch
soc.2013.gobjectification.plugins
changeset 36590
e77919ff5e74
parent 36589
4a12e889d1fd
child 36591
6428f75bffc8

Refactored oscar to use the new protocol API

libpurple/protocols/oscar/libaim.c file | annotate | diff | comparison | revisions
libpurple/protocols/oscar/libaim.h file | annotate | diff | comparison | revisions
libpurple/protocols/oscar/libicq.c file | annotate | diff | comparison | revisions
libpurple/protocols/oscar/libicq.h file | annotate | diff | comparison | revisions
libpurple/protocols/oscar/oscar.c file | annotate | diff | comparison | revisions
libpurple/protocols/oscar/oscar.h file | annotate | diff | comparison | revisions
libpurple/protocols/oscar/oscarcommon.h file | annotate | diff | comparison | revisions
--- a/libpurple/protocols/oscar/libaim.c	Wed Aug 28 00:13:52 2013 +0530
+++ b/libpurple/protocols/oscar/libaim.c	Wed Aug 28 03:37:22 2013 +0530
@@ -24,96 +24,46 @@
  * which contains all the shared implementation code with libicq
  */
 
+#include "core.h"
 #include "plugins.h"
+#include "signals.h"
 
+#include "libaim.h"
 #include "oscarcommon.h"
-#include "oscar.h"
+
+static PurpleProtocol *my_protocol = NULL;
 
-static PurpleProtocol protocol =
+static void
+aim_protocol_base_init(AIMProtocolClass *klass)
 {
-	"prpl-aim",				/* id */
-	"AIM",					/* name */
-	sizeof(PurpleProtocol),       /* struct_size */
-	OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE | OPT_PROTO_AUTHORIZATION_DENIED_MESSAGE,
-	NULL,					/* user_splits */
-	NULL,					/* protocol_options */
-	{"gif,jpeg,bmp,ico", 0, 0, 64, 64, 7168, PURPLE_ICON_SCALE_SEND | PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */
-	oscar_get_actions,		/* get_actions */
-	oscar_list_icon_aim,	/* list_icon */
-	oscar_list_emblem,		/* list_emblems */
-	oscar_status_text,		/* status_text */
-	oscar_tooltip_text,		/* tooltip_text */
-	oscar_status_types,		/* status_types */
-	oscar_blist_node_menu,	/* blist_node_menu */
-	oscar_chat_info,		/* chat_info */
-	oscar_chat_info_defaults, /* chat_info_defaults */
-	oscar_login,			/* login */
-	oscar_close,			/* close */
-	oscar_send_im,			/* send_im */
-	oscar_set_info,			/* set_info */
-	oscar_send_typing,		/* send_typing */
-	oscar_get_info,			/* get_info */
-	oscar_set_status,		/* set_status */
-	oscar_set_idle,			/* set_idle */
-	oscar_change_passwd,	/* change_passwd */
-	oscar_add_buddy,		/* add_buddy */
-	NULL,					/* add_buddies */
-	oscar_remove_buddy,		/* remove_buddy */
-	NULL,					/* remove_buddies */
-	oscar_add_permit,		/* add_permit */
-	oscar_add_deny,			/* add_deny */
-	oscar_rem_permit,		/* rem_permit */
-	oscar_rem_deny,			/* rem_deny */
-	oscar_set_aim_permdeny,	/* set_permit_deny */
-	oscar_join_chat,		/* join_chat */
-	NULL,					/* reject_chat */
-	oscar_get_chat_name,	/* get_chat_name */
-	oscar_chat_invite,		/* chat_invite */
-	oscar_chat_leave,		/* chat_leave */
-	NULL,					/* chat_whisper */
-	oscar_send_chat,		/* chat_send */
-	oscar_keepalive,		/* keepalive */
-	NULL,					/* register_user */
-	NULL,					/* get_cb_info */
-	oscar_alias_buddy,		/* alias_buddy */
-	oscar_move_buddy,		/* group_buddy */
-	oscar_rename_group,		/* rename_group */
-	NULL,					/* buddy_free */
-	oscar_convo_closed,		/* convo_closed */
-	oscar_normalize,		/* normalize */
-	oscar_set_icon,			/* set_buddy_icon */
-	oscar_remove_group,		/* remove_group */
-	NULL,					/* get_cb_real_name */
-	NULL,					/* set_chat_topic */
-	NULL,					/* find_blist_chat */
-	NULL,					/* roomlist_get_list */
-	NULL,					/* roomlist_cancel */
-	NULL,					/* roomlist_expand_category */
-	oscar_can_receive_file,	/* can_receive_file */
-	oscar_send_file,		/* send_file */
-	oscar_new_xfer,			/* new_xfer */
-	oscar_offline_message,	/* offline_message */
-	NULL,					/* whiteboard_protocol_ops */
-	NULL,					/* send_raw */
-	NULL,					/* roomlist_room_serialize */
-	NULL,					/* unregister_user */
-	NULL,					/* send_attention */
-	NULL,					/* get_attention_types */
-	NULL,					/* get_account_text_table */
-	NULL,					/* initiate_media */
-	NULL,					/* get_media_caps */
-	NULL,					/* get_moods */
-	NULL,					/* set_public_alias */
-	NULL,					/* get_public_alias */
-	oscar_get_max_message_size		/* get_max_message_size */
-};
+	PurpleProtocolClass *proto_class = PURPLE_PROTOCOL_CLASS(klass);
+	PurpleAccountOption *option;
+
+	proto_class->id        = AIM_ID;
+	proto_class->name      = AIM_NAME;
+
+	option = purple_account_option_string_new(_("Server"), "server", oscar_get_login_server(FALSE, TRUE));
+	proto_class->protocol_options = g_list_append(proto_class->protocol_options, option);
+}
+
+static void
+aim_protocol_interface_init(PurpleProtocolInterface *iface)
+{
+	iface->list_icon            = oscar_list_icon_aim;
+	iface->add_permit           = oscar_add_permit;
+	iface->rem_permit           = oscar_rem_permit;
+	iface->set_permit_deny      = oscar_set_aim_permdeny;
+	iface->get_max_message_size = oscar_get_max_message_size;
+}
+
+static void aim_protocol_base_finalize(AIMProtocolClass *klass) { }
 
 static PurplePluginInfo *
 plugin_query(GError **error)
 {
 	return purple_plugin_info_new(
-		"id",           "prpl-aim",
-		"name",         "AIM",
+		"id",           AIM_ID,
+		"name",         AIM_NAME,
 		"version",      DISPLAY_VERSION,
 		"category",     N_("Protocol"),
 		"summary",      N_("AIM Protocol Plugin"),
@@ -129,8 +79,14 @@
 static gboolean
 plugin_load(PurplePlugin *plugin, GError **error)
 {
-	oscar_init(&protocol, FALSE);
-	purple_protocols_add(&protocol);
+	my_protocol = purple_protocols_add(AIM_TYPE_PROTOCOL);
+	if (!my_protocol) {
+		g_set_error(error, AIM_DOMAIN, 0, _("Failed to add aim protocol"));
+		return FALSE;
+	}
+
+	purple_signal_connect(purple_get_core(), "uri-handler", my_protocol,
+		PURPLE_CALLBACK(oscar_uri_handler), NULL);
 
 	return TRUE;
 }
@@ -138,9 +94,15 @@
 static gboolean
 plugin_unload(PurplePlugin *plugin, GError **error)
 {
-	purple_protocols_remove(&protocol);
+	if (!purple_protocols_remove(my_protocol)) {
+		g_set_error(error, AIM_DOMAIN, 0, _("Failed to remove aim protocol"));
+		return FALSE;
+	}
 
 	return TRUE;
 }
 
+PURPLE_PROTOCOL_DEFINE_EXTENDED(AIMProtocol, aim_protocol,
+                                OSCAR_TYPE_PROTOCOL, 0);
+
 PURPLE_PLUGIN_INIT(aim, plugin_query, plugin_load, plugin_unload);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/oscar/libaim.h	Wed Aug 28 03:37:22 2013 +0530
@@ -0,0 +1,53 @@
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ *
+ */
+#ifndef _LIBAIM_H_
+#define _LIBAIM_H_
+
+#include "oscar.h"
+
+#define AIM_ID     "prpl-aim"
+#define AIM_NAME   "AIM"
+#define AIM_DOMAIN (g_quark_from_static_string(AIM_ID))
+
+#define AIM_TYPE_PROTOCOL             (aim_protocol_get_type())
+#define AIM_PROTOCOL(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), AIM_TYPE_PROTOCOL, AIMProtocol))
+#define AIM_PROTOCOL_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), AIM_TYPE_PROTOCOL, AIMProtocolClass))
+#define AIM_IS_PROTOCOL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), AIM_TYPE_PROTOCOL))
+#define AIM_IS_PROTOCOL_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), AIM_TYPE_PROTOCOL))
+#define AIM_PROTOCOL_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), AIM_TYPE_PROTOCOL, AIMProtocolClass))
+
+typedef struct _AIMProtocol
+{
+	OscarProtocol parent;
+} AIMProtocol;
+
+typedef struct _AIMProtocolClass
+{
+	OscarProtocolClass parent_class;
+} AIMProtocolClass;
+
+/**
+ * Returns the GType for the AIMProtocol object.
+ */
+GType aim_protocol_get_type(void);
+
+#endif /* _LIBAIM_H_ */
--- a/libpurple/protocols/oscar/libicq.c	Wed Aug 28 00:13:52 2013 +0530
+++ b/libpurple/protocols/oscar/libicq.c	Wed Aug 28 03:37:22 2013 +0530
@@ -24,10 +24,15 @@
  * which contains all the shared implementation code with libaim
  */
 
+#include "core.h"
 #include "plugins.h"
+#include "signals.h"
 
+#include "libicq.h"
 #include "oscarcommon.h"
 
+static PurpleProtocol *my_protocol = NULL;
+
 static GHashTable *
 icq_get_account_text_table(PurpleAccount *account)
 {
@@ -44,91 +49,39 @@
 	return 2346;
 }
 
-static PurpleProtocol protocol =
+static void
+icq_protocol_base_init(ICQProtocolClass *klass)
 {
-	"prpl-icq",				/* id */
-	"ICQ",					/* name */
-	sizeof(PurpleProtocol),       /* struct_size */
-	OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE | OPT_PROTO_AUTHORIZATION_DENIED_MESSAGE,
-	NULL,					/* user_splits */
-	NULL,					/* protocol_options */
-	{"gif,jpeg,bmp,ico", 0, 0, 64, 64, 7168, PURPLE_ICON_SCALE_SEND | PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */
-	oscar_get_actions,		/* get_actions */
-	oscar_list_icon_icq,	/* list_icon */
-	oscar_list_emblem,		/* list_emblems */
-	oscar_status_text,		/* status_text */
-	oscar_tooltip_text,		/* tooltip_text */
-	oscar_status_types,		/* status_types */
-	oscar_blist_node_menu,	/* blist_node_menu */
-	oscar_chat_info,		/* chat_info */
-	oscar_chat_info_defaults, /* chat_info_defaults */
-	oscar_login,			/* login */
-	oscar_close,			/* close */
-	oscar_send_im,			/* send_im */
-	oscar_set_info,			/* set_info */
-	oscar_send_typing,		/* send_typing */
-	oscar_get_info,			/* get_info */
-	oscar_set_status,		/* set_status */
-	oscar_set_idle,			/* set_idle */
-	oscar_change_passwd,	/* change_passwd */
-	oscar_add_buddy,		/* add_buddy */
-	NULL,					/* add_buddies */
-	oscar_remove_buddy,		/* remove_buddy */
-	NULL,					/* remove_buddies */
-	NULL,		/* add_permit */
-	oscar_add_deny,			/* add_deny */
-	NULL,		/* rem_permit */
-	oscar_rem_deny,			/* rem_deny */
-	NULL,	/* set_permit_deny */
-	oscar_join_chat,		/* join_chat */
-	NULL,					/* reject_chat */
-	oscar_get_chat_name,	/* get_chat_name */
-	oscar_chat_invite,		/* chat_invite */
-	oscar_chat_leave,		/* chat_leave */
-	NULL,					/* chat_whisper */
-	oscar_send_chat,		/* chat_send */
-	oscar_keepalive,		/* keepalive */
-	NULL,					/* register_user */
-	NULL,					/* get_cb_info */
-	oscar_alias_buddy,		/* alias_buddy */
-	oscar_move_buddy,		/* group_buddy */
-	oscar_rename_group,		/* rename_group */
-	NULL,					/* buddy_free */
-	oscar_convo_closed,		/* convo_closed */
-	oscar_normalize,		/* normalize */
-	oscar_set_icon,			/* set_buddy_icon */
-	oscar_remove_group,		/* remove_group */
-	NULL,					/* get_cb_real_name */
-	NULL,					/* set_chat_topic */
-	NULL,					/* find_blist_chat */
-	NULL,					/* roomlist_get_list */
-	NULL,					/* roomlist_cancel */
-	NULL,					/* roomlist_expand_category */
-	oscar_can_receive_file,	/* can_receive_file */
-	oscar_send_file,		/* send_file */
-	oscar_new_xfer,			/* new_xfer */
-	oscar_offline_message,	/* offline_message */
-	NULL,					/* whiteboard_protocol_ops */
-	NULL,					/* send_raw */
-	NULL,					/* roomlist_room_serialize */
-	NULL,					/* unregister_user */
-	NULL,					/* send_attention */
-	NULL,					/* get_attention_types */
-	icq_get_account_text_table, /* get_account_text_table */
-	NULL,					/* initiate_media */
-	NULL,					/* can_do_media */
-	oscar_get_purple_moods, /* get_moods */
-	NULL,					/* set_public_alias */
-	NULL,					/* get_public_alias */
-	icq_get_max_message_size		/* get_max_message_size */
-};
+	PurpleProtocolClass *proto_class = PURPLE_PROTOCOL_CLASS(klass);
+	PurpleAccountOption *option;
+
+	proto_class->id        = ICQ_ID;
+	proto_class->name      = ICQ_NAME;
+
+	option = purple_account_option_string_new(_("Server"), "server", oscar_get_login_server(TRUE, TRUE));
+	proto_class->protocol_options = g_list_append(proto_class->protocol_options, option);
+
+	option = purple_account_option_string_new(_("Encoding"), "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
+	proto_class->protocol_options = g_list_append(proto_class->protocol_options, option);
+}
+
+static void
+icq_protocol_interface_init(PurpleProtocolInterface *iface)
+{
+	iface->list_icon              = oscar_list_icon_icq;
+	iface->get_account_text_table = icq_get_account_text_table;
+	iface->get_moods              = oscar_get_purple_moods;
+	iface->get_max_message_size   = icq_get_max_message_size;
+}
+
+static void icq_protocol_base_finalize(ICQProtocolClass *klass) { }
 
 static PurplePluginInfo *
 plugin_query(GError **error)
 {
 	return purple_plugin_info_new(
-		"id",           "prpl-icq",
-		"name",         "ICQ",
+		"id",           ICQ_ID,
+		"name",         ICQ_NAME,
 		"version",      DISPLAY_VERSION,
 		"category",     N_("Protocol"),
 		"summary",      N_("ICQ Protocol Plugin"),
@@ -144,14 +97,14 @@
 static gboolean
 plugin_load(PurplePlugin *plugin, GError **error)
 {
-	PurpleAccountOption *option;
-
-	oscar_init(&protocol, TRUE);
+	my_protocol = purple_protocols_add(ICQ_TYPE_PROTOCOL);
+	if (!my_protocol) {
+		g_set_error(error, ICQ_DOMAIN, 0, _("Failed to add icq protocol"));
+		return FALSE;
+	}
 
-	option = purple_account_option_string_new(_("Encoding"), "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
-	protocol.protocol_options = g_list_append(protocol.protocol_options, option);
-
-	purple_protocols_add(&protocol);
+	purple_signal_connect(purple_get_core(), "uri-handler", my_protocol,
+		PURPLE_CALLBACK(oscar_uri_handler), NULL);
 
 	return TRUE;
 }
@@ -159,9 +112,15 @@
 static gboolean
 plugin_unload(PurplePlugin *plugin, GError **error)
 {
-	purple_protocols_remove(&protocol);
+	if (!purple_protocols_remove(my_protocol)) {
+		g_set_error(error, ICQ_DOMAIN, 0, _("Failed to remove icq protocol"));
+		return FALSE;
+	}
 
 	return TRUE;
 }
 
+PURPLE_PROTOCOL_DEFINE_EXTENDED(ICQProtocol, icq_protocol,
+                                OSCAR_TYPE_PROTOCOL, 0);
+
 PURPLE_PLUGIN_INIT(icq, plugin_query, plugin_load, plugin_unload);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/oscar/libicq.h	Wed Aug 28 03:37:22 2013 +0530
@@ -0,0 +1,53 @@
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ *
+ */
+#ifndef _LIBICQ_H_
+#define _LIBICQ_H_
+
+#include "oscar.h"
+
+#define ICQ_ID     "prpl-icq"
+#define ICQ_NAME   "ICQ"
+#define ICQ_DOMAIN (g_quark_from_static_string(ICQ_ID))
+
+#define ICQ_TYPE_PROTOCOL             (icq_protocol_get_type())
+#define ICQ_PROTOCOL(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), ICQ_TYPE_PROTOCOL, ICQProtocol))
+#define ICQ_PROTOCOL_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), ICQ_TYPE_PROTOCOL, ICQProtocolClass))
+#define ICQ_IS_PROTOCOL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), ICQ_TYPE_PROTOCOL))
+#define ICQ_IS_PROTOCOL_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), ICQ_TYPE_PROTOCOL))
+#define ICQ_PROTOCOL_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), ICQ_TYPE_PROTOCOL, ICQProtocolClass))
+
+typedef struct _ICQProtocol
+{
+	OscarProtocol parent;
+} ICQProtocol;
+
+typedef struct _ICQProtocolClass
+{
+	OscarProtocolClass parent_class;
+} ICQProtocolClass;
+
+/**
+ * Returns the GType for the ICQProtocol object.
+ */
+GType icq_protocol_get_type(void);
+
+#endif /* _LIBICQ_H_ */
--- a/libpurple/protocols/oscar/oscar.c	Wed Aug 28 00:13:52 2013 +0530
+++ b/libpurple/protocols/oscar/oscar.c	Wed Aug 28 03:37:22 2013 +0530
@@ -608,8 +608,8 @@
 	ICQ_DEFAULT_SSL_LOGIN_SERVER,
 };
 
-static const gchar *
-get_login_server(gboolean is_icq, gboolean use_ssl)
+const gchar *
+oscar_get_login_server(gboolean is_icq, gboolean use_ssl)
 {
 	return login_servers[(is_icq ? 2 : 0) + (use_ssl ? 1 : 0)];
 }
@@ -767,7 +767,7 @@
 		newconn = flap_connection_new(od, SNAC_FAMILY_AUTH);
 
 		if (od->use_ssl) {
-			server = purple_account_get_string(account, "server", get_login_server(od->icq, TRUE));
+			server = purple_account_get_string(account, "server", oscar_get_login_server(od->icq, TRUE));
 
 			/*
 			 * If the account's server is what the oscar prpl has offered as
@@ -776,27 +776,27 @@
 			 * do what we know is best for them and change the setting out
 			 * from under them to the SSL login server.
 			 */
-			if (!strcmp(server, get_login_server(od->icq, FALSE)) || !strcmp(server, AIM_ALT_LOGIN_SERVER)) {
+			if (!strcmp(server, oscar_get_login_server(od->icq, FALSE)) || !strcmp(server, AIM_ALT_LOGIN_SERVER)) {
 				purple_debug_info("oscar", "Account uses SSL, so changing server to default SSL server\n");
-				purple_account_set_string(account, "server", get_login_server(od->icq, TRUE));
-				server = get_login_server(od->icq, TRUE);
+				purple_account_set_string(account, "server", oscar_get_login_server(od->icq, TRUE));
+				server = oscar_get_login_server(od->icq, TRUE);
 			}
 
 			newconn->gsc = purple_ssl_connect(account, server,
 					purple_account_get_int(account, "port", OSCAR_DEFAULT_LOGIN_PORT),
 					ssl_connection_established_cb, ssl_connection_error_cb, newconn);
 		} else {
-			server = purple_account_get_string(account, "server", get_login_server(od->icq, FALSE));
+			server = purple_account_get_string(account, "server", oscar_get_login_server(od->icq, FALSE));
 
 			/*
 			 * See the comment above. We do the reverse here. If they don't want
 			 * SSL but their server is set to OSCAR_DEFAULT_SSL_LOGIN_SERVER,
 			 * set it back to the default.
 			 */
-			if (!strcmp(server, get_login_server(od->icq, TRUE))) {
+			if (!strcmp(server, oscar_get_login_server(od->icq, TRUE))) {
 				purple_debug_info("oscar", "Account does not use SSL, so changing server back to non-SSL\n");
-				purple_account_set_string(account, "server", get_login_server(od->icq, FALSE));
-				server = get_login_server(od->icq, FALSE);
+				purple_account_set_string(account, "server", oscar_get_login_server(od->icq, FALSE));
+				server = oscar_get_login_server(od->icq, FALSE);
 			}
 
 			newconn->connect_data = purple_proxy_connect(NULL, account, server,
@@ -5468,8 +5468,7 @@
 	return acct;
 }
 
-
-static gboolean oscar_uri_handler(const char *proto, const char *cmd, GHashTable *params)
+gboolean oscar_uri_handler(const char *proto, const char *cmd, GHashTable *params)
 {
 	char *acct_id = g_hash_table_lookup(params, "account");
 	char prpl[11];
@@ -5536,10 +5535,11 @@
 	return FALSE;
 }
 
-void oscar_init(PurpleProtocol *protocol, gboolean is_icq)
+static void
+oscar_protocol_base_init(OscarProtocolClass *klass)
 {
+	PurpleProtocolClass *proto_class = PURPLE_PROTOCOL_CLASS(klass);
 	PurpleAccountOption *option;
-	static gboolean init = FALSE;
 	static const gchar *encryption_keys[] = {
 		N_("Use encryption if available"),
 		N_("Require encryption"),
@@ -5555,11 +5555,17 @@
 	GList *encryption_options = NULL;
 	int i;
 
-	option = purple_account_option_string_new(_("Server"), "server", get_login_server(is_icq, TRUE));
-	protocol->protocol_options = g_list_append(protocol->protocol_options, option);
+	proto_class->options   = OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE |
+	                         OPT_PROTO_INVITE_MESSAGE |
+	                         OPT_PROTO_AUTHORIZATION_DENIED_MESSAGE;
+
+	proto_class->icon_spec = (PurpleBuddyIconSpec) {"gif,jpeg,bmp,ico",
+	                                                0, 0, 64, 64, 7168,
+	                                                PURPLE_ICON_SCALE_SEND |
+	                                                PURPLE_ICON_SCALE_DISPLAY};
 
 	option = purple_account_option_int_new(_("Port"), "port", OSCAR_DEFAULT_LOGIN_PORT);
-	protocol->protocol_options = g_list_append(protocol->protocol_options, option);
+	proto_class->protocol_options = g_list_append(proto_class->protocol_options, option);
 
 	for (i = 0; encryption_keys[i]; i++) {
 		PurpleKeyValuePair *kvp = g_new0(PurpleKeyValuePair, 1);
@@ -5568,37 +5574,75 @@
 		encryption_options = g_list_append(encryption_options, kvp);
 	}
 	option = purple_account_option_list_new(_("Connection security"), "encryption", encryption_options);
-	protocol->protocol_options = g_list_append(protocol->protocol_options, option);
+	proto_class->protocol_options = g_list_append(proto_class->protocol_options, option);
 
 	option = purple_account_option_bool_new(_("Use clientLogin"), "use_clientlogin",
 			OSCAR_DEFAULT_USE_CLIENTLOGIN);
-	protocol->protocol_options = g_list_append(protocol->protocol_options, option);
+	proto_class->protocol_options = g_list_append(proto_class->protocol_options, option);
 
 	option = purple_account_option_bool_new(
 		_("Always use AIM/ICQ proxy server for\nfile transfers and direct IM (slower,\nbut does not reveal your IP address)"), "always_use_rv_proxy",
 		OSCAR_DEFAULT_ALWAYS_USE_RV_PROXY);
-	protocol->protocol_options = g_list_append(protocol->protocol_options, option);
-
-	if (g_str_equal(protocol->id, "prpl-aim")) {
+	proto_class->protocol_options = g_list_append(proto_class->protocol_options, option);
+
+	if (g_str_equal(proto_class->id, "prpl-aim")) {
 		option = purple_account_option_bool_new(_("Allow multiple simultaneous logins"), "allow_multiple_logins",
 												OSCAR_DEFAULT_ALLOW_MULTIPLE_LOGINS);
-		protocol->protocol_options = g_list_append(protocol->protocol_options, option);
+		proto_class->protocol_options = g_list_append(proto_class->protocol_options, option);
 	}
 
-	if (init)
-		return;
-	init = TRUE;
-
 	/* Preferences */
 	purple_prefs_add_none("/plugins/prpl/oscar");
 	purple_prefs_add_bool("/plugins/prpl/oscar/recent_buddies", FALSE);
 
 	purple_prefs_remove("/plugins/prpl/oscar/show_idle");
 	purple_prefs_remove("/plugins/prpl/oscar/always_use_rv_proxy");
-
-	/* protocol handler */
-	/* TODO: figure out a good instance to use here */
-	purple_signal_connect(purple_get_core(), "uri-handler", protocol,
-		PURPLE_CALLBACK(oscar_uri_handler), NULL);
 }
 
+static void
+oscar_protocol_interface_init(PurpleProtocolInterface *iface)
+{
+	iface->get_actions        = oscar_get_actions;
+	iface->list_emblem        = oscar_list_emblem;
+	iface->status_text        = oscar_status_text;
+	iface->tooltip_text       = oscar_tooltip_text;
+	iface->status_types       = oscar_status_types;
+	iface->blist_node_menu    = oscar_blist_node_menu;
+	iface->chat_info          = oscar_chat_info;
+	iface->chat_info_defaults = oscar_chat_info_defaults;
+	iface->login              = oscar_login;
+	iface->close              = oscar_close;
+	iface->send_im            = oscar_send_im;
+	iface->set_info           = oscar_set_info;
+	iface->send_typing        = oscar_send_typing;
+	iface->get_info           = oscar_get_info;
+	iface->set_status         = oscar_set_status;
+	iface->set_idle           = oscar_set_idle;
+	iface->change_passwd      = oscar_change_passwd;
+	iface->add_buddy          = oscar_add_buddy;
+	iface->remove_buddy       = oscar_remove_buddy;
+	iface->add_deny           = oscar_add_deny;
+	iface->rem_deny           = oscar_rem_deny;
+	iface->join_chat          = oscar_join_chat;
+	iface->get_chat_name      = oscar_get_chat_name;
+	iface->chat_invite        = oscar_chat_invite;
+	iface->chat_leave         = oscar_chat_leave;
+	iface->chat_send          = oscar_send_chat;
+	iface->keepalive          = oscar_keepalive;
+	iface->alias_buddy        = oscar_alias_buddy;
+	iface->group_buddy        = oscar_move_buddy;
+	iface->rename_group       = oscar_rename_group;
+	iface->convo_closed       = oscar_convo_closed;
+	iface->normalize          = oscar_normalize;
+	iface->set_buddy_icon     = oscar_set_icon;
+	iface->remove_group       = oscar_remove_group;
+	iface->can_receive_file   = oscar_can_receive_file;
+	iface->send_file          = oscar_send_file;
+	iface->new_xfer           = oscar_new_xfer;
+	iface->offline_message    = oscar_offline_message;
+}
+
+static void oscar_protocol_base_finalize(OscarProtocolClass *klass) { }
+
+PURPLE_PROTOCOL_DEFINE_EXTENDED (OscarProtocol, oscar_protocol,
+                                 PURPLE_TYPE_PROTOCOL, G_TYPE_FLAG_ABSTRACT);
--- a/libpurple/protocols/oscar/oscar.h	Wed Aug 28 00:13:52 2013 +0530
+++ b/libpurple/protocols/oscar/oscar.h	Wed Aug 28 03:37:22 2013 +0530
@@ -56,6 +56,13 @@
 #include "libc_interface.h"
 #endif
 
+#define OSCAR_TYPE_PROTOCOL             (oscar_protocol_get_type())
+#define OSCAR_PROTOCOL(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), OSCAR_TYPE_PROTOCOL, OscarProtocol))
+#define OSCAR_PROTOCOL_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), OSCAR_TYPE_PROTOCOL, OscarProtocolClass))
+#define OSCAR_IS_PROTOCOL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), OSCAR_TYPE_PROTOCOL))
+#define OSCAR_IS_PROTOCOL_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), OSCAR_TYPE_PROTOCOL))
+#define OSCAR_PROTOCOL_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), OSCAR_TYPE_PROTOCOL, OscarProtocolClass))
+
 typedef struct _ByteStream         ByteStream;
 typedef struct _ClientInfo         ClientInfo;
 typedef struct _FlapConnection     FlapConnection;
@@ -224,6 +231,21 @@
 #define OSCAR_STATUS_ID_ATWORK      "atwork"
 #define OSCAR_STATUS_ID_LUNCH       "lunch"
 
+typedef struct _OscarProtocol
+{
+	PurpleProtocol parent;
+} OscarProtocol;
+
+typedef struct _OscarProtocolClass
+{
+	PurpleProtocolClass parent_class;
+} OscarProtocolClass;
+
+/**
+ * Returns the GType for the OscarProtocol object.
+ */
+GType oscar_protocol_get_type(void);
+
 /*
  * Byte Stream type. Sort of.
  *
--- a/libpurple/protocols/oscar/oscarcommon.h	Wed Aug 28 00:13:52 2013 +0530
+++ b/libpurple/protocols/oscar/oscarcommon.h	Wed Aug 28 03:37:22 2013 +0530
@@ -104,4 +104,5 @@
 gboolean oscar_offline_message(const PurpleBuddy *buddy);
 gsize oscar_get_max_message_size(PurpleConnection *gc);
 GList *oscar_get_actions(PurpleConnection *gc);
-void oscar_init(PurpleProtocol *protocol, gboolean is_icq);
+const gchar *oscar_get_login_server(gboolean is_icq, gboolean use_ssl);
+gboolean oscar_uri_handler(const char *proto, const char *cmd, GHashTable *params);

mercurial