[compiz] dbus introspection

Travis Watkins alleykat at gmail.com
Tue Mar 13 19:14:00 PDT 2007


On 3/4/07, Travis Watkins <alleykat at gmail.com> wrote:
> Known problems:
>   * still don't know what to do with activate/deactivate
>   * had to comment out a couple free()s in my added code to make it
> work, dunno why
>

Redid the patch split up into smaller patches to be more easily
reviewed. I'd really like to see these go in soon as I have future
plans for the dbus plugin but don't want to diverge too far.

-- 
Travis Watkins
http://www.realistanew.com
-------------- next part --------------
From a37a817f6b95168e4450697a78b754b397730a81 Mon Sep 17 00:00:00 2001
From: Travis Watkins <amaranth at ubuntu.com>
Date: Tue, 13 Mar 2007 19:50:05 -0500
Subject: [PATCH] Add functions to generate dbus introspection XML.

---
 plugins/dbus.c |  106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 106 insertions(+), 0 deletions(-)

diff --git a/plugins/dbus.c b/plugins/dbus.c
index 782ad24..e8e1051 100644
--- a/plugins/dbus.c
+++ b/plugins/dbus.c
@@ -29,6 +29,7 @@
 
 #define DBUS_API_SUBJECT_TO_CHANGE
 #include <dbus/dbus.h>
+#include <libxml/xmlwriter.h>
 
 #include <compiz.h>
 
@@ -150,6 +151,111 @@ dbusGetOptionsFromPath (CompDisplay *d,
     return NULL;
 }
 
