[compiz] [PATCH] Dbus improvements (was Include option type in gconf schema)

Mike Dransfield mike at blueroot.co.uk
Fri Nov 24 07:52:28 PST 2006


> Great, I've been hoping that someone would implement functionality for
> retrieving all the option meta data through the dbus plugin. Let me know
> when this is ready to go into head and I'll have a look at it.
>
>   

I think the attached patch is much better than the previous
one I have made the methods return complex datatypes and
I have split the function into type specific rest functions.  This
will hopefully make it much easier for strictly typed
languages.

I have also added some changes to send notifications as signals,
this serves as a simple way for the actions to return
information, doing it any other way would mean some nasty
hacks to the core.  The downside is that script writers will
have to deal with asynchronous programming.

I will have a look at adding some functions to get information
on windows and screens and then I will have a look at
introspection.

I have attached the patches in the git format specified,
hopefully they will be acceptable.
-------------- next part --------------
>From 9469fff85e16650e842e3dbb9a871dca6b279e01 Mon Sep 17 00:00:00 2001
From: mike at blueroot.co.uk <mike at localhost.(none)>
Date: Fri, 24 Nov 2006 15:41:16 +0000
Subject: [PATCH] Updates to dbus to use dictionaries in return values for getMetadata messages.  Split the get metadata method into getMetadata, getIntRest,
getFloatRest and getStringRest.  This is to make is work better with language bindings.

Added basic support for forwarding notifications over dbus.

Made all activate and terminate functions return something for now so that language bindings to not hang.
---
 plugins/dbus.c |  807 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 775 insertions(+), 32 deletions(-)

diff --git a/plugins/dbus.c b/plugins/dbus.c
index e754690..fae127d 100644
--- a/plugins/dbus.c
+++ b/plugins/dbus.c
@@ -32,11 +32,19 @@
 
 #include <compiz.h>
 
