changeset 26334:535c866b433c

Hide the structs, add accessors, and fix various smaller things: * Make the flags an enum instead of #defines * There were two sets of _in_progress functions, removed one. * Adjusted a few return types to match usage * Move the fetch_count into the prpl's protocol_data (which is no longer the JabberStream but a dedicated struct)
author Paul Aurich <paul@darkrain42.org>
date Mon, 30 Mar 2009 00:42:15 +0000
parents 31e05bafd7a3
children 290ea90869c0
files libpurple/disco.c libpurple/disco.h libpurple/protocols/jabber/disco.c pidgin/gtkdisco.c
diffstat 4 files changed, 411 insertions(+), 198 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/disco.c	Sun Mar 29 21:17:34 2009 +0000
+++ b/libpurple/disco.c	Mon Mar 30 00:42:15 2009 +0000
@@ -29,6 +29,37 @@
 
 #include "disco.h"
 
+/**************************************************************************/
+/* Main structures, members and constants                                 */
+/**************************************************************************/
+
+/**
+ * Represents a list of services for a given connection on a given protocol.
+ */
+struct _PurpleDiscoList {
+	PurpleAccount *account; /**< The account this list belongs to. */
+	GList *services; /**< The list of services. */
+
+	gboolean in_progress;
+
+	gpointer ui_data; /**< UI private data. */
+	gpointer proto_data; /** Prpl private data. */
+	guint ref; /**< The reference count. */
+};
+
+/**
+ * Represents a list of services for a given connection on a given protocol.
+ */
+struct _PurpleDiscoService {
+	PurpleDiscoList *list;
+	gchar *name; /**< The name of the service. */
+	gchar *description; /**< The name of the service. */
+
+	PurpleDiscoServiceCategory category; /**< The category of service. */
+	PurpleDiscoServiceType type; /**< The type of service. */
+	PurpleDiscoServiceFlags flags;
+};
+
 static PurpleDiscoUiOps *ops = NULL;
 
 PurpleDiscoList *purple_disco_list_new(PurpleAccount *account, void *ui_data)
@@ -48,12 +79,14 @@
 	return list;
 }
 
-void purple_disco_list_ref(PurpleDiscoList *list)
+PurpleDiscoList *purple_disco_list_ref(PurpleDiscoList *list)
 {
-	g_return_if_fail(list != NULL);
+	g_return_val_if_fail(list != NULL, NULL);
 
 	list->ref++;
 	purple_debug_misc("disco", "reffing list, ref count now %d\n", list->ref);
+
+	return list;
 }
 
 static void purple_disco_list_service_destroy(PurpleDiscoList *list, PurpleDiscoService *r)
@@ -106,11 +139,12 @@
 }
 
 PurpleDiscoService *purple_disco_list_service_new(PurpleDiscoServiceCategory category, const gchar *name,
-		PurpleDiscoServiceType type, const gchar *description, int flags)
+		PurpleDiscoServiceType type, const gchar *description, PurpleDiscoServiceFlags flags)
 {
 	PurpleDiscoService *s;
 
 	g_return_val_if_fail(name != NULL, NULL);
+	g_return_val_if_fail(category != PURPLE_DISCO_SERVICE_CAT_UNSET, NULL);
 
 	s = g_new0(PurpleDiscoService, 1);
 	s->category = category;
@@ -122,20 +156,25 @@
 	return s;
 }
 
-void purple_disco_get_list(PurpleConnection *gc, PurpleDiscoList *list)
+void purple_disco_get_list(PurpleDiscoList *list)
 {
+	PurpleConnection *pc = NULL;
 	PurplePlugin *prpl = NULL;
 	PurplePluginProtocolInfo *prpl_info = NULL;
 
-	g_return_if_fail(gc != NULL);
+	g_return_if_fail(list != NULL);
+
+	pc = purple_account_get_connection(list->account);
 
-	prpl = purple_connection_get_prpl(gc);
+	g_return_if_fail(pc != NULL);
+
+	prpl = purple_connection_get_prpl(pc);
 
 	if (prpl != NULL)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
 	if (prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, disco_get_list))
-		prpl_info->disco_get_list(gc, list);
+		prpl_info->disco_get_list(pc, list);
 }
 
 void purple_disco_cancel_get_list(PurpleDiscoList *list)
@@ -160,25 +199,95 @@
 		prpl_info->disco_cancel(list);
 }
 
-int purple_disco_service_register(PurpleConnection *gc, PurpleDiscoService *service)
+void purple_disco_service_register(PurpleDiscoService *service)
 {
+	PurpleConnection *pc;
 	PurplePlugin *prpl = NULL;
 	PurplePluginProtocolInfo *prpl_info = NULL;
 
-	g_return_val_if_fail(gc != NULL, -EINVAL);
+	g_return_if_fail(service != NULL);
+	
+	pc = purple_account_get_connection(service->list->account);
 
-	prpl = purple_connection_get_prpl(gc);
+	g_return_if_fail(pc != NULL);
+
+	prpl = purple_connection_get_prpl(pc);
 
 	if (prpl != NULL)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
 	if (prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, disco_service_register))