+/* functions to create introspection XML */
+static void
+dbusIntrospectStartInterface (xmlTextWriterPtr writer)
+{
+    xmlTextWriterStartElement (writer, BAD_CAST "interface");
+    xmlTextWriterWriteAttribute (writer, BAD_CAST "name",
+				 BAD_CAST COMPIZ_DBUS_SERVICE_NAME);
+}
+
+static void
+dbusIntrospectEndInterface (xmlTextWriterPtr writer)
+{
+    xmlTextWriterEndElement (writer);
+}
+
+static void
+dbusIntrospectAddArgument (xmlTextWriterPtr writer,
+			   char             *type,
+			   char             *direction)
+{
+    xmlTextWriterStartElement (writer, BAD_CAST "arg");
+    xmlTextWriterWriteAttribute (writer, BAD_CAST "type", BAD_CAST type);
+    xmlTextWriterWriteAttribute (writer, BAD_CAST "direction",
+				 BAD_CAST direction);
+    xmlTextWriterEndElement (writer);
+}
+
+static void
+dbusIntrospectAddMethod (xmlTextWriterPtr writer,
+			 char             *name,
+			 int              nArgs,
+			 ...)
+{
+    va_list var_args;
+    char *type, *direction;
+
+    xmlTextWriterStartElement (writer, BAD_CAST "method");
+    xmlTextWriterWriteAttribute (writer, BAD_CAST "name", BAD_CAST name);
+
+    va_start (var_args, nArgs);
+    while (nArgs)
+    {
+	type = va_arg (var_args, char *);
+	direction = va_arg (var_args, char *);
+	dbusIntrospectAddArgument (writer, type, direction);
+	nArgs--;
+    }
+    va_end (var_args);
+
+    xmlTextWriterEndElement (writer);
+}
+
+static void
+dbusIntrospectAddSignal (xmlTextWriterPtr writer,
+			 char             *name,
+			 int              nArgs,
+			 ...)
+{
+    va_list var_args;
+    char *type;
+
+    xmlTextWriterStartElement (writer, BAD_CAST "signal");
+    xmlTextWriterWriteAttribute (writer, BAD_CAST "name", BAD_CAST name);
+
+    va_start (var_args, nArgs);
+    while (nArgs)
+    {
+	type = va_arg (var_args, char *);
+	dbusIntrospectAddArgument (writer, type, "out");
+	nArgs--;
+    }
+    va_end (var_args);
+
+    xmlTextWriterEndElement (writer);
+}
+
+static void
+dbusIntrospectAddNode (xmlTextWriterPtr writer,
+		       char             *name)
+{
+    xmlTextWriterStartElement (writer, BAD_CAST "node");
+    xmlTextWriterWriteAttribute (writer, BAD_CAST "name", BAD_CAST name);
+    xmlTextWriterEndElement (writer);
+}
+
+static void
+dbusIntrospectStartRoot (xmlTextWriterPtr writer)
+{
+    xmlTextWriterStartElement (writer, BAD_CAST "node");
+
+    xmlTextWriterStartElement (writer, BAD_CAST "interface");
+    xmlTextWriterWriteAttribute (writer, BAD_CAST "name",
+				 BAD_CAST "org.freedesktop.DBus.Introspectable");
+
+    dbusIntrospectAddMethod (writer, "Introspect", 1, "s", "out");
+
+    xmlTextWriterEndElement (writer);
+}
+
+static void
+dbusIntrospectEndRoot (xmlTextWriterPtr writer)
+{
+    xmlTextWriterEndDocument (writer);
+}
+
 /*
  * Activate can be used to trigger any existing action. Arguments
  * should be a pair of { string, bool|int32|double|string }.
-- 
1.4.4.2
-------------- next part --------------
From 469cf743d8d16a6b344bd09e5a9cfe2019550bdc Mon Sep 17 00:00:00 2001
From: Travis Watkins <amaranth at ubuntu.com>
Date: Tue, 13 Mar 2007 19:51:10 -0500
Subject: [PATCH] Add libxml2 build dependency.

---
 configure.ac |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/configure.ac b/configure.ac
index 7b3863c..8e1937d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -171,7 +171,7 @@ AC_ARG_ENABLE(dbus,
   [use_dbus=$enableval], [use_dbus=yes])
 
 if test "x$use_dbus" = "xyes"; then
-  PKG_CHECK_MODULES(DBUS, dbus-1, [use_dbus=yes], [use_dbus=no])
+  PKG_CHECK_MODULES(DBUS, dbus-1 libxml-2.0, [use_dbus=yes], [use_dbus=no])
 fi
 
 AM_CONDITIONAL(DBUS_PLUGIN, test "x$use_dbus" = "xyes")
-- 
1.4.4.2
-------------- next part --------------
From c6d5c2acbacb48cd57d92d4f3aa97b7677d92421 Mon Sep 17 00:00:00 2001
From: Travis Watkins <amaranth at ubuntu.com>
Date: Tue, 13 Mar 2007 20:02:41 -0500
Subject: [PATCH] Add dbus introspection generation functions.

---
 plugins/dbus.c |  385 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 385 insertions(+), 0 deletions(-)

diff --git a/plugins/dbus.c b/plugins/dbus.c
index e8e1051..14b9b00 100644
--- a/plugins/dbus.c
+++ b/plugins/dbus.c
@@ -256,6 +256,391 @@ dbusIntrospectEndRoot (xmlTextWriterPtr writer)
     xmlTextWriterEndDocument (writer);
 }
 
+/* introspection handlers */
+static Bool
+dbusHandleRootIntrospectMessage (DBusConnection *connection,
+				 DBusMessage    *message,
+				 CompDisplay	*d)
+{
+    char **plugins, **plugin_name;
+    int nPlugins;
+
+    xmlTextWriterPtr writer;
+    xmlBufferPtr buf;
+
+    buf = xmlBufferCreate ();
+    writer = xmlNewTextWriterMemory (buf, 0);
+
+    dbusIntrospectStartRoot (writer);
+    dbusIntrospectStartInterface (writer);
+
+    dbusIntrospectAddMethod (writer, COMPIZ_DBUS_GET_PLUGINS_MEMBER_NAME, 1,
+			     "as", "out");
+    dbusIntrospectAddMethod (writer,
+			     COMPIZ_DBUS_GET_PLUGIN_METADATA_MEMBER_NAME, 7,
+			     "s", "in", "s", "out", "s", "out", "s", "out",
+			     "b", "out", "as", "out", "as", "out");
+    dbusIntrospectAddSignal (writer,
+			     COMPIZ_DBUS_PLUGINS_CHANGED_SIGNAL_NAME, 0);
+
+    dbusIntrospectEndInterface (writer);
+
+    plugins = availablePlugins (&nPlugins);
+    if (plugins)
+    {
+	plugin_name = plugins;
+
+	while (nPlugins--)
+	{
+	    dbusIntrospectAddNode (writer, *plugin_name);
+	    free (*plugin_name);
+	    plugin_name++;
+	}
+
+	free (plugins);
+    }
+    else
+    {
+	xmlFreeTextWriter (writer);
+	xmlBufferFree (buf);
+	return FALSE;
+    }
+
+    dbusIntrospectAddNode (writer, "core");
+
+    dbusIntrospectEndRoot (writer);
+
+    xmlFreeTextWriter (writer);
+
+    DBusMessage *reply = dbus_message_new_method_return (message);
+    if (!reply)
+    {
+	xmlBufferFree (buf);
+	return FALSE;
+    }
+
+    DBusMessageIter args;
+    dbus_message_iter_init_append (reply, &args);
+
+    if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING,
+					 &buf->content))
+    {
+	xmlBufferFree (buf);
+	return FALSE;
+    }
+
+    xmlBufferFree (buf);
+
+    if (!dbus_connection_send (connection, reply, NULL))
+    {
+	return FALSE;
+    }
+
+    dbus_connection_flush (connection);
+    dbus_message_unref (reply);
+
+    return TRUE;
+}
+
+static Bool
+dbusHandlePluginIntrospectMessage (DBusConnection *connection,
+				    DBusMessage   *message,
+				    CompDisplay	  *d,
+				    char          **path)
+{
+    CompScreen *s;
+    char screen_name[256];
+
+    xmlTextWriterPtr writer;
+    xmlBufferPtr buf;
+
+    buf = xmlBufferCreate ();
+    writer = xmlNewTextWriterMemory (buf, 0);
+
+    dbusIntrospectStartRoot (writer);
+
+    dbusIntrospectAddNode (writer, "allscreens");
+
+    for (s = d->screens; s; s = s->next)
+    {
+	sprintf (screen_name, "screen%d", s->screenNum);
+	dbusIntrospectAddNode (writer, screen_name);
+    }
+
+    dbusIntrospectEndRoot (writer);
+
+    xmlFreeTextWriter (writer);
+
+    DBusMessage *reply = dbus_message_new_method_return (message);
+    if (!reply)
+    {
+	xmlBufferFree (buf);
+	return FALSE;
+    }
+
+    DBusMessageIter args;
+    dbus_message_iter_init_append (reply, &args);
+
+    if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING,
+					 &buf->content))
+    {
+	xmlBufferFree (buf);
+	return FALSE;
+    }
+
+    xmlBufferFree (buf);
+
+    if (!dbus_connection_send (connection, reply, NULL))
+    {
+	return FALSE;
+    }
+
+    dbus_connection_flush (connection);
+    dbus_message_unref (reply);
+
+    return TRUE;
+}
+
+static Bool
+dbusHandleScreenIntrospectMessage (DBusConnection *connection,
+				   DBusMessage    *message,
+				   CompDisplay	  *d,
+				   char           **path)
+{
+    CompOption *option = NULL;
+    int nOptions;
+
+    xmlTextWriterPtr writer;
+    xmlBufferPtr buf;
+
+    buf = xmlBufferCreate ();
+    writer = xmlNewTextWriterMemory (buf, 0);
+
+    dbusIntrospectStartRoot (writer);
+    dbusIntrospectStartInterface (writer);
+
+    dbusIntrospectAddMethod (writer, COMPIZ_DBUS_LIST_MEMBER_NAME, 1,
+			     "as", "out");
+
+    dbusIntrospectEndInterface (writer);
+
+    option = dbusGetOptionsFromPath (d, path, NULL, &nOptions);
+    if (option)
+    {
+	while (nOptions--)
+	{
+	    dbusIntrospectAddNode (writer, option->name);
+	    option++;
+	}
+    }
+
+    dbusIntrospectEndRoot (writer);
+
+    xmlFreeTextWriter (writer);
+
+    DBusMessage *reply = dbus_message_new_method_return (message);
+    if (!reply)
+    {
+	xmlBufferFree (buf);
+	return FALSE;
+    }
+
+    DBusMessageIter args;
+    dbus_message_iter_init_append (reply, &args);
+
+    if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING,
+					 &buf->content))
+    {
+	xmlBufferFree (buf);
+	return FALSE;
+    }
+
+    xmlBufferFree (buf);
+
+    if (!dbus_connection_send (connection, reply, NULL))
+    {
+	return FALSE;
+    }
+
+    dbus_connection_flush (connection);
+    dbus_message_unref (reply);
+
+    return TRUE;
+}
+
+static Bool
+dbusHandleOptionIntrospectMessage (DBusConnection *connection,
+				   DBusMessage    *message,
+				   CompDisplay	  *d,
+				   char           **path)
+{
+    CompOption *option;
+    int nOptions;
+    CompOptionType restrictionType;
+    Bool getHandled, metadataHandled;
+    char *type;
+    xmlTextWriterPtr writer;
+    xmlBufferPtr buf;
+    Bool is_list = FALSE;
+
+    buf = xmlBufferCreate ();
+    writer = xmlNewTextWriterMemory (buf, 0);
+
+    dbusIntrospectStartRoot (writer);
+    dbusIntrospectStartInterface (writer);
+
+    option = dbusGetOptionsFromPath (d, path, NULL, &nOptions);
+    if (!option)
+    {
+	xmlFreeTextWriter (writer);
+	xmlBufferFree (buf);
+	return FALSE;
+    }
+
+    while (nOptions--)
+    {
+	if (strcmp (option->name, path[2]) == 0)
+	{
+	    restrictionType = option->type;
+	    if (restrictionType == CompOptionTypeList)
+	    {
+		restrictionType = option->value.list.type;
+		is_list = TRUE;
+	    }
+
+	    getHandled = metadataHandled = FALSE;
+	    switch (restrictionType)
+	    {
+	    case CompOptionTypeInt:
+		if (is_list)
+		    type = "ai";
+		else
+		    type = "i";
+
+		dbusIntrospectAddMethod (writer,
+					 COMPIZ_DBUS_GET_METADATA_MEMBER_NAME,
+					 6, "s", "out", "s", "out",
+					 "b", "out", "s", "out",
+					 "i", "out", "i", "out");
+		metadataHandled = TRUE;
+		break;
+	    case CompOptionTypeFloat:
+		if (is_list)
+		    type = "ad";
+		else
+		    type = "d";
+
+		dbusIntrospectAddMethod (writer,
+					 COMPIZ_DBUS_GET_METADATA_MEMBER_NAME,
+					 7, "s", "out", "s", "out",
+					 "b", "out", "s", "out",
+					 "d", "out", "d", "out",
+					 "d", "out");
+		metadataHandled = TRUE;
+		break;
+	    case CompOptionTypeString:
+		if (is_list)
+		    type = "as";
+		else
+		    type = "s";
+
+		dbusIntrospectAddMethod (writer,
+					 COMPIZ_DBUS_GET_METADATA_MEMBER_NAME,
+					 5, "s", "out", "s", "out",
+					 "b", "out", "s", "out",
+					 "as", "out");
+		metadataHandled = TRUE;
+		break;
+	    case CompOptionTypeBool:
+		if (is_list)
+		    type = "ab";
+		else
+		    type = "b";
+
+		break;
+	    case CompOptionTypeAction:
+		dbusIntrospectAddMethod (writer, COMPIZ_DBUS_GET_MEMBER_NAME,
+					    5, "s", "out", "s", "out",
+					    "b", "out", "s", "out", "i", "out");
+		dbusIntrospectAddMethod (writer, COMPIZ_DBUS_SET_MEMBER_NAME,
+					    5, "s", "in", "s", "in",
+					    "b", "in", "s", "in", "i", "in");
+		dbusIntrospectAddSignal (writer,
+					 COMPIZ_DBUS_CHANGED_SIGNAL_NAME, 5,
+					 "s", "out", "s", "out", "b", "out",
+					 "s", "out", "i", "out");
+		getHandled = TRUE;
+		break;
+	    case CompOptionTypeColor:
+	    case CompOptionTypeMatch:
+		if (is_list)
+		    type = "as";
+		else
+		    type = "s";
+
+		break;
+	    }
+
+	    if (!getHandled)
+	    {
+		dbusIntrospectAddMethod (writer,
+					 COMPIZ_DBUS_GET_MEMBER_NAME, 1,
+					 type, "out");
+		dbusIntrospectAddMethod (writer,
+					 COMPIZ_DBUS_SET_MEMBER_NAME, 1,
+					 type, "in");
+		dbusIntrospectAddSignal (writer,
+					 COMPIZ_DBUS_CHANGED_SIGNAL_NAME, 1,
+					 type, "out");
+	    }
+
+	    if (!metadataHandled)
+		dbusIntrospectAddMethod (writer,
+					 COMPIZ_DBUS_GET_METADATA_MEMBER_NAME,
+					 4, "s", "out", "s", "out",
+					 "b", "out", "s", "out");
+	    break;
+	}
+
+	option++;
+    }
+
+    dbusIntrospectEndInterface (writer);
+    dbusIntrospectEndRoot (writer);
+
+    xmlFreeTextWriter (writer);
+
+    DBusMessage *reply = dbus_message_new_method_return (message);
+    if (!reply)
+    {
+	xmlBufferFree (buf);
+	return FALSE;
+    }
+
+    DBusMessageIter args;
+    dbus_message_iter_init_append (reply, &args);
+
+    if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING,
+					 &buf->content))
+    {
+	xmlBufferFree (buf);
+	return FALSE;
+    }
+
+    xmlBufferFree (buf);
+
+    if (!dbus_connection_send (connection, reply, NULL))
+    {
+	return FALSE;
+    }
+
+    dbus_connection_flush (connection);
+    dbus_message_unref (reply);
+
+    return TRUE;
+}
+
+
 /*
  * Activate can be used to trigger any existing action. Arguments
  * should be a pair of { string, bool|int32|double|string }.
-- 
1.4.4.2
-------------- next part --------------
From 57b37f24cb392af0c1145284932ac65b2e4fcba5 Mon Sep 17 00:00:00 2001
From: Travis Watkins <amaranth at ubuntu.com>
Date: Tue, 13 Mar 2007 20:16:44 -0500
Subject: [PATCH] Switch to object registration instead of message filtering.

---
 plugins/dbus.c |  154 +++++++++++++++++++++++++++++++-------------------------
 1 files changed, 86 insertions(+), 68 deletions(-)

diff --git a/plugins/dbus.c b/plugins/dbus.c
index 14b9b00..eeee3d3 100644
--- a/plugins/dbus.c
+++ b/plugins/dbus.c
@@ -34,6 +34,8 @@
 #include <compiz.h>
 
 #define COMPIZ_DBUS_SERVICE_NAME	            "org.freedesktop.compiz"
+#define COMPIZ_DBUS_INTERFACE			    "org.freedesktop.compiz"
+#define COMPIZ_DBUS_ROOT_PATH			    "/org/freedesktop/compiz"
 
 #define COMPIZ_DBUS_ACTIVATE_MEMBER_NAME            "activate"
 #define COMPIZ_DBUS_DEACTIVATE_MEMBER_NAME          "deactivate"
@@ -79,6 +81,15 @@ typedef struct _DbusScreen {
     SetScreenOptionForPluginProc setScreenOptionForPlugin;
 } DbusScreen;
 
+static DBusHandlerResult dbusHandleMessage (DBusConnection *,
+					    DBusMessage *,
+					    void *);
+
+static DBusObjectPathVTable dbus_messages_vtable = {
+    NULL, dbusHandleMessage, /* handler function */
+    NULL, NULL, NULL, NULL
+};
+
 #define GET_DBUS_DISPLAY(d)				     \
     ((DbusDisplay *) (d)->privates[displayPrivateIndex].ptr)
 
