On 3/1/07, Travis Watkins <[EMAIL PROTECTED]> wrote:
Remaining problems: * need to figure out what to do with activate/deactivate * core doesn't get any options registered
Updated the patch. It now registers/unregisters plugins on load/unload by wrapping initPluginForDisplay and friends. I also cleaned the code up a bit. 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 Please comment. -- Travis Watkins http://www.realistanew.com
diff --git a/configure.ac b/configure.ac index 4d71729..7010690 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") diff --git a/plugins/dbus.c b/plugins/dbus.c index 782ad24..40ffdf1 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" @@ -71,13 +74,28 @@ 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 *, + 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) @@ -104,7 +122,7 @@ dbusGetOptionsFromPath (CompDisplay *d, int screenNum; if (sscanf (path[1], "screen%d", &screenNum) != 1) - return FALSE; + return NULL; for (s = d->screens; s; s = s->next) if (s->screenNum == screenNum) @@ -150,6 +168,487 @@ 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"); + 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 }. @@ -1212,20 +1711,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; @@ -1236,75 +1721,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]); @@ -1367,7 +1882,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); } @@ -1382,13 +1897,243 @@ 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); } } 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); + + int pos = 0; + while (path[pos]) + free (path[pos++]); + free (path); + + 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); + +// int pos = 0; +// while (path[pos]) +// free (path[pos++]); +// free (path); + + 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) @@ -1526,7 +2271,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); @@ -1537,6 +2282,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) { @@ -1602,19 +2417,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); - - /* dbus_connection_unref (dd->connection); */ - free (dd); + //register the objects + dbus_connection_register_object_path (dd->connection, + COMPIZ_DBUS_ROOT_PATH, + &dbus_messages_vtable, d); - return FALSE; - } + dbusRegisterPlugins (dd->connection, d); status = dbus_connection_get_unix_fd (dd->connection, &fd); if (!status) @@ -1670,6 +2478,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; @@ -1700,6 +2510,8 @@ dbusFiniDisplay (CompPlugin *p, UNWRAP (dd, d, setDisplayOption); UNWRAP (dd, d, setDisplayOptionForPlugin); + UNWRAP (dd, d, initPluginForDisplay); + UNWRAP (dd, d, finiPluginForDisplay); free (dd); } @@ -1718,6 +2530,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; @@ -1732,6 +2546,8 @@ dbusFiniScreen (CompPlugin *p, UNWRAP (ds, s, setScreenOption); UNWRAP (ds, s, setScreenOptionForPlugin); + UNWRAP (ds, s, initPluginForScreen); + UNWRAP (ds, s, finiPluginForScreen); free (ds); }
_______________________________________________ compiz mailing list compiz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/compiz