-		return prpl_info->disco_service_register(gc, service);
+		prpl_info->disco_service_register(pc, service);
+}
+
+const gchar *purple_disco_service_get_name(PurpleDiscoService *service)
+{
+	g_return_val_if_fail(service != NULL, NULL);
+
+	return service->name;
+}
+
+const gchar *purple_disco_service_get_description(PurpleDiscoService *service)
+{
+	g_return_val_if_fail(service != NULL, NULL);
 
-	return -EINVAL;
+	return service->description;
+}
+
+PurpleDiscoServiceCategory
+purple_disco_service_get_category(PurpleDiscoService *service)
+{
+	g_return_val_if_fail(service != NULL, PURPLE_DISCO_SERVICE_CAT_UNSET);
+
+	return service->category;
+}
+
+PurpleDiscoServiceType
+purple_disco_service_get_type(PurpleDiscoService *service)
+{
+	g_return_val_if_fail(service != NULL, PURPLE_DISCO_SERVICE_TYPE_NONE);
+
+	return service->type;
 }
 
-void purple_disco_set_in_progress(PurpleDiscoList *list, gboolean in_progress)
+PurpleDiscoServiceFlags
+purple_disco_service_get_flags(PurpleDiscoService *service)
+{
+	g_return_val_if_fail(service != NULL, PURPLE_DISCO_NONE);
+
+	return service->flags;
+}
+
+PurpleAccount* purple_disco_list_get_account(PurpleDiscoList *list)
+{
+	g_return_val_if_fail(list != NULL, NULL);
+
+	return list->account;
+}
+
+GList* purple_disco_list_get_services(PurpleDiscoList *list)
+{
+	g_return_val_if_fail(list != NULL, NULL);
+
+	return list->services;
+}
+
+void purple_disco_list_set_ui_data(PurpleDiscoList *list, gpointer ui_data)
+{
+	g_return_if_fail(list != NULL);
+
+	list->ui_data = ui_data;
+}
+
+gpointer purple_disco_list_get_ui_data(PurpleDiscoList *list)
+{
+	g_return_val_if_fail(list != NULL, NULL);
+
+	return list->ui_data;
+}
+
+void purple_disco_list_set_in_progress(PurpleDiscoList *list,
+                                       gboolean in_progress)
 {
 	g_return_if_fail(list != NULL);
 
@@ -188,66 +297,25 @@
 		ops->in_progress(list, in_progress);
 }
 
-gboolean purple_disco_get_in_progress(PurpleDiscoList *list)
+gboolean purple_disco_list_get_in_progress(PurpleDiscoList *list) 
 {
 	g_return_val_if_fail(list != NULL, FALSE);
 
 	return list->in_progress;
 }
 
-void purple_disco_list_set_account(PurpleDiscoList *list, PurpleAccount *account)
-{
-	list->account = account;
-}
-
-PurpleAccount* purple_disco_list_get_account(PurpleDiscoList *list)
-{
-	return list->account;
-}
-
-GList* spurple_disco_list_get_services(PurpleDiscoList *dl)
-{
-	return dl->services;
-}
-
-void purple_disco_list_set_ui_data(PurpleDiscoList *list, gpointer ui_data)
-{
-	list->ui_data = ui_data;
-}
-
-gpointer purple_disco_list_get_ui_data(PurpleDiscoList *list)
+void purple_disco_list_set_protocol_data(PurpleDiscoList *list,
+                                         gpointer proto_data)
 {
-	return list->ui_data;
-}
-
-void purple_disco_list_set_in_progress(PurpleDiscoList *list, gboolean in_progress)
-{
-	list->in_progress = in_progress;
-}
-
-gboolean purple_disco_list_get_in_progress(PurpleDiscoList *list) 
-{
-	return list->in_progress;
-}
+	g_return_if_fail(list != NULL);
 
-void purple_disco_list_set_fetch_count(PurpleDiscoList *list, gint fetch_count)
-{
-	list->fetch_count = fetch_count;
-	purple_debug_info("disco", "fetch_count = %d\n", fetch_count);
-}
-
-gint purple_disco_list_get_fetch_count(PurpleDiscoList *list)
-{
-	return list->fetch_count;
-}
-
-void purple_disco_list_set_proto_data(PurpleDiscoList *list, gpointer proto_data)
-{
 	list->proto_data = proto_data;
 }
 
-gpointer purple_disco_list_get_proto_data(PurpleDiscoList *list)
+gpointer purple_disco_list_get_protocol_data(PurpleDiscoList *list)
 {
+	g_return_val_if_fail(list != NULL, NULL);
+
 	return list->proto_data;
 }
 