-#define COMPIZ_DBUS_SERVICE_NAME	   "org.freedesktop.compiz"
-#define COMPIZ_DBUS_ACTIVATE_MEMBER_NAME   "activate"
-#define COMPIZ_DBUS_DEACTIVATE_MEMBER_NAME "deactivate"
-#define COMPIZ_DBUS_SET_MEMBER_NAME        "set"
-#define COMPIZ_DBUS_GET_MEMBER_NAME        "get"
+#define COMPIZ_DBUS_SERVICE_NAME	             "org.freedesktop.compiz"
+#define COMPIZ_DBUS_PATH		             "/org/freedesktop/compiz"
+#define COMPIZ_DBUS_ACTIVATE_MEMBER_NAME             "activate"
+#define COMPIZ_DBUS_DEACTIVATE_MEMBER_NAME           "deactivate"
+#define COMPIZ_DBUS_SET_MEMBER_NAME_DEP              "set"
+#define COMPIZ_DBUS_GET_MEMBER_NAME_DEP              "get"
+#define COMPIZ_DBUS_SET_MEMBER_NAME                  "setValue"
+#define COMPIZ_DBUS_GET_MEMBER_NAME                  "getValue"
+#define COMPIZ_DBUS_GET_OPTIONS_MEMBER_NAME          "getOptions"
+#define COMPIZ_DBUS_GET_OPTION_META_MEMBER_NAME      "getMetadata"
+#define COMPIZ_DBUS_GET_INT_REST_MEMBER_NAME	     "getIntRest"
+#define COMPIZ_DBUS_GET_FLOAT_REST_MEMBER_NAME	     "getFloatRest"
+#define COMPIZ_DBUS_GET_STRING_REST_MEMBER_NAME	     "getStringRest"
 
 typedef enum {
     DbusActionIndexKeyBinding    = 0,
@@ -49,16 +57,279 @@ typedef enum {
 static int displayPrivateIndex;
 
 typedef struct _DbusDisplay {
+    int 	      screenPrivateIndex;
     DBusConnection    *connection;
     CompWatchFdHandle watchFdHandle;
+    HandleCompizEventProc	       handleCompizEvent;
 } DbusDisplay;
 
+typedef struct _DbusScreen {
+    WindowResizeNotifyProc 		windowResizeNotify;
+    WindowMoveNotifyProc 		windowMoveNotify;
+    WindowGrabNotifyProc  		windowGrabNotify;
+    WindowUngrabNotifyProc		windowUngrabNotify;
+    WindowStateChangeNotifyProc	        windowStateChangeNotify;
+} DbusScreen;
+
 #define GET_DBUS_DISPLAY(d)				     \
     ((DbusDisplay *) (d)->privates[displayPrivateIndex].ptr)
 
-#define DBUS_DISPLAY(d)			   \
+#define DBUS_DISPLAY(d)					   \
     DbusDisplay *dd = GET_DBUS_DISPLAY (d)
 
+#define GET_DBUS_SCREEN(s, dd)				     \
+    ((DbusScreen *) (s)->privates[(dd)->screenPrivateIndex].ptr)
+
+#define DBUS_SCREEN(s) DbusScreen *ds = GET_DBUS_SCREEN (s, GET_DBUS_DISPLAY (s->display))
+
+
+struct _Datatype {
+    char *name;
+    int  type;
+} datatypes[] = {
+    { "Action",         CompOptionTypeAction    },
+    { "Bool",           CompOptionTypeBool      },
+    { "Int",            CompOptionTypeInt       },
+    { "Float",          CompOptionTypeFloat     },
+    { "String",         CompOptionTypeString    },
+    { "Color",          CompOptionTypeColor     },
+    { "List",           CompOptionTypeList      },
+};
+#define N_DATATYPES (sizeof (datatypes) / sizeof (struct _Datatype))
+
+char *
+dbusOptionTypeToString (CompOptionType type)
+{
+    char *datatype;
+    int  i;
+
+    for (i = 0; i < N_DATATYPES; i++)
+    {
+        if (type == datatypes[i].type)
+        {
+            datatype = strdup(datatypes[i].name);
+            return datatype;
+        }
+    }
+
+    return datatype;
+}
+
+static void
+dbusSendSignal (CompDisplay    *d,
+		DBusConnection *connection,
+		char           *signalName,
+		CompOption     *option,
+		int            nOption)
+{
+    DBusMessage *message;
+    char        *path = COMPIZ_DBUS_PATH;
+    char	*name = COMPIZ_DBUS_SERVICE_NAME;
+    int 	n;
+
+    message = dbus_message_new_signal (path, name, signalName);
+
+    n = 0;
+
+    while (n < nOption)
+    {
+	switch (option->type)
+	{
+	    case CompOptionTypeInt:
+		dbus_message_append_args (message,
+				          DBUS_TYPE_INT32, &option->value.i,
+				          DBUS_TYPE_INVALID);
+		break;
+	    case CompOptionTypeBool:
+		dbus_message_append_args (message,
+				          DBUS_TYPE_BOOLEAN, &option->value.b,
+				          DBUS_TYPE_INVALID);
+		break;
+	    case CompOptionTypeString:
+		dbus_message_append_args (message,
+				          DBUS_TYPE_STRING, &option->value.s,
+				          DBUS_TYPE_INVALID);
+		break;
+	    default:
+		break;
+	}
+	option++;
+	n++;
+    }
+
+    dbus_connection_send (connection, message, NULL);
+    dbus_connection_flush (connection);
+    dbus_message_unref (message);
+
+    /*fprintf(stderr, "sent signal to path %s, name %s, msgName %s\n", path, name, signalName);
+    dbus_connection_unref (connection);*/
+}
+
+void
+dbusHandleCompizEvent (CompDisplay *display, char *pluginName, char *signalName, CompOption *option, int nOption)
+{
+
+    DBUS_DISPLAY (display);
+
+    dbusSendSignal(display, dd->connection, signalName, option, nOption);
+
+    UNWRAP (dd, display, handleCompizEvent);
+    (*display->handleCompizEvent) (display, pluginName, signalName, option, nOption);
+    WRAP (dd, display, handleCompizEvent, dbusHandleCompizEvent);
+
+}
+
+static void
+dbusWindowMoveNotify (CompWindow * w, int dx, int dy, Bool immediate)
+{
+
+    CompOption opt[4];
+    int nopt = 4;
+    char	*signalName = "windowMoveNotify";
+
+    DBUS_DISPLAY (w->screen->display);
+    DBUS_SCREEN (w->screen);
+
+    opt[0].type    = CompOptionTypeInt;
+    opt[0].name = "window_id";
+    opt[0].value.i = w->id;
+
+    opt[1].type    = CompOptionTypeInt;
+    opt[1].name = "dx";
+    opt[1].value.i = dx;
+
+    opt[2].type    = CompOptionTypeInt;
+    opt[2].name = "dy";
+    opt[2].value.i = dy;
+
+    opt[3].type    = CompOptionTypeBool;
+    opt[3].name = "immediate";
+    opt[3].value.i = immediate;
+
+    dbusSendSignal(w->screen->display, dd->connection, signalName, opt, nopt);
+
+
+    UNWRAP (ds, w->screen, windowMoveNotify);
+    (*w->screen->windowMoveNotify) (w, dx, dy, immediate);
+    WRAP (ds, w->screen, windowMoveNotify, dbusWindowMoveNotify);
+
+    /*if (immediate)
+        fprintf(stderr, "Window move 0x%02x %d, %d, %d\n", w->id, dx, dy, (int) immediate);*/
+}
+
+static void
+dbusWindowGrabNotify (CompWindow * w, int dx, int dy,
+			unsigned int state,
+        		unsigned int mask)
+{
+    CompOption opt[5];
+    int nopt = 5;
+    char	*signalName = "windowGrabNotify";
+
+    DBUS_DISPLAY (w->screen->display);
+    DBUS_SCREEN (w->screen);
+
+    opt[0].type    = CompOptionTypeInt;
+    opt[0].name = "window_id";
+    opt[0].value.i = w->id;
+
+    opt[1].type    = CompOptionTypeInt;
+    opt[1].name = "dx";
+    opt[1].value.i = dx;
+
+    opt[2].type    = CompOptionTypeInt;
+    opt[2].name = "dy";
+    opt[2].value.i = dy;
+
+    opt[3].type    = CompOptionTypeInt;
+    opt[3].name = "state";
+    opt[3].value.i = state;
+
+    opt[4].type    = CompOptionTypeInt;
+    opt[4].name = "mask";
+    opt[4].value.i = mask;
+
+    dbusSendSignal(w->screen->display, dd->connection, signalName, opt, nopt);
+
+    UNWRAP (ds, w->screen, windowGrabNotify);
+    (*w->screen->windowGrabNotify) (w, dx, dy, state, mask);
+    WRAP (ds, w->screen, windowGrabNotify, dbusWindowGrabNotify);
+    //fprintf(stderr, "Window grab 0x%02x %d, %d, %d\n", w->id, dx, dy, state, mask);
+}
+
+static void
+dbusWindowUngrabNotify (CompWindow * w)
+{
+    CompOption opt[1];
+    int nopt = 1;
+    char	*signalName = "windowUngrabNotify";
+
+    DBUS_DISPLAY (w->screen->display);
+    DBUS_SCREEN (w->screen);
+
+    opt[0].type    = CompOptionTypeInt;
+    opt[0].name = "window_id";
+    opt[0].value.i = w->id;
+
+    dbusSendSignal(w->screen->display, dd->connection, signalName, opt, nopt);
+
+    UNWRAP (ds, w->screen, windowUngrabNotify);
+    (*w->screen->windowUngrabNotify) (w);
+    WRAP (ds, w->screen, windowUngrabNotify, dbusWindowUngrabNotify);
+
+    //fprintf(stderr, "Window ungrab 0x%02x\n", w->id);
+}
+
+static void
+dbusWindowResizeNotify (CompWindow * w)
+{
+    CompOption opt[1];
+    int nopt = 1;
+    char	*signalName = "windowResizeNotify";
+
+    if (w->hidden)
+	return;
+
+    DBUS_DISPLAY (w->screen->display);
+    DBUS_SCREEN (w->screen);
+
+    opt[0].type    = CompOptionTypeInt;
+    opt[0].name = "window_id";
+    opt[0].value.i = w->id;
+
+    dbusSendSignal(w->screen->display, dd->connection, signalName, opt, nopt);
+
+    UNWRAP (ds, w->screen, windowResizeNotify);
+    (*w->screen->windowResizeNotify) (w);
+    WRAP (ds, w->screen, windowResizeNotify, dbusWindowResizeNotify);
+
+    //fprintf(stderr, "Window resize 0x%02x\n", w->id);
+}
+
+static void
+dbusWindowStateChangeNotify (CompWindow * w)
+{
+    CompOption opt[1];
+    int nopt = 1;
+    char	*signalName = "windowStateChangeNotify";
+
+    DBUS_DISPLAY (w->screen->display);
+    DBUS_SCREEN (w->screen);
+
+    opt[0].type    = CompOptionTypeInt;
+    opt[0].name = "window_id";
+    opt[0].value.i = w->id;
+
+    dbusSendSignal(w->screen->display, dd->connection, signalName, opt, nopt);
+
+    UNWRAP (ds, w->screen, windowStateChangeNotify);
+    (*w->screen->windowStateChangeNotify) (w);
+    WRAP (ds, w->screen, windowStateChangeNotify, dbusWindowStateChangeNotify);
+
+    //fprintf(stderr, "Window state changed 0x%02x\n", w->id);
+}
+
+
 
 static CompOption *
 dbusGetOptionsFromPath (CompDisplay *d,
@@ -119,6 +390,23 @@ dbusGetOptionsFromPath (CompDisplay *d,
     return NULL;
 }
 
+void
+dbusReturnBool (DBusConnection *connection,
+		DBusMessage *message,
+		Bool value)
+{
+    DBusMessage *reply;
+    Bool    msgBool = TRUE;
+    reply = dbus_message_new_method_return (message);
+    dbus_message_append_args (reply,
+				  DBUS_TYPE_BOOLEAN, &msgBool,
+				  DBUS_TYPE_INVALID);
+    dbus_connection_send (connection, reply, NULL);
+    dbus_connection_flush (connection);
+    dbus_message_unref (reply);
+}
+
+
 /*
  * Activate can be used to trigger any existing action. Arguments
  * should be a pair of { string, bool|int32|double|string }.
@@ -140,15 +428,14 @@ dbusGetOptionsFromPath (CompDisplay *d,
  * /org/freedesktop/compiz/cube/allscreens/unfold	      \
  * org.freedesktop.compiz.activate			      \
  * string:'root'					      \
- * int32:`xwininfo -root | grep id: | awk '{ print $4 }'`     \
- * string:'face' int32:1
+ * int32:`xwininfo -root | grep id: | awk '{ print $4 }'`
  *
  * dbus-send --type=method_call --dest=org.freedesktop.compiz \
  * /org/freedesktop/compiz/cube/allscreens/unfold	      \
  * org.freedesktop.compiz.deactivate			      \
  * string:'root'					      \
- * int32:`xwininfo -root | grep id: | awk '{ print $4 }'`     \
- * string:'face' int32:1
+ * int32:`xwininfo -root | grep id: | awk '{ print $4 }'`
+ *
  */
 static Bool
 dbusHandleActionMessage (DBusConnection *connection,
@@ -702,13 +989,362 @@ dbusHandleGetOptionMessage (DBusConnecti
     return FALSE;
 }
 
+static Bool
+dbusHandleGetOptionsMessage (DBusConnection *connection,
+			     DBusMessage    *message,
+			     CompDisplay	   *d,
+			     char	   **path)
+{
+    CompScreen *s;
+    CompOption *option;
+    int	       nOption;
+
+    option = dbusGetOptionsFromPath (d, path, &s, &nOption);
+    if (!option)
+	return FALSE;
+
+    DBusMessage *reply;
+
+    reply = dbus_message_new_method_return (message);
+
+    while (nOption--)
+    {
+        dbus_message_append_args (reply,
+				  DBUS_TYPE_STRING, &option->name,
+				  DBUS_TYPE_INVALID);
+	option++;
+    }
+    dbus_connection_send (connection, reply, NULL);
+    dbus_connection_flush (connection);
+
+    dbus_message_unref (reply);
+
+    return TRUE;
+
+}
+
+static Bool
+dbusHandleGetOptionMetadataMessage (DBusConnection *connection,
+			            DBusMessage    *message,
+			            CompDisplay	   *d,
+			            char	   **path)
+{
+    CompScreen	*s;
+    CompOption	*option;
+    int		nOption;
+    Bool	handled = FALSE;
+
+    char *datatype;
+    char *listtype;
+
+    DBusMessage *reply;
+    DBusMessageIter iter;
+    DBusMessageIter listiter;
+    DBusMessageIter dictiter;
+
+    char *shortDescStr = "shortDesc";
+    char *longDescStr = "longDesc";
+    char *datatypeStr = "datatype";
+    char *listTypeStr = "listType";
+
+    char sig[5];
+    sig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
+    sig[1] = DBUS_TYPE_STRING;
+    sig[2] = DBUS_TYPE_STRING;
+    sig[3] = DBUS_DICT_ENTRY_END_CHAR;
+    sig[4] = '\0';
+
+    reply = dbus_message_new_method_return (message);
+
+    option = dbusGetOptionsFromPath (d, path, &s, &nOption);
+    if (!option)
+	return FALSE;
+
+    while (nOption--)
+    {
+	if (strcmp (option->name, path[2]) == 0)
+	{
+
+	    datatype = dbusOptionTypeToString (option->type);
+
+	    dbus_message_iter_init_append (reply, &iter);
+	    dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, sig, &listiter);
+
+	    dbus_message_iter_open_container (&listiter, DBUS_TYPE_DICT_ENTRY, NULL, &dictiter);
+	    dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &shortDescStr);
+	    dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &option->shortDesc);
+	    dbus_message_iter_close_container (&listiter, &dictiter);
+
+	    dbus_message_iter_open_container (&listiter, DBUS_TYPE_DICT_ENTRY, NULL, &dictiter);
+	    dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &longDescStr);
+	    dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &option->longDesc);
+	    dbus_message_iter_close_container (&listiter, &dictiter);
+
+	    dbus_message_iter_open_container (&listiter, DBUS_TYPE_DICT_ENTRY, NULL, &dictiter);
+	    dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &datatypeStr);
+	    dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &datatype);
+	    dbus_message_iter_close_container (&listiter, &dictiter);
+
+	    if (option->type == CompOptionTypeList)
+	    {
+	        listtype = dbusOptionTypeToString (option->value.list.type);
+
+		dbus_message_iter_open_container (&listiter, DBUS_TYPE_DICT_ENTRY, NULL, &dictiter);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &listTypeStr);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &listtype);
+		dbus_message_iter_close_container (&listiter, &dictiter);
+	    }
+
+
+	    dbus_message_iter_close_container (&iter, &listiter);
+	    handled = TRUE;
+	}
+	option++;
+    }
+
+    if (!handled)
+	return FALSE;
+
+    dbus_connection_send (connection, reply, NULL);
+    dbus_connection_flush (connection);
+
+    dbus_message_unref (reply);
+
+    return TRUE;
+
+}
+
+static Bool
+dbusHandleGetIntRestMessage (DBusConnection *connection,
+			            DBusMessage    *message,
+			            CompDisplay	   *d,
+			            char	   **path)
+{
+    CompScreen	*s;
+    CompOption	*option;
+    int		nOption;
+
+    int min;
+    int max;
+
+    DBusMessage *reply;
+    DBusMessageIter iter;
+    DBusMessageIter listiter;
+    DBusMessageIter dictiter;
+
+    char *minStr = "min";
+    char *maxStr = "max";
+
+    char sig[5];
+    sig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
+    sig[1] = DBUS_TYPE_STRING;
+    sig[2] = DBUS_TYPE_INT32;
+    sig[3] = DBUS_DICT_ENTRY_END_CHAR;
+    sig[4] = '\0';
+
+    reply = dbus_message_new_method_return (message);
+
+    option = dbusGetOptionsFromPath (d, path, &s, &nOption);
+    if (!option)
+	return FALSE;
+
+
+    while (nOption--)
+    {
+
+	if (strcmp (option->name, path[2]) == 0)
+	{
+	    dbus_message_iter_init_append (reply, &iter);
+	    dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, sig, &listiter);
+
+	    if (option->type == CompOptionTypeInt ||
+		( (option->type == CompOptionTypeList) &&
+                  (option->value.list.type == CompOptionTypeInt) ) )
+	    {
+		min = option->rest.i.min;
+		max = option->rest.i.max;
+
+		dbus_message_iter_open_container (&listiter, DBUS_TYPE_DICT_ENTRY, NULL, &dictiter);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &minStr);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_INT32, &min);
+		dbus_message_iter_close_container (&listiter, &dictiter);
+
+		dbus_message_iter_open_container (&listiter, DBUS_TYPE_DICT_ENTRY, NULL, &dictiter);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &maxStr);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_INT32, &max);
+		dbus_message_iter_close_container (&listiter, &dictiter);
+	    }
+
+	    dbus_message_iter_close_container (&iter, &listiter);
+	}
+	option++;
+    }
+
+    dbus_connection_send (connection, reply, NULL);
+    dbus_connection_flush (connection);
+
+    dbus_message_unref (reply);
+
+    return TRUE;
+}
+
+static Bool
+dbusHandleGetFloatRestMessage (DBusConnection *connection,
+			            DBusMessage    *message,
+			            CompDisplay	   *d,
+			            char	   **path)
+{
+    CompScreen	*s;
+    CompOption	*option;
+    int		nOption;
+
+    double min;
+    double max;
+    double precision;
+
+    DBusMessage *reply;
+    DBusMessageIter iter;
+    DBusMessageIter listiter;
+    DBusMessageIter dictiter;
+
+    char *minStr = "min";
+    char *maxStr = "max";
+    char *precisionStr = "precision";
+
+    char sig[5];
+    sig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
+    sig[1] = DBUS_TYPE_STRING;
+    sig[2] = DBUS_TYPE_DOUBLE;
+    sig[3] = DBUS_DICT_ENTRY_END_CHAR;
+    sig[4] = '\0';
+
+    reply = dbus_message_new_method_return (message);
+
+    option = dbusGetOptionsFromPath (d, path, &s, &nOption);
+    if (!option)
+	return FALSE;
+
+
+    while (nOption--)
+    {
+
+	if (strcmp (option->name, path[2]) == 0)
+	{
+	    dbus_message_iter_init_append (reply, &iter);
+	    dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, sig, &listiter);
+
+	    if (option->type == CompOptionTypeFloat ||
+		     ( (option->type == CompOptionTypeList) &&
+                       (option->value.list.type == CompOptionTypeFloat) ) )
+	    {
+		min = option->rest.f.min;
+		max = option->rest.f.max;
+		precision = option->rest.f.precision;
+
+		dbus_message_iter_open_container (&listiter, DBUS_TYPE_DICT_ENTRY, NULL, &dictiter);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &minStr);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_DOUBLE, &min);
+		dbus_message_iter_close_container (&listiter, &dictiter);
+
+		dbus_message_iter_open_container (&listiter, DBUS_TYPE_DICT_ENTRY, NULL, &dictiter);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &maxStr);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_DOUBLE, &max);
+		dbus_message_iter_close_container (&listiter, &dictiter);
+
+		dbus_message_iter_open_container (&listiter, DBUS_TYPE_DICT_ENTRY, NULL, &dictiter);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_STRING, &precisionStr);
+		dbus_message_iter_append_basic (&dictiter, DBUS_TYPE_DOUBLE, &precision);
+		dbus_message_iter_close_container (&listiter, &dictiter);
+
+	    }
+
+	    dbus_message_iter_close_container (&iter, &listiter);
+	}
+	option++;
+    }
+
+    dbus_connection_send (connection, reply, NULL);
+    dbus_connection_flush (connection);
+
+    dbus_message_unref (reply);
+
+    return TRUE;
+}
+
+static Bool
+dbusHandleGetStringRestMessage (DBusConnection *connection,
+			            DBusMessage    *message,
+			            CompDisplay	   *d,
+			            char	   **path)
+{
+    CompScreen	*s;
+    CompOption	*option;
+    int		nOption;
+
+    DBusMessage *reply;
+    DBusMessageIter iter;
+    DBusMessageIter listiter;
+
+    char sig[2];
+    sig[0] = DBUS_TYPE_STRING;
+    sig[1] = '\0';
+
+    reply = dbus_message_new_method_return (message);
+
+    option = dbusGetOptionsFromPath (d, path, &s, &nOption);
+    if (!option)
+	return FALSE;
+
+
+    while (nOption--)
+    {
+
+	if (strcmp (option->name, path[2]) == 0)
+	{
+	    dbus_message_iter_init_append (reply, &iter);
+	    dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, sig, &listiter);
+
+	    if (option->type == CompOptionTypeString ||
+		     ( (option->type == CompOptionTypeList) &&
+                       (option->value.list.type == CompOptionTypeString) ) )
+	    {
+		char *sPossible;
+		int i;
+
+    		if (option->rest.s.nString)
+    		{
+		    for ( i=0; i < option->rest.s.nString; i++ )
+		    {
+			sPossible = option->rest.s.string[i];
+			dbus_message_iter_append_basic (&listiter, DBUS_TYPE_STRING, &sPossible);
+		    }
+
+
+		}
+	    }
+
+	    dbus_message_iter_close_container (&iter, &listiter);
+
+	}
+	option++;
+    }
+
+    dbus_connection_send (connection, reply, NULL);
+    dbus_connection_flush (connection);
+
+    dbus_message_unref (reply);
+
+    return TRUE;
+}
+
 static DBusHandlerResult
 dbusHandleMessage (DBusConnection *connection,
 		   DBusMessage    *message,
 		   void           *userData)
 {
     CompDisplay *d = (CompDisplay *) userData;
-    Bool	status = FALSE;
+    Bool	status  = FALSE;
+    Bool	handled = FALSE;
     char	**path;
     const char  *service, *interface, *member;
 
@@ -728,7 +1364,7 @@ dbusHandleMessage (DBusConnection *conne
     if (!dbus_message_get_path_decomposed (message, &path))
 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-    if (!path[0] || !path[1] || !path[2] || !path[3] || !path[4] || !path[5])
+    if (!path[0] || !path[1] || !path[2] || !path[3] || !path[4])
 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
     if (strcmp (path[0], "org")	       ||
@@ -736,32 +1372,91 @@ dbusHandleMessage (DBusConnection *conne
 	strcmp (path[2], "compiz"))
 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-    if (dbus_message_has_member (message, COMPIZ_DBUS_ACTIVATE_MEMBER_NAME))
+    if (path[5])  /* option level */
     {
-	status = dbusHandleActionMessage (connection, message, d, &path[3],
-					  TRUE);
+	/* actions */
+        if (dbus_message_has_member (message, COMPIZ_DBUS_ACTIVATE_MEMBER_NAME))
+        {
+	    status = dbusHandleActionMessage (connection, message, d, &path[3],
+					      TRUE);
+	    handled = TRUE;
+        }
+        else if (dbus_message_has_member (message,
+				          COMPIZ_DBUS_DEACTIVATE_MEMBER_NAME))
+        {
+	    status = dbusHandleActionMessage (connection, message, d, &path[3],
+					      FALSE);
+	    handled = TRUE;
+        }
+	/* get/set option values */
+        else if (dbus_message_has_member (message,
+					  COMPIZ_DBUS_SET_MEMBER_NAME) ||
+		dbus_message_has_member (message,
+					 COMPIZ_DBUS_SET_MEMBER_NAME_DEP))
+        {
+	    status = dbusHandleSetOptionMessage (connection, message, d,
+						 &path[3]);
+	    handled = TRUE;
+        }
+        else if (dbus_message_has_member (message,
+					  COMPIZ_DBUS_GET_MEMBER_NAME) ||
+		dbus_message_has_member (message,
+					 COMPIZ_DBUS_GET_MEMBER_NAME_DEP))
+        {
+	    status = dbusHandleGetOptionMessage (connection, message, d,
+						 &path[3]);
+	    handled = TRUE;
+        }
+        else if (dbus_message_has_member (message,
+                                          COMPIZ_DBUS_GET_OPTION_META_MEMBER_NAME))
+        {
+	    status = dbusHandleGetOptionMetadataMessage (connection, message, d,
+						         &path[3]);
+	    handled = TRUE;
+        }
+        else if (dbus_message_has_member (message,
+                                          COMPIZ_DBUS_GET_INT_REST_MEMBER_NAME))
+        {
+	    status = dbusHandleGetIntRestMessage (connection, message, d,
+						  &path[3]);
+	    handled = TRUE;
+        }
+        else if (dbus_message_has_member (message,
+                                          COMPIZ_DBUS_GET_FLOAT_REST_MEMBER_NAME))
+        {
+	    status = dbusHandleGetFloatRestMessage (connection, message, d,
+						  &path[3]);
+	    handled = TRUE;
+        }
+        else if (dbus_message_has_member (message,
+                                          COMPIZ_DBUS_GET_STRING_REST_MEMBER_NAME))
+        {
+	    status = dbusHandleGetStringRestMessage (connection, message, d,
+						  &path[3]);
+	    handled = TRUE;
+        }
     }
-    else if (dbus_message_has_member (message,
-				      COMPIZ_DBUS_DEACTIVATE_MEMBER_NAME))
+    else if (path[4])  /* plugin screen/display level */
     {
-	status = dbusHandleActionMessage (connection, message, d, &path[3],
-					  FALSE);
-    }
-    else if (dbus_message_has_member (message, COMPIZ_DBUS_SET_MEMBER_NAME))
-    {
-	status = dbusHandleSetOptionMessage (connection, message, d, &path[3]);
-    }
-    else if (dbus_message_has_member (message, COMPIZ_DBUS_GET_MEMBER_NAME))
-    {
-	status = dbusHandleGetOptionMessage (connection, message, d, &path[3]);
+
+        if (dbus_message_has_member (message,
+				          COMPIZ_DBUS_GET_OPTIONS_MEMBER_NAME))
+        {
+	    status = dbusHandleGetOptionsMessage (connection, message, d,
+						  &path[3]);
+	    handled = TRUE;
+        }
     }
 
     dbus_free_string_array (path);
 
-    if (status)
-	return DBUS_HANDLER_RESULT_HANDLED;
+    if (handled)
+	dbusReturnBool (connection, message, status);
+    else
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    return DBUS_HANDLER_RESULT_HANDLED;
 
-    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
 static Bool
@@ -795,6 +1490,13 @@ dbusInitDisplay (CompPlugin  *p,
     if (!dd)
 	return FALSE;
 
+    dd->screenPrivateIndex = allocateScreenPrivateIndex (d);
+    if (dd->screenPrivateIndex < 0) {
+	free (dd);
+	return FALSE;
+    }
+
+
     dbus_error_init (&error);
 
     dd->connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
@@ -868,6 +1570,8 @@ dbusInitDisplay (CompPlugin  *p,
 
     d->privates[displayPrivateIndex].ptr = dd;
 
+    WRAP (dd, d, handleCompizEvent, dbusHandleCompizEvent);
+
     return TRUE;
 }
 
@@ -887,11 +1591,50 @@ dbusFiniDisplay (CompPlugin  *p,
 
       dbus_connection_unref (dd->connection);
     */
+    UNWRAP (dd, d, handleCompizEvent);
 
     free (dd);
 }
 
 static Bool
+dbusInitScreen (CompPlugin *p, CompScreen *s)
+{
+    DbusScreen *ds;
+
+    DBUS_DISPLAY (s->display);
+
+    ds = malloc (sizeof (DbusScreen));
+    if (!ds)
+	return FALSE;
+
+    WRAP (ds, s, windowMoveNotify, dbusWindowMoveNotify);
+    WRAP (ds, s, windowGrabNotify, dbusWindowGrabNotify);
+    WRAP (ds, s, windowUngrabNotify, dbusWindowUngrabNotify);
+    WRAP (ds, s, windowResizeNotify, dbusWindowResizeNotify);
+    WRAP (ds, s, windowStateChangeNotify, dbusWindowStateChangeNotify);
+
+    s->privates[dd->screenPrivateIndex].ptr = ds;
+
+    return TRUE;
+}
+
+static void
+dbusFiniScreen (CompPlugin *p, CompScreen *s)
+{
+    DBUS_SCREEN (s);
+
+    UNWRAP (ds, s, windowMoveNotify);
+    UNWRAP (ds, s, windowGrabNotify);
+    UNWRAP (ds, s, windowUngrabNotify);
+    UNWRAP (ds, s, windowResizeNotify);
+    UNWRAP (ds, s, windowStateChangeNotify);
+
+    free(ds);
+
+}
+
+
+static Bool
 dbusInit (CompPlugin *p)
 {
     displayPrivateIndex = allocateDisplayPrivateIndex ();
@@ -924,8 +1667,8 @@ CompPluginVTable dbusVTable = {
     dbusFini,
     dbusInitDisplay,
     dbusFiniDisplay,
-    0, /* InitScreen */
-    0, /* FiniScreen */
+    dbusInitScreen,
+    dbusFiniScreen,
     0, /* InitWindow */
     0, /* FiniWindow */
     0, /* GetDisplayOptions */
-- 
1.4.4



More information about the compiz mailing list