On 2/27/07, Travis Watkins <[EMAIL PROTECTED]> wrote:
Alright, I'll redo it as an addition to the current dbus plugin and
send in a patch. It might not be until tomorrow though.


Alright, here is my patch. A couple issues:
 * It doesn't seem to register any options for core,
dbusGetOptionsFromPath is failing for some reason
 * it doesn't include introspection for signals as I wasn't quite
sure where they belong
 * It doesn't register/unregister plugins and their screens/options
when you change active_plugins, it should do so
 * It probably leaks like a sieve :)

Also, it needs libxml2 but I wasn't sure how to include this in the
build system. I was doing my work with the standalone Makefile we use
for ported beryl plugins.

--
Travis Watkins
http://www.realistanew.com
diff --git a/plugins/dbus.c b/plugins/dbus.c
index 6fbb2e2..06e813a 100644
--- a/plugins/dbus.c
+++ b/plugins/dbus.c
@@ -29,10 +29,13 @@
 
 #define DBUS_API_SUBJECT_TO_CHANGE
 #include <dbus/dbus.h>
+#include <libxml/xmlwriter.h>
 
 #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"
@@ -78,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)
 
@@ -150,6 +162,488 @@ 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);
+}
+
+/* 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");
+
+    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;
+    CompPlugin *p;
+    char screen_name[256];
+
+    xmlTextWriterPtr writer;
+    xmlBufferPtr buf;
+
+    buf = xmlBufferCreate ();
+    writer = xmlNewTextWriterMemory (buf, 0);
+
+    dbusIntrospectStartRoot (writer);
+
+    p = findActivePlugin (path[0]);
+
+    if (path[0] && (strcmp (path[0], "core") == 0 || p))
+    {
+	if ((strcmp (path[0], "core") == 0) || p->vTable->getDisplayOptions)
+	    dbusIntrospectAddNode (writer, "allscreens");
+
+	if ((strcmp (path[0], "core") == 0) || p->vTable->getScreenOptions)
+	{
+	    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)
+    {
+	xmlFreeTextWriter (writer);
+	xmlBufferFree (buf);
+	return FALSE;
+    }
+
+    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;
+    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;
+	    }
+
+	    switch (restrictionType)
+	    {
+	    case CompOptionTypeInt:
+		if (is_list)
+		    dbusIntrospectAddMethod (writer,
+					     COMPIZ_DBUS_GET_MEMBER_NAME, 1,
+					     "ai", "out");
+		else
+		    dbusIntrospectAddMethod (writer,
+					     COMPIZ_DBUS_GET_MEMBER_NAME, 1,
+					     "i", "out");
+
+		dbusIntrospectAddMethod (writer,
+					 COMPIZ_DBUS_GET_METADATA_MEMBER_NAME,
+					 6, "s", "out", "s", "out",
+					 "b", "out", "s", "out",
+					 "i", "out", "i", "out");
+		break;
+	    case CompOptionTypeFloat:
+		if (is_list)
+		    dbusIntrospectAddMethod (writer,
+					     COMPIZ_DBUS_GET_MEMBER_NAME, 1,
+					     "ad", "out");
+		else
+		    dbusIntrospectAddMethod (writer,
+					     COMPIZ_DBUS_GET_MEMBER_NAME, 1,
+					     "d", "out");
+
+		dbusIntrospectAddMethod (writer,
+					 COMPIZ_DBUS_GET_METADATA_MEMBER_NAME,
+					 7, "s", "out", "s", "out",
+					 "b", "out", "s", "out",
+					 "d", "out", "d", "out",
+					 "d", "out");
+		break;
+	    case CompOptionTypeString:
+		if (is_list)
+		    dbusIntrospectAddMethod (writer,
+					     COMPIZ_DBUS_GET_MEMBER_NAME, 1,
+					     "as", "out");
+		else
+		    dbusIntrospectAddMethod (writer,
+					     COMPIZ_DBUS_GET_MEMBER_NAME, 1,
+					     "s", "out");
+
+		dbusIntrospectAddMethod (writer,
+					 COMPIZ_DBUS_GET_METADATA_MEMBER_NAME,
+					 5, "s", "out", "s", "out",
+					 "b", "out", "s", "out",
+					 "as", "out");
+		break;
+	    case CompOptionTypeBool:
+		if (is_list)
+		    dbusIntrospectAddMethod (writer,
+					     COMPIZ_DBUS_GET_MEMBER_NAME, 1,
+					     "ab", "out");
+		else
+		    dbusIntrospectAddMethod (writer,
+					     COMPIZ_DBUS_GET_MEMBER_NAME, 1,
+					     "b", "out");
+
+		dbusIntrospectAddMethod (writer,
+					 COMPIZ_DBUS_GET_METADATA_MEMBER_NAME,
+					 4, "s", "out", "s", "out",
+					 "b", "out", "s", "out");
+		break;
+	    case CompOptionTypeColor:
+	    case CompOptionTypeAction:
+		if (is_list)
+		    dbusIntrospectAddMethod (writer,
+					     COMPIZ_DBUS_GET_MEMBER_NAME, 1,
+					     "as", "out");
+		else
+		    dbusIntrospectAddMethod (writer,
+					     COMPIZ_DBUS_GET_MEMBER_NAME, 1,
+					     "s", "out");
+
+		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 }.
@@ -1172,20 +1666,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;
@@ -1196,75 +1676,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]);
@@ -1327,7 +1837,7 @@ dbusSendChangeSignalForDisplayOption (CompDisplay *d,
 
     if (o)
     {
-	sprintf (path, "/org/freedesktop/compiz/%s/allscreens/%s",
+	sprintf (path, "%s/%s/allscreens/%s", COMPIZ_DBUS_ROOT_PATH,
 		 plugin, o->name);
 	dbusSendChangeSignalForOption (d, o->type, &o->value, path);
     }
@@ -1342,12 +1852,168 @@ dbusSendChangeSignalForScreenOption (CompScreen *s,
 
     if (o)
     {
-	sprintf (path, "/org/freedesktop/compiz/%s/screens%d/%s",
+	sprintf (path, "%s/%s/screens%d/%s", COMPIZ_DBUS_ROOT_PATH,
 		 plugin, s->screenNum, o->name);
 	dbusSendChangeSignalForOption (s->display, o->type, &o->value, path);
     }
 }
 
+/* dbus registration */
+static Bool
+dbusRegisterOptions (DBusConnection *connection,
+		     CompDisplay    *d,
+		     char           *screen_path,
+		     char           *plugin_name,
+		     CompScreen     *s)
+{
+    CompPlugin *p;
+    CompOption *option = NULL;
+    int nOptions, size;
+    char *option_path;
+
+    if (strcmp (plugin_name, "core") == 0)
+    {
+	if (s)
+	    option = compGetScreenOptions (s, &nOptions);
+	else
+	    option = compGetDisplayOptions (d, &nOptions);
+    }
+    else
+    {
+	p = findActivePlugin (plugin_name);
+	if (p)
+	{
+	    if (s)
+	    {
+		if (p->vTable->getScreenOptions)
+		    option = (*p->vTable->getScreenOptions) (s, &nOptions);
+	    }
+	    else
+	    {
+		if (p->vTable->getDisplayOptions)
+		    option = (*p->vTable->getDisplayOptions) (d, &nOptions);
+	    }
+	}
+	else
+	{
+	    return FALSE;
+	}
+    }
+
+    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
+dbusRegisterScreens (DBusConnection *connection,
+		     CompDisplay    *d,
+		     char           *plugin_name)
+{
+    CompScreen *s;
+    CompPlugin *p;
+    char *screen_path;
+    int size;
+
+    //we only want to register these if they have options under them
+    p = findActivePlugin (plugin_name);
+
+    if ((strcmp (plugin_name, "core") == 0) || p->vTable->getDisplayOptions)
+    {
+	//root path + plugin name + "allscreens" + separators + \0
+	size = strlen (COMPIZ_DBUS_ROOT_PATH) + strlen (plugin_name) + 13;
+	screen_path = malloc (size);
+	snprintf (screen_path, size, "%s/%s/%s",
+		  COMPIZ_DBUS_ROOT_PATH, plugin_name, "allscreens");
+	dbus_connection_register_object_path (connection, screen_path,
+					      &dbus_messages_vtable, d);
+	dbusRegisterOptions (connection, d, screen_path, plugin_name, NULL);
+	free (screen_path);
+    }
+
+    if ((strcmp (plugin_name, "core") == 0) || p->vTable->getScreenOptions)
+    {
+	for (s = d->screens; s; s = s->next)
+	{
+	    //root path + plugin name + "screen" + screen number + separators + \0
+	    size = strlen (COMPIZ_DBUS_ROOT_PATH) + strlen (plugin_name) + 10;
+	    screen_path = malloc (size);
+	    snprintf (screen_path, size, "%s/%s/screen%d",
+		      COMPIZ_DBUS_ROOT_PATH, plugin_name, s->screenNum);
+	    dbus_connection_register_object_path (connection, screen_path,
+						  &dbus_messages_vtable, d);
+	    dbusRegisterOptions (connection, d, screen_path, plugin_name, s);
+	    free (screen_path);
+	}
+    }
+
+    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);
+
+    //if plugin is loaded we need to register screens for it
+    if (findActivePlugin (plugin_name))
+	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,
@@ -1486,7 +2152,7 @@ dbusSendPluginsChangedSignal (const char *name,
 
     DBUS_DISPLAY (d);
 
-    signal = dbus_message_new_signal ("/org/freedesktop/compiz",
+    signal = dbus_message_new_signal (COMPIZ_DBUS_ROOT_PATH,
 				      COMPIZ_DBUS_SERVICE_NAME,
 				      COMPIZ_DBUS_PLUGINS_CHANGED_SIGNAL_NAME);
 
@@ -1562,19 +2228,12 @@ 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);
+    //register the objects
+    dbus_connection_register_object_path (dd->connection,
+					  COMPIZ_DBUS_ROOT_PATH,
+					  &dbus_messages_vtable, d);
 
-	/* dbus_connection_unref (dd->connection); */
-	free (dd);
-
-	return FALSE;
-    }
+    dbusRegisterPlugins (dd->connection, d);
 
     status = dbus_connection_get_unix_fd (dd->connection, &fd);
     if (!status)
_______________________________________________
compiz mailing list
compiz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/compiz

Reply via email to