--- a/libpurple/disco.h	Sun Mar 29 21:17:34 2009 +0000
+++ b/libpurple/disco.h	Mon Mar 30 00:42:15 2009 +0000
@@ -35,19 +35,6 @@
 #include "account.h"
 
 /**
- * Represents a list of services for a given connection on a given protocol.
- */
-struct _PurpleDiscoList {
-	PurpleAccount *account; /**< The account this list belongs to. */
-	GList *services; /**< The list of services. */
-	gpointer *ui_data; /**< UI private data. */
-	gboolean in_progress;
-	gint fetch_count; /**< Uses in fetch processes */
-	gpointer proto_data; /** Prpl private data. */
-	guint ref; /**< The reference count. */
-};
-
-/**
  * The categories of services.
  */
 typedef enum
@@ -81,22 +68,13 @@
 /**
  * The flags of services.
  */
-#define PURPLE_DISCO_FLAG_NONE			0
-#define PURPLE_DISCO_FLAG_ADD			1 << 0
-#define PURPLE_DISCO_FLAG_BROWSE		1 << 1
-#define PURPLE_DISCO_FLAG_REGISTER		1 << 2
-
-/**
- * Represents a list of services for a given connection on a given protocol.
- */
-struct _PurpleDiscoService {
-	PurpleDiscoList *list;
-	PurpleDiscoServiceCategory category; /**< The category of service. */
-	gchar *name; /**< The name of the service. */
-	PurpleDiscoServiceType type; /**< The type of service. */
-	guint flags;
-	gchar *description; /**< The name of the service. */
-};
+typedef enum
+{
+	PURPLE_DISCO_NONE          = 0x0000,
+	PURPLE_DISCO_ADD           = 0x0001, /**< Supports an 'add' operation */
+	PURPLE_DISCO_BROWSE        = 0x0002, /**< Supports browsing */
+	PURPLE_DISCO_REGISTER      = 0x0004  /**< Supports a 'register' operation */
+} PurpleDiscoServiceFlags;
 
 struct _PurpleDiscoUiOps {
 	/** Ask the UI to display a dialog for the specified account.
@@ -131,9 +109,9 @@
 /**
  * Increases the reference count on the service discovery list.
  *
- * @param list The object to ref.
+ * @param list The disco list to ref.
  */
-void purple_disco_list_ref(PurpleDiscoList *list);
+PurpleDiscoList *purple_disco_list_ref(PurpleDiscoList *list);
 
 /**
  * Decreases the reference count on the service discovery list.
@@ -148,10 +126,8 @@
 /**
  * Instructs the prpl to start fetching the list.
  *
- * @param gc The PurpleConnection to have get a list.
- *
  */
-void purple_disco_get_list(PurpleConnection *gc, PurpleDiscoList *list);
+void purple_disco_get_list(PurpleDiscoList *list);
 
 /**
  * Tells the prpl to stop fetching the list.
@@ -167,7 +143,7 @@
  * Create new service object
  */
 PurpleDiscoService *purple_disco_list_service_new(PurpleDiscoServiceCategory category, const gchar *name,
-		PurpleDiscoServiceType type, const gchar *description, int flags);
+		PurpleDiscoServiceType type, const gchar *description, PurpleDiscoServiceFlags flags);
 
 /**
  * Add service to list
@@ -175,6 +151,103 @@
 void purple_disco_list_service_add(PurpleDiscoList *list, PurpleDiscoService *service, PurpleDiscoService *parent);
 
 /**
+ * Register service
+ * @param service The service that will be registered
+ */
+void purple_disco_service_register(PurpleDiscoService *service);
+
+/**
+ * Returns a service's name.
+ *
+ * @param service The service.
+ * @return The name.
+ *
+ * @since TODO
+ */
+const gchar *purple_disco_service_get_name(PurpleDiscoService *service);
+
+/**
+ * Return a service's description.
+ *
+ * @param service The service.
+ * @return The description.
+ *
+ * @since TODO
+ */
+const gchar* purple_disco_service_get_description(PurpleDiscoService *service);
+
+/**
+ * Return a service's category.
+ *
+ * @param service The service.
+ * @return The category.
+ *
+ * @since TODO
+ */
+PurpleDiscoServiceCategory purple_disco_service_get_category(PurpleDiscoService *service);
+
+/**
+ * Return a service's type.
+ *
+ * @param service The service.
+ * @return The type.
+ *
+ * @since TODO
+ */
+PurpleDiscoServiceType purple_disco_service_get_type(PurpleDiscoService *service);
+
+/**
+ * Return a service's flags.
+ *
+ * @param service The service.
+ * @return The flags.
+ *
+ * @since TODO
+ */
+PurpleDiscoServiceFlags purple_disco_service_get_flags(PurpleDiscoService *service);
+/**
+ * Get the account associated with a service list.
+ *
+ * @param list  The service list.
+ * @return      The account
+ *
+ * @since TODO
+ */
+PurpleAccount* purple_disco_list_get_account(PurpleDiscoList *list);
+
+/**
+ * Get a list of the services associated with this service list.
+ *
+ * @param dl The serivce list.
+ * @returns    A list of PurpleDiscoService items.
+ *
+ * @since TODO
+ */
+GList* purple_disco_list_get_services(PurpleDiscoList *dl);
+
+/**
+ * Set the service list's UI data.
+ *
+ * @param list  The service list.
+ * @param data  The data.
+ *
+ * @see purple_disco_list_get_ui_data()
+ * @since TODO
+ */
+void purple_disco_list_set_ui_data(PurpleDiscoList *list, gpointer data);
+
+/**
+ * Get the service list's UI data.
+ *
+ * @param list  The service list.
+ * @return      The data.
+ *
+ * @see purple_disco_list_set_ui_data()
+ * @since TODO
+ */
+gpointer purple_disco_list_get_ui_data(PurpleDiscoList *list);
+
+/**
  * Set the "in progress" state of the Service Discovery.
  *
  * The UI is encouraged to somehow hint to the user
@@ -182,8 +255,11 @@
  *
  * @param list The service list.
  * @param in_progress We're downloading it, or we're not.
+ *
+ * @see purple_disco_list_get_in_progress()
+ * @since TODO
  */