@@ -1703,20 +1714,6 @@ dbusHandleMessage (DBusConnection *connection,
     CompDisplay *d = (CompDisplay *) userData;
     Bool	status = FALSE;
     char	**path;
-    const char  *service, *interface, *member;
-
-    service   = dbus_message_get_destination (message);
-    interface = dbus_message_get_interface (message);
-    member    = dbus_message_get_member (message);
-
-    if (!service || !interface || !member)
-	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    if (!dbus_message_is_method_call (message, interface, member))
-	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    if (!dbus_message_has_destination (message, COMPIZ_DBUS_SERVICE_NAME))
-	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
     if (!dbus_message_get_path_decomposed (message, &path))
 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -1727,75 +1724,105 @@ dbusHandleMessage (DBusConnection *connection,
 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
 
-    if (strcmp (path[0], "org")	        ||
-	strcmp (path[1], "freedesktop") ||
-	strcmp (path[2], "compiz"))
+    //root messages
+    if (!path[3])
     {
-	dbus_free_string_array (path);
-	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
-
-    if (dbus_message_has_member (message,
+	if (dbus_message_is_method_call (message, DBUS_INTERFACE_INTROSPECTABLE,
+					 "Introspect"))
+	{
+	    if (dbusHandleRootIntrospectMessage (connection, message, d))
+	    {
+		dbus_free_string_array (path);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	    }
+	}
+	else if (dbus_message_is_method_call (message, COMPIZ_DBUS_INTERFACE,
 				 COMPIZ_DBUS_GET_PLUGIN_METADATA_MEMBER_NAME))
-    {
-	if (dbusHandleGetPluginMetadataMessage (connection, message, d))
 	{
-	    dbus_free_string_array (path);
-	    return DBUS_HANDLER_RESULT_HANDLED;
+	    if (dbusHandleGetPluginMetadataMessage (connection, message, d))
+	    {
+		dbus_free_string_array (path);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	    }
 	}
-    }
-    else if (dbus_message_has_member (message,
-				      COMPIZ_DBUS_GET_PLUGINS_MEMBER_NAME))
-    {
-	if (dbusHandleGetPluginsMessage (connection, message, d))
+	else if (dbus_message_is_method_call (message, COMPIZ_DBUS_INTERFACE,
+					  COMPIZ_DBUS_GET_PLUGINS_MEMBER_NAME))
 	{
-	    dbus_free_string_array (path);
-	    return DBUS_HANDLER_RESULT_HANDLED;
+	    if (dbusHandleGetPluginsMessage (connection, message, d))
+	    {
+		dbus_free_string_array (path);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	    }
 	}
     }
-
-    if (!path[3] || !path[4])
+    //plugin message
+    else if (!path[4])
     {
-	dbus_free_string_array (path);
-	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	if (dbus_message_is_method_call (message, DBUS_INTERFACE_INTROSPECTABLE,
+					 "Introspect"))
+	{
+	    if (dbusHandlePluginIntrospectMessage (connection, message, d,
+						   &path[3]))
+	    {
+		dbus_free_string_array (path);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	    }
+	}
     }
-
-    if (dbus_message_has_member (message, COMPIZ_DBUS_LIST_MEMBER_NAME))
+    //screen message
+    else if (!path[5])
     {
-	if (dbusHandleListMessage (connection, message, d, &path[3]))
+	if (dbus_message_is_method_call (message, DBUS_INTERFACE_INTROSPECTABLE,
+					 "Introspect"))
 	{
-	    dbus_free_string_array (path);
-	    return DBUS_HANDLER_RESULT_HANDLED;
+	    if (dbusHandleScreenIntrospectMessage (connection, message, d,
+						   &path[3]))
+	    {
+		dbus_free_string_array (path);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	    }
+	}
+	else if (dbus_message_is_method_call (message, COMPIZ_DBUS_INTERFACE,
+					      COMPIZ_DBUS_LIST_MEMBER_NAME))
+	{
+	    if (dbusHandleListMessage (connection, message, d, &path[3]))
+	    {
+		dbus_free_string_array (path);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	    }
 	}
     }
-
-    if (!path[5])
+    //option message
+    if (dbus_message_is_method_call (message, DBUS_INTERFACE_INTROSPECTABLE,
+				     "Introspect"))
     {
-	dbus_free_string_array (path);
-	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	status = dbusHandleOptionIntrospectMessage (connection, message, d,
+						    &path[3]);
     }
-
-    if (dbus_message_has_member (message, COMPIZ_DBUS_ACTIVATE_MEMBER_NAME))
+    else if (dbus_message_is_method_call (message, COMPIZ_DBUS_INTERFACE,
+					  COMPIZ_DBUS_ACTIVATE_MEMBER_NAME))
     {
 	status = dbusHandleActionMessage (connection, message, d, &path[3],
 					  TRUE);
     }
-    else if (dbus_message_has_member (message,
-				      COMPIZ_DBUS_DEACTIVATE_MEMBER_NAME))
+    else if (dbus_message_is_method_call (message, COMPIZ_DBUS_INTERFACE,
+					  COMPIZ_DBUS_DEACTIVATE_MEMBER_NAME))
     {
 	status = dbusHandleActionMessage (connection, message, d, &path[3],
 					  FALSE);
     }
-    else if (dbus_message_has_member (message, COMPIZ_DBUS_SET_MEMBER_NAME))
+    else if (dbus_message_is_method_call (message, COMPIZ_DBUS_INTERFACE,
+					  COMPIZ_DBUS_SET_MEMBER_NAME))
     {
 	status = dbusHandleSetOptionMessage (connection, message, d, &path[3]);
     }
-    else if (dbus_message_has_member (message, COMPIZ_DBUS_GET_MEMBER_NAME))
+    else if (dbus_message_is_method_call (message, COMPIZ_DBUS_INTERFACE,
+					  COMPIZ_DBUS_GET_MEMBER_NAME))
     {
 	status = dbusHandleGetOptionMessage (connection, message, d, &path[3]);
     }
-    else if (dbus_message_has_member (message,
-				      COMPIZ_DBUS_GET_METADATA_MEMBER_NAME))
+    else if (dbus_message_is_method_call (message, COMPIZ_DBUS_INTERFACE,
+					  COMPIZ_DBUS_GET_METADATA_MEMBER_NAME))
     {
 	status = dbusHandleGetMetadataMessage (connection, message, d,
 					       &path[3]);
@@ -2093,20 +2120,11 @@ dbusInitDisplay (CompPlugin  *p,
 	return FALSE;
     }
 
-    status = dbus_connection_add_filter (dd->connection,
-					 dbusHandleMessage,
-					 d, NULL);
-    if (!status)
-    {
-	fprintf (stderr, "%s: dbus_connection_add_filter failed\n",
-		 programName);
-
-	/* dbus_connection_unref (dd->connection); */
-	free (dd);
-
-	return FALSE;
-    }
-
+    //register the objects
+    dbus_connection_register_object_path (dd->connection,
+					  COMPIZ_DBUS_ROOT_PATH,
+					  &dbus_messages_vtable, d);
+ 
     status = dbus_connection_get_unix_fd (dd->connection, &fd);
     if (!status)
     {
-- 
1.4.4.2
-------------- next part --------------
From fb8379e4c6841726aba9acb460d7cf842b4bc751 Mon Sep 17 00:00:00 2001
From: Travis Watkins <amaranth at ubuntu.com>
Date: Tue, 13 Mar 2007 20:34:26 -0500
Subject: [PATCH] Register plugin, screen, and option objects.

---
 plugins/dbus.c |  222 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 222 insertions(+), 0 deletions(-)

diff --git a/plugins/dbus.c b/plugins/dbus.c
index eeee3d3..3eef210 100644
--- a/plugins/dbus.c
+++ b/plugins/dbus.c
@@ -1907,6 +1907,226 @@ dbusSendChangeSignalForScreenOption (CompScreen *s,
 }
 
 static Bool
+dbusGetPathDecomposed (char *data,
+		       char ***path)
+{
+    char **retval;
+    char *temp;
+    char *token;
+    int nComponents;
+    int i;
+
+    nComponents = 0;
+    if (strlen (data) > 1)
+    {
+	i = 0;
+	while (i < strlen (data))
+	{
+            if (data[i] == '/')
+		nComponents += 1;
+	    ++i;
+	}
+    }
+  
+    retval = malloc (sizeof (char*) * nComponents + 1);
+
+    if (nComponents == 0)
+    {
+	retval[0] = malloc (1);
+	retval[0][0] = '\0';
+	*path = retval;
+	return TRUE;
+    }
+
+    temp = strdup (data);
+
+    i = 0;
+    token = strtok (temp, "/");
+    while (token != NULL)
+    {
+	retval[i] = strdup (token);
+	token = strtok (NULL, "/");
+	i++;
+    }
+    free (temp);
+
+    *path = retval;
+    return TRUE;
+}
+
+/* dbus registration */
+static Bool
+dbusRegisterOptions (DBusConnection *connection,
+		     CompDisplay    *d,
+		     char           *screen_path)
+{
+    CompOption *option = NULL;
+    int nOptions, size;
+    char *option_path;
+    char **path;
+
+    dbusGetPathDecomposed (screen_path, &path);
+
+    option = dbusGetOptionsFromPath (d, &path[3], NULL, &nOptions);
+
+    if (!option)
+	return FALSE;
+
+    while (nOptions--)
+    {
+	size = strlen (screen_path) + strlen (option->name) + 2;
+	option_path = malloc (size);
+	snprintf (option_path, size, "%s/%s", screen_path, option->name);
+
+	dbus_connection_register_object_path (connection, option_path,
+					      &dbus_messages_vtable, d);
+	free (option_path);
+	option++;
+    }
+
+    return TRUE;
+}
+
+static Bool
+dbusUnregisterOptions (DBusConnection *connection,
+		       CompDisplay    *d,
+		       char           *screen_path)
+{
+    CompOption *option = NULL;
+    int nOptions, size;
+    char *option_path;
+    char **path;
+
+    dbusGetPathDecomposed (screen_path, &path);
+
+    option = dbusGetOptionsFromPath (d, &path[3], NULL, &nOptions);
+
+    if (!option)
+	return FALSE;
+
+    while (nOptions--)
+    {
+	size = strlen (screen_path) + strlen (option->name) + 2;
+	option_path = malloc (size);
+	snprintf (option_path, size, "%s/%s", screen_path, option->name);
+
+	dbus_connection_unregister_object_path (connection, option_path);
+	free (option_path);
+	option++;
+    }
+
+    return TRUE;
+}
+
+static void
+dbusRegisterScreen (DBusConnection *connection,
+		    CompDisplay   *d,
+		    char          *plugin_name,
+		    char          *screen_name)
+{
+    char *screen_path;
+    int  size;
+
+    size = strlen (COMPIZ_DBUS_ROOT_PATH) + strlen (plugin_name) +
+		strlen (screen_name) + 3;
+
+    screen_path = malloc (size);
+    snprintf (screen_path, size, "%s/%s/%s", COMPIZ_DBUS_ROOT_PATH,
+	      plugin_name, screen_name);
+    dbus_connection_register_object_path (connection, screen_path,
+					  &dbus_messages_vtable, d);
+    dbusRegisterOptions (connection, d, screen_path);
+    free (screen_path);
+}
+
+static void
+dbusUnregisterScreen (DBusConnection *connection,
+		      CompDisplay   *d,
+		      char          *plugin_name,
+		      char          *screen_name)
+{
+    char *screen_path;
+    int  size;
+
+    size = strlen (COMPIZ_DBUS_ROOT_PATH) + strlen (plugin_name) +
+		strlen (screen_name) + 3;
+
+    screen_path = malloc (size);
+    snprintf (screen_path, size, "%s/%s/%s", COMPIZ_DBUS_ROOT_PATH,
+	      plugin_name, screen_name);
+
+    dbusUnregisterOptions (connection, d, screen_path);
+    free (screen_path);
+}
+
+static Bool
+dbusRegisterScreens (DBusConnection *connection,
+		     CompDisplay    *d,
+		     char           *plugin_name)
+{
+    CompScreen *s;
+
+    dbusRegisterScreen (connection, d, plugin_name, "allscreens");
+
+    for (s = d->screens; s; s = s->next)
+    {
+	char screen_name[256];
+	sprintf (screen_name, "screen%d", s->screenNum);
+	dbusRegisterScreen (connection, d, plugin_name, screen_name);
+    }
+
+    return TRUE;
+}
+
+static void
+dbusRegisterPlugin (DBusConnection *connection,
+		    CompDisplay    *d,
+		    char           *plugin_name)
+{
+    int size;
+    char *plugin_path;
+
+    //root path + plugin name + separator + \0
+    size = strlen (COMPIZ_DBUS_ROOT_PATH) + strlen (plugin_name) + 2;
+    plugin_path = malloc (size);
+    snprintf (plugin_path, size, "%s/%s", COMPIZ_DBUS_ROOT_PATH, plugin_name);
+    dbus_connection_register_object_path (connection, plugin_path,
+					  &dbus_messages_vtable, d);
+
+    dbusRegisterScreens (connection, d, plugin_name);
+
+    free (plugin_path);
+}
+
+static Bool
+dbusRegisterPlugins (DBusConnection *connection,
+		     CompDisplay    *d)
+{
+    int nPlugins;
+    char **plugins, **plugin_name;
+
+    //register core 'plugin'
+    dbusRegisterPlugin (connection, d, "core");
+
+    plugins = availablePlugins (&nPlugins);
+    if (plugins)
+    {
+	plugin_name = plugins;
+	while (nPlugins--)
+	{
+		dbusRegisterPlugin (connection, d, *plugin_name);
+		free (*plugin_name);
+		plugin_name++;
+	}
+
+	free (plugins);
+	return TRUE;
+    }
+
+    return FALSE;
+}
+
+static Bool
 dbusSetDisplayOption (CompDisplay     *d,
 		      char	      *name,
 		      CompOptionValue *value)
@@ -2124,6 +2344,8 @@ dbusInitDisplay (CompPlugin  *p,
     dbus_connection_register_object_path (dd->connection,
 					  COMPIZ_DBUS_ROOT_PATH,
 					  &dbus_messages_vtable, d);
+
+    dbusRegisterPlugins (dd->connection, d);
  
     status = dbus_connection_get_unix_fd (dd->connection, &fd);
     if (!status)
-- 
1.4.4.2
-------------- next part --------------
From f198917e1c342e18ea8c6a886d542a43ae586ee3 Mon Sep 17 00:00:00 2001
From: Travis Watkins <amaranth at ubuntu.com>
Date: Tue, 13 Mar 2007 20:38:57 -0500
Subject: [PATCH] Register and unregister plugins on load and unload.

---
 plugins/dbus.c |   86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 85 insertions(+), 1 deletions(-)

diff --git a/plugins/dbus.c b/plugins/dbus.c
index 3eef210..376e7cc 100644
--- a/plugins/dbus.c
+++ b/plugins/dbus.c
@@ -74,11 +74,17 @@ typedef struct _DbusDisplay {
 
     SetDisplayOptionProc	  setDisplayOption;
     SetDisplayOptionForPluginProc setDisplayOptionForPlugin;
+
+    InitPluginForDisplayProc initPluginForDisplay;
+    FiniPluginForDisplayProc finiPluginForDisplay;
 } DbusDisplay;
 
 typedef struct _DbusScreen {
     SetScreenOptionProc		 setScreenOption;
     SetScreenOptionForPluginProc setScreenOptionForPlugin;
+
+    InitPluginForScreenProc initPluginForScreen;
+    FiniPluginForScreenProc finiPluginForScreen;
 } DbusScreen;
 
 static DBusHandlerResult dbusHandleMessage (DBusConnection *,
@@ -2275,6 +2281,76 @@ dbusSendPluginsChangedSignal (const char *name,
 }
 
 static Bool
+dbusInitPluginForDisplay (CompPlugin  *p,
+			  CompDisplay *d)
+{
+    DBUS_DISPLAY (d);
+    Bool status;
+
+    UNWRAP (dd, d, initPluginForDisplay);
+    status = (*d->initPluginForDisplay) (p, d);
+    WRAP (dd, d, initPluginForDisplay, dbusInitPluginForDisplay);
+
+    if (status)
+	dbusRegisterScreen (dd->connection, d, p->vTable->name, "allscreens");
+
+    return status;
+}
+
+static void
+dbusFiniPluginForDisplay (CompPlugin  *p,
+			  CompDisplay *d)
+{
+    DBUS_DISPLAY (d);
+
+    dbusUnregisterScreen (dd->connection, d, p->vTable->name, "allscreens");
+
+    UNWRAP (dd, d, finiPluginForDisplay);
+    (*d->finiPluginForDisplay) (p, d);
+    WRAP (dd, d, finiPluginForDisplay, dbusFiniPluginForDisplay);
+}
+
+static Bool
+dbusInitPluginForScreen (CompPlugin *p,
+			 CompScreen *s)
+{
+    DBUS_SCREEN (s);
+    DBUS_DISPLAY (s->display);
+    Bool status;
+    char screen_name[256];
+
+    UNWRAP (ds, s, initPluginForScreen);
+    status = (*s->initPluginForScreen) (p, s);
+    WRAP (ds, s, initPluginForScreen, dbusInitPluginForScreen);
+
+    if (status)
+    {
+	sprintf (screen_name, "screen%d", s->screenNum);
+	dbusRegisterScreen (dd->connection, s->display, p->vTable->name,
+			    screen_name);
+    }
+
+    return status;
+}
+
+static void
+dbusFiniPluginForScreen (CompPlugin *p,
+			 CompScreen *s)
+{
+    DBUS_SCREEN (s);
+    DBUS_DISPLAY (s->display);
+    char screen_name[256];
+
+    sprintf (screen_name, "screen%d", s->screenNum);
+    dbusUnregisterScreen (dd->connection, s->display, p->vTable->name,
+			  screen_name);
+
+    UNWRAP (ds, s, finiPluginForScreen);
+    (*s->finiPluginForScreen) (p, s);
+    WRAP (ds, s, finiPluginForScreen, dbusFiniPluginForScreen);
+}
+
+static Bool
 dbusInitDisplay (CompPlugin  *p,
 		 CompDisplay *d)
 {
@@ -2346,7 +2422,7 @@ dbusInitDisplay (CompPlugin  *p,
 					  &dbus_messages_vtable, d);
 
     dbusRegisterPlugins (dd->connection, d);
- 
+
     status = dbus_connection_get_unix_fd (dd->connection, &fd);
     if (!status)
     {
@@ -2401,6 +2477,8 @@ dbusInitDisplay (CompPlugin  *p,
 
     WRAP (dd, d, setDisplayOption, dbusSetDisplayOption);
     WRAP (dd, d, setDisplayOptionForPlugin, dbusSetDisplayOptionForPlugin);
+    WRAP (dd, d, initPluginForDisplay, dbusInitPluginForDisplay);
+    WRAP (dd, d, finiPluginForDisplay, dbusFiniPluginForDisplay);
 
     d->privates[displayPrivateIndex].ptr = dd;
 
@@ -2431,6 +2509,8 @@ dbusFiniDisplay (CompPlugin  *p,
 
     UNWRAP (dd, d, setDisplayOption);
     UNWRAP (dd, d, setDisplayOptionForPlugin);
+    UNWRAP (dd, d, initPluginForDisplay);
+    UNWRAP (dd, d, finiPluginForDisplay);
 
     free (dd);
 }
@@ -2449,6 +2529,8 @@ dbusInitScreen (CompPlugin *p,
 
     WRAP (ds, s, setScreenOption, dbusSetScreenOption);
     WRAP (ds, s, setScreenOptionForPlugin, dbusSetScreenOptionForPlugin);
+    WRAP (ds, s, initPluginForScreen, dbusInitPluginForScreen);
+    WRAP (ds, s, finiPluginForScreen, dbusFiniPluginForScreen);
 
     s->privates[dd->screenPrivateIndex].ptr = ds;
 
@@ -2463,6 +2545,8 @@ dbusFiniScreen (CompPlugin *p,
 
     UNWRAP (ds, s, setScreenOption);
     UNWRAP (ds, s, setScreenOptionForPlugin);
+    UNWRAP (ds, s, initPluginForScreen);
+    UNWRAP (ds, s, finiPluginForScreen);
 
     free (ds);
 }
-- 
1.4.4.2


More information about the compiz mailing list