[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