-void purple_disco_set_in_progress(PurpleDiscoList *list, gboolean in_progress);
+void purple_disco_list_set_in_progress(PurpleDiscoList *list, gboolean in_progress);
 
 /**
  * Gets the "in progress" state of the Service Discovery.
@@ -193,14 +269,44 @@
  *
  * @param list The service list.
  * @return True if we're downloading it, or false if we're not.
+ *
+ * @see purple_disco_list_set_in_progress()
+ * @since TODO
  */
-gboolean purple_disco_get_in_progress(PurpleDiscoList *list);
+gboolean purple_disco_list_get_in_progress(PurpleDiscoList *list);
 
+/**
+ * Sets the disco list's protocol-specific data.
+ *
+ * This should only be called from the associated prpl.
+ *
+ * @param list The disco list.
+ * @param data The protocol data.
+ *
+ * @see purple_disco_list_get_protocol_data()
+ * @since TODO
+ */
+void purple_disco_list_set_protocol_data(PurpleDiscoList *list, gpointer data);
+
+/**
+ * Returns the disco list's protocol-specific data.
+ *
+ * This should only be called from the associated prpl.
+ *
+ * @param list The disco list.
+ * @return     The protocol data.
+ *
+ * @see purple_disco_list_set_protocol_data()
+ * @since TODO
+ */
+gpointer purple_disco_list_get_protocol_data(PurpleDiscoList *list);
 
 /**
  * Sets the UI operations structure to be used in all purple service discovery.
  *
  * @param ops The UI operations structure.
+ *
+ * @since TODO
  */
 void purple_disco_set_ui_ops(PurpleDiscoUiOps *ui_ops);
 
@@ -208,39 +314,11 @@
  * Returns the service discovery UI operations structure.
  *
  * @return A filled-out PurpleDiscoUiOps structure.
+ *
+ * @since TODO
  */
 PurpleDiscoUiOps *purple_disco_get_ui_ops(void);
 
-/**
- * Register service
- * @param gc Connection
- * @param service The service that will be registered
- */
-int purple_disco_service_register(PurpleConnection *gc, PurpleDiscoService *service);
-
-/**< Set/Get the account this list belongs to. */
-void purple_disco_list_set_account(PurpleDiscoList *list, PurpleAccount *account);
-PurpleAccount* purple_disco_list_get_account(PurpleDiscoList *list);
-
-/**< The list of services. */
-GList* spurple_disco_list_get_services(PurpleDiscoList *dl);
-
-/**< Set/Get UI private data. */
-void purple_disco_list_set_ui_data(PurpleDiscoList *list, gpointer ui_data);
-gpointer purple_disco_list_get_ui_data(PurpleDiscoList *list);
-
-/** Set/Get in progress flag */ 
-void purple_disco_list_set_in_progress(PurpleDiscoList *list, gboolean in_progress);
-gboolean purple_disco_list_get_in_progress(PurpleDiscoList *list);
-
-/** Set/Get fetch counter */
-void purple_disco_list_set_fetch_count(PurpleDiscoList *list, gint fetch_count);
-gint purple_disco_list_get_fetch_count(PurpleDiscoList *list);
-
-/** Set/Get prpl private data. */
-void purple_disco_list_set_proto_data(PurpleDiscoList *list, gpointer proto_data);
-gpointer purple_disco_list_get_proto_data(PurpleDiscoList *list);
-
 #ifdef __cplusplus
 }
 #endif
--- a/libpurple/protocols/jabber/disco.c	Sun Mar 29 21:17:34 2009 +0000
+++ b/libpurple/protocols/jabber/disco.c	Mon Mar 30 00:42:15 2009 +0000
@@ -47,6 +47,11 @@
 	xmlnode_set_attrib(feature, "var", x); \
 }
 
+struct jabber_disco_list_data {
+	char *server;
+	int fetch_count;
+};
+
 static void
 jabber_disco_bytestream_server_cb(JabberStream *js, xmlnode *packet, gpointer data) {
 	JabberBytestreamsStreamhost *sh = data;
@@ -570,6 +575,15 @@
 	jabber_iq_send(iq);
 }
 
+static void
+jabber_disco_list_data_destroy(struct jabber_disco_list_data *data)
+{
+	g_return_if_fail(data != NULL);
+
+	g_free(data->server);
+	g_free(data);
+}
+
 static PurpleDiscoServiceCategory
 jabber_disco_category_from_string(const gchar *str)
 {
@@ -617,6 +631,7 @@
 jabber_disco_service_items_cb(JabberStream *js, xmlnode *packet, gpointer data)
 {
 	struct _disco_data *disco_data = data;
+	struct jabber_disco_list_data *list_data;
 	PurpleDiscoList *list = disco_data->list;
 	PurpleDiscoService *parent = disco_data->parent;
 	const char *parent_node = disco_data->node;
@@ -626,12 +641,16 @@
 	xmlnode *child;
 	gboolean has_items = FALSE;
 
-	purple_disco_list_set_fetch_count(list, purple_disco_list_get_fetch_count(list) - 1);
+	list_data = purple_disco_list_get_protocol_data(list);
+	--list_data->fetch_count;
 
-	if (!from || !result || !query || (strcmp(result, "result")
-			|| !purple_disco_list_get_proto_data(list))) {
-		if (!purple_disco_list_get_fetch_count(list))
-			purple_disco_set_in_progress(list, FALSE);
+	if (!from || !result || !query || strcmp(result, "result") != 0) {
+		if (list_data->fetch_count == 0) {
+			jabber_disco_list_data_destroy(list_data);
+			purple_disco_list_set_protocol_data(list, NULL);
+
+			purple_disco_list_set_in_progress(list, FALSE);
+		}
 
 		purple_disco_list_unref(list);
 		return;
@@ -647,7 +666,7 @@
 		struct _disco_data *disco_data;
 		char *full_node;
 
-		if(!(jid = xmlnode_get_attrib(child, "jid")) || !purple_disco_list_get_proto_data(list))
+		if(!(jid = xmlnode_get_attrib(child, "jid")) || !purple_disco_list_get_protocol_data(list))
 			continue;
 
 		node = xmlnode_get_attrib(child, "node");
@@ -671,7 +690,7 @@
 		disco_data->node = full_node;
 
 		has_items = TRUE;
-		purple_disco_list_set_fetch_count(list, purple_disco_list_get_fetch_count(list) + 1);
+		++list_data->fetch_count;
 		purple_disco_list_ref(list);
 		iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info");
 		xmlnode_set_attrib(iq->node, "to", jid);
@@ -682,8 +701,13 @@
 		jabber_iq_send(iq);
 	}
 
-	if (!purple_disco_list_get_fetch_count(list))
-		purple_disco_set_in_progress(list, FALSE);
+	if (list_data->fetch_count == 0) {
+		jabber_disco_list_data_destroy(list_data);
+		purple_disco_list_set_protocol_data(list, NULL);
+
+		purple_disco_list_set_in_progress(list, FALSE);
+	}
+
 	purple_disco_list_unref(list);
 
 	g_free(disco_data->node);
@@ -694,6 +718,7 @@
 jabber_disco_service_info_cb(JabberStream *js, xmlnode *packet, gpointer data)
 {
 	struct _disco_data *disco_data = data;
+	struct jabber_disco_list_data *list_data;
 	PurpleDiscoList *list = disco_data->list;
 	PurpleDiscoService *parent = disco_data->parent;
 	char *node = g_strdup(disco_data->node);
@@ -705,17 +730,23 @@
 	PurpleDiscoService *s;
 	PurpleDiscoServiceCategory cat;
 	PurpleDiscoServiceType type;
-	int flags = PURPLE_DISCO_FLAG_ADD;
+	PurpleDiscoServiceFlags flags = PURPLE_DISCO_ADD;
 
 	g_free(disco_data->node);
 	g_free(disco_data);
-	purple_disco_list_set_fetch_count(list, purple_disco_list_get_fetch_count(list) - 1);
 
-	if (!from || !result || (strcmp(result, "result") || !purple_disco_list_get_proto_data(list))
+	list_data = purple_disco_list_get_protocol_data(list);
+	--list_data->fetch_count;
+
+	if (!from || !result || strcmp(result, "result") != 0
 			|| (!(query = xmlnode_get_child(packet, "query")))
 			|| (!(ident = xmlnode_get_child(query, "identity")))) {
-		if (!purple_disco_list_get_fetch_count(list))
-			purple_disco_set_in_progress(list, FALSE);
+		if (list_data->fetch_count == 0) {
+			jabber_disco_list_data_destroy(list_data);
+			purple_disco_list_set_protocol_data(list, NULL);
+
+			purple_disco_list_set_in_progress(list, FALSE);
+		}
 
 		purple_disco_list_unref(list);
 		return;
@@ -745,10 +776,10 @@
 			continue;
 		
 		if (!strcmp(var, "jabber:iq:register"))
-			flags |= PURPLE_DISCO_FLAG_REGISTER;
+			flags |= PURPLE_DISCO_REGISTER;
 		
 		if (!strcmp(var, "http://jabber.org/protocol/disco#items"))
-			flags |= PURPLE_DISCO_FLAG_BROWSE;
+			flags |= PURPLE_DISCO_BROWSE;
 
 		if (!strcmp(var, "http://jabber.org/protocol/muc"))
 			cat = PURPLE_DISCO_SERVICE_CAT_MUC;
@@ -767,8 +798,8 @@
 	{
 		xmlnode *q;
 		JabberIq *iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#items");
-			
-		purple_disco_list_set_fetch_count(list, purple_disco_list_get_fetch_count(list) + 1);
+
+		++list_data->fetch_count;
 		purple_disco_list_ref(list);
 		disco_data = g_new0(struct _disco_data, 1);
 		disco_data->list = list;
@@ -781,8 +812,12 @@
 		jabber_iq_send(iq);
 	}
 
-	if (!purple_disco_list_get_fetch_count(list))
-		purple_disco_set_in_progress(list, FALSE);
+	if (list_data->fetch_count == 0) {
+		jabber_disco_list_data_destroy(list_data);
+		purple_disco_list_set_protocol_data(list, NULL);
+
+		purple_disco_list_set_in_progress(list, FALSE);
+	}
 
 	purple_disco_list_unref(list);
 
@@ -794,6 +829,7 @@
 jabber_disco_server_items_cb(JabberStream *js, xmlnode *packet, gpointer data)
 {
 	PurpleDiscoList *list = data;
+	struct jabber_disco_list_data *list_data;
 	xmlnode *query, *child;
 	const char *from = xmlnode_get_attrib(packet, "from");
 	const char *type = xmlnode_get_attrib(packet, "type");
@@ -805,6 +841,8 @@
 	if (strcmp(type, "result"))
 		return;
 
+	list_data = purple_disco_list_get_protocol_data(list);
+
 	query = xmlnode_get_child(packet, "query");
 
 	for(child = xmlnode_get_child(query, "item"); child;
@@ -813,14 +851,14 @@
 		const char *jid;
 		struct _disco_data *disco_data;
 
-		if(!(jid = xmlnode_get_attrib(child, "jid")) || !purple_disco_list_get_proto_data(list))
+		if(!(jid = xmlnode_get_attrib(child, "jid")) || !purple_disco_list_get_protocol_data(list))
 			continue;
 
 		disco_data = g_new0(struct _disco_data, 1);
 		disco_data->list = list;
 
 		has_items = TRUE;
-		purple_disco_list_set_fetch_count(list, purple_disco_list_get_fetch_count(list) + 1);
+		++list_data->fetch_count;
 		purple_disco_list_ref(list);
 		iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info");
 		xmlnode_set_attrib(iq->node, "to", jid);
@@ -830,7 +868,7 @@
 	}
 
 	if (!has_items)
-		purple_disco_set_in_progress(list, FALSE);
+		purple_disco_list_set_in_progress(list, FALSE);
 
 	purple_disco_list_unref(list);
 }
@@ -846,14 +884,14 @@
 		xmlnode_set_attrib(iq->node, "to", who);
 		jabber_iq_set_callback(iq, jabber_disco_server_items_cb, list);
 	
-		if (purple_disco_list_get_proto_data(list))
+		if (purple_disco_list_get_protocol_data(list))
 			jabber_iq_send(iq);
 		else
 			purple_disco_list_unref(list);
 	
 	} else {
 		purple_notify_error(NULL, _("Error"), _("Server doesn't support service discovery"), NULL); 
-		purple_disco_set_in_progress(list, FALSE);
+		purple_disco_list_set_in_progress(list, FALSE);
 		purple_disco_list_unref(list);
 	}
 }
@@ -861,19 +899,20 @@
 static void
 jabber_disco_server_cb(PurpleDiscoList *list, PurpleRequestFields *fields)
 {
+	PurpleAccount *account;
+	PurpleConnection *gc;
 	JabberStream *js;
 	const char *server_name;
 
 	server_name = purple_request_fields_get_string(fields, "server");
 
-	js = purple_disco_list_get_proto_data(list);
-	if (!js) {
-		purple_debug_error("jabber", "Service discovery requested for %s "
-		                             "without proto_data", server_name);
+	account = purple_disco_list_get_account(list);
+	gc = purple_account_get_connection(account);
+	if (!gc)
 		return;
-	}
+	js = purple_connection_get_protocol_data(gc);
 
-	purple_disco_set_in_progress(list, TRUE);
+	purple_disco_list_set_in_progress(list, TRUE);
 	purple_debug_misc("jabber", "Service discovery for %s\n", server_name);
 	if (js->last_disco_server)
 		g_free(js->last_disco_server);
@@ -889,18 +928,20 @@
 	PurpleRequestFieldGroup *g;
 	PurpleRequestField *f;
 	JabberStream *js;
+	struct jabber_disco_list_data *disco_list_data;
 	const char *last_server;
-	
+
 	purple_debug_misc("disco.c", "get_list\n");
 
 	js = purple_connection_get_protocol_data(gc);
-	purple_disco_list_set_proto_data(list, js);
+
+	disco_list_data = g_new0(struct jabber_disco_list_data, 1);
+	purple_disco_list_set_protocol_data(list, disco_list_data);
 
 	last_server = js->last_disco_server;
 	if (last_server == NULL)
 		last_server = js->user->domain;
 
-
 	fields = purple_request_fields_new();
 	g = purple_request_field_group_new(NULL);
 	f = purple_request_field_string_new("server", _("Server"), 
@@ -917,23 +958,24 @@
 		NULL,
 		fields,
 		_("OK"), G_CALLBACK(jabber_disco_server_cb),
-		_("Cancel"), NULL,
+		_("Cancel"), G_CALLBACK(jabber_disco_cancel),
 		purple_connection_get_account(gc), NULL, NULL, list);
 }
 
 void
 jabber_disco_cancel(PurpleDiscoList *list)
 {
-	purple_disco_list_set_proto_data(list, NULL);
-	purple_disco_set_in_progress(list, FALSE);	
+	jabber_disco_list_data_destroy(purple_disco_list_get_protocol_data(list));
+	purple_disco_list_set_protocol_data(list, NULL);
+	purple_disco_list_set_in_progress(list, FALSE);	
 }
 
 int
 jabber_disco_service_register(PurpleConnection *gc, PurpleDiscoService *service)
 {
-	JabberStream *js = gc->proto_data;
-	
-	jabber_register_gateway(js, service->name);
+	JabberStream *js = purple_connection_get_protocol_data(gc);
+
+	jabber_register_gateway(js, purple_disco_service_get_name(service));
 
 	return 0;
 }
--- a/pidgin/gtkdisco.c	Sun Mar 29 21:17:34 2009 +0000
+++ b/pidgin/gtkdisco.c	Mon Mar 30 00:42:15 2009 +0000
@@ -74,9 +74,13 @@
 static void register_button_cb(GtkButton *button, PidginDiscoDialog *dialog)
 {
 	struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "disco-info");
-	PurpleConnection *gc = purple_account_get_connection(info->list->account);
+	PurpleAccount *account;
+	PurpleConnection *gc;
 
-	purple_disco_service_register(gc, info->service);
+	account = purple_disco_list_get_account(info->list);
+	gc = purple_account_get_connection(account);
+
+	purple_disco_service_register(info->service);
 }
 
 static void list_button_cb(GtkButton *button, PidginDiscoDialog *dialog)
@@ -92,25 +96,31 @@
 	
 	dialog->discolist = purple_disco_list_new(dialog->account, (void*) dialog);
 
-	purple_disco_get_list(gc, dialog->discolist);
+	purple_disco_get_list(dialog->discolist);
 }
 
 static void add_room_to_blist_cb(GtkButton *button, PidginDiscoDialog *dialog)
 {
 	struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "disco-info");
+	PurpleAccount *account;
+	const char *name;
 
-	if (info) {
-		if (info->service->category == PURPLE_DISCO_SERVICE_CAT_MUC)
-			purple_blist_request_add_chat(info->list->account, NULL, NULL, info->service->name);
-		else
-			purple_blist_request_add_buddy(info->list->account, info->service->name, NULL, NULL);
-	}
+	g_return_if_fail(info != NULL);
+
+	account = purple_disco_list_get_account(info->list);
+	name = purple_disco_service_get_name(info->service);
+
+	if (purple_disco_service_get_category(info->service) == PURPLE_DISCO_SERVICE_CAT_MUC)
+		purple_blist_request_add_chat(account, NULL, NULL, name);
+	else
+		purple_blist_request_add_buddy(account, name, NULL, NULL);
 }
 
 static void
 selection_changed_cb(GtkTreeSelection *selection, PidginDiscoDialog *dialog) 
 {
 	PurpleDiscoService *service;
+	PurpleDiscoServiceFlags flags;
 	GtkTreeIter iter;
 	GValue val;
 	static struct _menu_cb_info *info;
@@ -132,8 +142,10 @@
 		g_object_set_data(G_OBJECT(dialog->add_button), "disco-info", info);
 		g_object_set_data(G_OBJECT(dialog->register_button), "disco-info", info);
 
-		gtk_widget_set_sensitive(dialog->add_button, service->flags & PURPLE_DISCO_FLAG_ADD);
-		gtk_widget_set_sensitive(dialog->register_button, service->flags & PURPLE_DISCO_FLAG_REGISTER);
+		flags = purple_disco_service_get_flags(service);
+
+		gtk_widget_set_sensitive(dialog->add_button, flags & PURPLE_DISCO_ADD);
+		gtk_widget_set_sensitive(dialog->register_button, flags & PURPLE_DISCO_REGISTER);
 	} else {
 		gtk_widget_set_sensitive(dialog->add_button, FALSE);
 		gtk_widget_set_sensitive(dialog->register_button, FALSE);
@@ -367,7 +379,9 @@
 static void
 pidgin_disco_create(PurpleDiscoList *list)
 {
-	PidginDiscoDialog *dialog = (PidginDiscoDialog *) list->ui_data;
+	PidginDiscoDialog *dialog;
+
+	dialog = purple_disco_list_get_ui_data(list);
 
 	dialog->cats = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)gtk_tree_row_reference_free);
 }
@@ -376,14 +390,18 @@
 static void
 pidgin_disco_destroy(PurpleDiscoList *list)
 {
-	PidginDiscoDialog *dialog = (PidginDiscoDialog *) list->ui_data;
+	PidginDiscoDialog *dialog;
+	
+	dialog = purple_disco_list_get_ui_data(list);
 
 	g_hash_table_destroy(dialog->cats);
 }
 
 static void pidgin_disco_in_progress(PurpleDiscoList *list, gboolean in_progress)
 {
-	PidginDiscoDialog *dialog = (PidginDiscoDialog *) list->ui_data;
+	PidginDiscoDialog *dialog;
+	
+	dialog = purple_disco_list_get_ui_data(list);
 
 	if (!dialog)
 		return;
@@ -405,14 +423,18 @@
 
 static void pidgin_disco_add_service(PurpleDiscoList *list, PurpleDiscoService *service, PurpleDiscoService *parent)
 {
-	PidginDiscoDialog *dialog = (PidginDiscoDialog *) list->ui_data;
+	PidginDiscoDialog *dialog;
+	PurpleDiscoServiceCategory category;
+	PurpleDiscoServiceType type;
 	GtkTreeIter iter, parent_iter;
 	GtkTreeRowReference *rr;
 	GtkTreePath *path;
 	char *filename = NULL;
 	GdkPixbuf *pixbuf = NULL;
 
-	purple_debug_info("disco", "Add_service \"%s\"\n", service->name);
+	dialog = purple_disco_list_get_ui_data(list);
+
+	purple_debug_info("disco", "Add_service \"%s\"\n", purple_disco_service_get_name(service));
 
 	gtk_progress_bar_pulse(GTK_PROGRESS_BAR(dialog->progress));
 
@@ -426,28 +448,31 @@
 	}
 
 	gtk_tree_store_append(dialog->model, &iter, (parent ? &parent_iter : NULL));
-	
-	if (service->type == PURPLE_DISCO_SERVICE_TYPE_XMPP)
+
+	category = purple_disco_service_get_category(service);
+	type = purple_disco_service_get_type(service);
+
+	if (type == PURPLE_DISCO_SERVICE_TYPE_XMPP)
 		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", "jabber.png", NULL);
-	else if (service->type == PURPLE_DISCO_SERVICE_TYPE_ICQ)
+	else if (type == PURPLE_DISCO_SERVICE_TYPE_ICQ)
 		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", "icq.png", NULL);
-	else if (service->type == PURPLE_DISCO_SERVICE_TYPE_YAHOO)
+	else if (type == PURPLE_DISCO_SERVICE_TYPE_YAHOO)
 		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", "yahoo.png", NULL);
-	else if (service->type == PURPLE_DISCO_SERVICE_TYPE_GTALK)
+	else if (type == PURPLE_DISCO_SERVICE_TYPE_GTALK)
 		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", "google-talk.png", NULL);
-	else if (service->type == PURPLE_DISCO_SERVICE_TYPE_IRC)
+	else if (type == PURPLE_DISCO_SERVICE_TYPE_IRC)
 		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", "irc.png", NULL);
-	else if (service->type == PURPLE_DISCO_SERVICE_TYPE_GG)
+	else if (type == PURPLE_DISCO_SERVICE_TYPE_GG)
 		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", "gadu-gadu.png", NULL);
-	else if (service->type == PURPLE_DISCO_SERVICE_TYPE_AIM)
+	else if (type == PURPLE_DISCO_SERVICE_TYPE_AIM)
 		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", "aim.png", NULL);
-	else if (service->type == PURPLE_DISCO_SERVICE_TYPE_QQ)
+	else if (type == PURPLE_DISCO_SERVICE_TYPE_QQ)
 		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", "qq.png", NULL);
-	else if (service->type == PURPLE_DISCO_SERVICE_TYPE_MSN)
+	else if (type == PURPLE_DISCO_SERVICE_TYPE_MSN)
 		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", "msn.png", NULL);
-	else if (service->type == PURPLE_DISCO_SERVICE_TYPE_USER)
+	else if (type == PURPLE_DISCO_SERVICE_TYPE_USER)
 		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "status", "22", "person.png", NULL);
-	else if (service->category == PURPLE_DISCO_SERVICE_CAT_MUC)
+	else if (category == PURPLE_DISCO_SERVICE_CAT_MUC)
 		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "status", "22", "chat.png", NULL);
 
 	if (filename) {
@@ -457,8 +482,8 @@
 
 	gtk_tree_store_set(dialog->model, &iter,
 			PIXBUF_COLUMN, pixbuf,
-			NAME_COLUMN, service->name,
-			DESCRIPTION_COLUMN, service->description,
+			NAME_COLUMN, purple_disco_service_get_name(service),
+			DESCRIPTION_COLUMN, purple_disco_service_get_description(service),
 			SERVICE_COLUMN, service,
 			-1);