$(top_builddir)/spi-common/libspicommon.la
at_spi_registryd_SOURCES = \
- desktop.c \
- desktop.h \
- deviceeventcontroller.c \
- deviceeventcontroller.h \
registry-main.c \
registry.c \
registry.h \
- reentrant-list.c \
- reentrant-list.h \
ucs2keysym.c
+
+# deviceeventcontroller.c
+# deviceeventcontroller.h
+++ /dev/null
-/*
- * AT-SPI - Assistive Technology Service Provider Interface
- * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
- *
- * Copyright 2001, 2002 Sun Microsystems Inc.,
- * Copyright 2001, 2002 Ximian, Inc., Ximian Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* desktop.c: implements SpiDesktop.idl */
-
-#include <config.h>
-#include <stdio.h>
-#include <string.h>
-#include <atk/atkcomponent.h>
-#include <gdk/gdkscreen.h>
-#include <gdk/gdkx.h>
-
-#include <spi-common/spi-dbus.h>
-
-#include "desktop.h"
-#include "registry.h"
-
-G_DEFINE_TYPE(SpiDesktop, spi_desktop, G_TYPE_OBJECT)
-
-/* SpiDesktop signals */
-enum {
- APPLICATION_ADDED,
- APPLICATION_REMOVED,
-LAST_SIGNAL
-};
-static guint spi_desktop_signals[LAST_SIGNAL];
-
-
-/* Our parent Gtk object type */
-#define PARENT_TYPE SPI_ACCESSIBLE_TYPE
-
-static gboolean exiting = FALSE;
-
-/* A pointer to our parent object class */
-static GObjectClass *parent_class;
-
-#define SPI_TYPE_ATK_DESKTOP (spi_atk_desktop_get_type ())
-#define SPI_ATK_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_TYPE_ATK_DESKTOP, SpiAtkDesktop))
-#define SPI_IS_ATK_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_TYPE_ATK_DESKTOP))
-
-typedef struct {
- AtkObject parent;
-
- GdkScreen *screen;
-} SpiAtkDesktop;
-
-typedef struct {
- AtkObjectClass parent;
-} SpiAtkDesktopClass;
-
-static void spi_atk_desktop_init (SpiAtkDesktop *desktop);
-static void atk_component_interface_init (AtkComponentIface *iface);
-static void spi_atk_desktop_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type);
-
-static GType
-spi_atk_desktop_get_type (void)
-{
- static GType type = 0;
-
- if (!type)
- {
- static const GTypeInfo typeInfo =
- {
- sizeof (SpiAtkDesktopClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) NULL,
- (GClassFinalizeFunc) NULL,
- NULL,
- sizeof (SpiAtkDesktop),
- 0,
- (GInstanceInitFunc) spi_atk_desktop_init,
- } ;
- static const GInterfaceInfo atk_component_info =
- {
- (GInterfaceInitFunc) atk_component_interface_init,
- (GInterfaceFinalizeFunc) NULL,
- NULL
- };
-
- type = g_type_register_static (ATK_TYPE_OBJECT,
- "SpiAtkDesktop", &typeInfo, 0);
- g_type_add_interface_static (type, ATK_TYPE_COMPONENT,
- &atk_component_info);
- }
- return type;
-}
-
-static void
-spi_atk_desktop_init (SpiAtkDesktop *desktop)
-{
- GdkDisplay *display;
-
- atk_object_set_name (ATK_OBJECT (desktop), "main");
- display = gdk_x11_lookup_xdisplay (GDK_DISPLAY ());
- desktop->screen = gdk_display_get_default_screen (display);
-}
-
-static void
-atk_component_interface_init (AtkComponentIface *iface)
-{
- g_return_if_fail (iface != NULL);
-
- iface->get_extents = spi_atk_desktop_get_extents;
-}
-
-static void
-spi_atk_desktop_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type)
-{
- SpiAtkDesktop *desktop;
-
- g_return_if_fail (SPI_IS_ATK_DESKTOP (component));
- desktop = SPI_ATK_DESKTOP (component);
- *x = 0;
- *y = 0;
- *width = gdk_screen_get_width (desktop->screen);
- *height = gdk_screen_get_height (desktop->screen);
-}
-
-static void
-spi_desktop_init (SpiDesktop *desktop)
-{
- desktop->applications = NULL;
-}
-
-static void
-spi_desktop_dispose (GObject *object)
-{
- SpiDesktop *desktop = (SpiDesktop *) object;
-
- while (desktop->applications)
- {
- SpiDesktopApplication *app = desktop->applications->data;
- g_assert (app != NULL);
- spi_desktop_remove_application (desktop, app->bus_name);
- }
-
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static dbus_bool_t
-impl_desktop_get_child_count (const char *path, DBusMessageIter * iter,
- void *user_data)
-{
- SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop;
-
- if (desktop->applications)
- {
- return droute_return_v_int32(iter, g_list_length (desktop->applications));
- }
- else
- {
- return droute_return_v_int32(iter, 0);
- }
-}
-
-static DBusMessage *
-impl_desktop_get_child_at_index (DBusConnection *bus, DBusMessage *message, void *user_data)
-{
- SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop;
- DBusError error;
- dbus_int32_t index;
- SpiDesktopApplication *app;
- const char *bus_name;
- DBusMessage *reply;
-
- dbus_error_init (&error);
- if (!dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
- {
- return spi_dbus_general_error (message);
- }
- app = g_list_nth_data (desktop->applications, index);
- bus_name = (app? app->bus_name: "");
-
- reply = dbus_message_new_method_return (message);
- if (reply)
- {
- dbus_message_append_args (reply, DBUS_TYPE_STRING, &bus_name, DBUS_TYPE_INVALID);
- }
-
- return reply;
-}
-
-static DBusMessage *
-impl_desktop_get_children (DBusConnection *bus, DBusMessage *message, void *user_data)
-{
- SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop;
- DBusError error;
- gint count;
- gint i;
- SpiDesktopApplication *app;
- DBusMessage *reply;
- DBusMessageIter iter, iter_array;
-
- reply = dbus_message_new_method_return (message);
- if (!reply) return NULL;
- dbus_message_iter_init_append (reply, &iter);
- if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s", &iter_array))
- {
- goto oom;
- }
- count = g_list_length (desktop->applications);
- for (i = 0; i < count; i++)
- {
- app = g_list_nth_data (desktop->applications, i);
- if (!app)
- {
- g_warning ("Null app\n");
- continue;
- }
- dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &app->bus_name);
- }
- if (!dbus_message_iter_close_container (&iter, &iter_array))
- {
- goto oom;
- }
- return reply;
-oom:
- // TODO: Handle out of memory
- return reply;
-}
-
-static dbus_bool_t
-impl_get_name (const char *path, DBusMessageIter * iter, void *user_data)
-{
- if (strcmp (path, SPI_DBUS_PATH_DESKTOP) != 0)
- return FALSE;
- // TODO: call atk_object_get_name
- return droute_return_v_string (iter, "main");
-}
-
-static void
-spi_desktop_exiting (void)
-{
- exiting = TRUE;
-}
-
-static void
-spi_desktop_class_init (SpiDesktopClass *klass)
-{
- GObjectClass * object_class = (GObjectClass *) klass;
-
- object_class->dispose = spi_desktop_dispose;
-
- parent_class = g_type_class_ref (G_TYPE_OBJECT);
-
- spi_desktop_signals[APPLICATION_ADDED] =
- g_signal_new ("application_added",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (SpiDesktopClass, application_added),
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE,
- 1, G_TYPE_UINT);
- spi_desktop_signals[APPLICATION_REMOVED] =
- g_signal_new ("application_removed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (SpiDesktopClass, application_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE,
- 1, G_TYPE_UINT);
- g_atexit (spi_desktop_exiting);
-}
-
-SpiDesktop *
-spi_desktop_new (void)
-{
- return g_object_new (SPI_DESKTOP_TYPE, NULL);
-}
-
-static void
-abnormal_application_termination (gpointer object, SpiDesktopApplication *app)
-{
- g_return_if_fail (SPI_IS_DESKTOP (app->desktop));
-
- if (!exiting)
- spi_desktop_remove_application (app->desktop, app->bus_name);
-}
-
-void
-spi_desktop_add_application (SpiDesktop *desktop,
- const char *application)
-{
- SpiDesktopApplication *app;
-
- g_return_if_fail (SPI_IS_DESKTOP (desktop));
-
- app = g_new (SpiDesktopApplication, 1);
- app->desktop = desktop;
- app->bus_name = g_strdup (application);
-
- desktop->applications = g_list_append (desktop->applications, app);
-
- // TODO: Listen for termination, and call abnormal_application_termination
-
- g_signal_emit (G_OBJECT (desktop),
- spi_desktop_signals[APPLICATION_ADDED], 0,
- g_list_index (desktop->applications, app));
-}
-
-void
-spi_desktop_remove_application (SpiDesktop *desktop,
- const char *bus_name)
-{
- guint idx;
- GList *l;
- SpiDesktopApplication *app;
-
- g_return_if_fail ( bus_name != NULL);
- g_return_if_fail (SPI_IS_DESKTOP (desktop));
-
- idx = 0;
- for (l = desktop->applications; l; l = l->next)
- {
- app = (SpiDesktopApplication *) l->data;
-
- if (!strcmp(app->bus_name, bus_name))
- {
- break;
- }
- idx++;
- }
-
- if (!l) return;
-
- g_signal_emit (G_OBJECT (desktop), spi_desktop_signals[APPLICATION_REMOVED], 0, idx);
-
- desktop->applications = g_list_delete_link (desktop->applications, l);
-
- g_free (app->bus_name);
- g_free (app);
-}
-
-static DRouteMethod methods_desktop[] =
-{
- { impl_desktop_get_child_at_index, "getChildAtIndex" },
- { impl_desktop_get_children, "getChildren" },
- { NULL, NULL }
-};
-
-static DRouteProperty properties_desktop[] =
-{
- { impl_desktop_get_child_count, NULL, "getChildCount" },
- { NULL, NULL, NULL }
-};
-
-static DRouteProperty properties_accessible[] =
-{
- { impl_get_name, "getName" },
- { NULL, NULL }
-};
-
-void
-spi_registry_initialize_desktop_interface (DRouteData * data)
-{
- droute_add_interface (data, SPI_DBUS_INTERFACE_DESKTOP, methods_desktop,
- properties_desktop, NULL, NULL);
- droute_add_interface (data, SPI_DBUS_INTERFACE_ACCESSIBLE, NULL,
- properties_accessible, NULL, NULL);
-};
+++ /dev/null
-/*
- * AT-SPI - Assistive Technology Service Provider Interface
- * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
- *
- * Copyright 2001, 2002 Sun Microsystems Inc.,
- * Copyright 2001, 2002 Ximian, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef SPI_DESKTOP_H_
-#define SPI_DESKTOP_H_
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define SPI_DESKTOP_TYPE (spi_desktop_get_type ())
-#define SPI_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_DESKTOP_TYPE, SpiDesktop))
-#define SPI_DESKTOP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SPI_DESKTOP_TYPE, SpiDesktopClass))
-#define SPI_IS_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_DESKTOP_TYPE))
-#define SPI_IS_DESKTOP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DESKTOP_TYPE))
-
-typedef struct {
- GObject parent;
- GList *applications;
-} SpiDesktop;
-
-typedef struct {
- GObjectClass parent_class;
- /*Signals */
- void (*application_added) (SpiDesktop *desktop,
- guint index);
- void (*application_removed) (SpiDesktop *desktop,
- guint index);
-} SpiDesktopClass;
-
-GType spi_desktop_get_type (void);
-SpiDesktop *spi_desktop_new (void);
-void spi_desktop_add_application (SpiDesktop *desktop,
- const char *bus_name);
-void spi_desktop_remove_application (SpiDesktop *desktop,
- const char *bus_name);
-
-typedef struct {
- SpiDesktop *desktop;
- const char *bus_name;
-} SpiDesktopApplication;
-
-G_END_DECLS
-
-#endif /* SPI_DESKTOP_H_ */
{ NULL, NULL }
};
-void
+static void
spi_registry_initialize_dec_interface (DRouteData * data)
{
droute_add_interface (data, SPI_DBUS_INTERFACE_DEC, methods,
NULL, NULL, NULL);
};
+
+SpiDEController *
+spi_registry_dec_new (DRouteData *droute)
+{
+ SpiDEController *dec = g_object_new (SPI_DEVICE_EVENT_CONTROLLER_TYPE, 1);
+ spi_registry_initialize_dec_interface (&droute);
+ return dec;
+}
void spi_remove_device_listeners (SpiDEController *controller, const char *bus_name);
+void spi_registry_initialize_dec_interface (DRouteData * data);
+
G_END_DECLS
#endif /* DEVICEEVENTCONTROLLER_H_ */
+++ /dev/null
-/*
- * AT-SPI - Assistive Technology Service Provider Interface
- * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
- *
- * Copyright 2001, 2002 Sun Microsystems Inc.,
- * Copyright 2001, 2002 Ximian, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-#include <glib.h>
-
-#include "reentrant-list.h"
-
-typedef struct {
- GList **list;
- GList *iterator;
-} Iteration;
-
-static GSList *working_list = NULL; /* of Iteration */
-
-/*
- * deletes an element from the list - in a re-entrant
- * safe fashion; advances the element pointer to the next
- * element.
- */
-void
-spi_re_entrant_list_delete_link (GList * const *element_ptr)
-{
- GSList *l;
- GList *next;
- GList *element;
- gboolean first_item;
-
- g_return_if_fail (element_ptr != NULL);
-
- element = *element_ptr;
- g_return_if_fail (element != NULL);
-
- next = element->next;
- first_item = (element->prev == NULL);
-
- g_list_remove_link (NULL, element);
-
- for (l = working_list; l; l = l->next)
- {
- Iteration *i = l->data;
-
- if (i->iterator == element)
- {
- i->iterator = next;
- }
-
- if (first_item && *(i->list) == element)
- {
- *(i->list) = next;
- }
- }
-
- g_list_free_1 (element);
-}
-
-void
-spi_re_entrant_list_foreach (GList **list,
- SpiReEntrantFn func,
- gpointer user_data)
-{
- Iteration i;
-
- if (!list || !*list)
- {
- return;
- }
-
- i.list = list;
- i.iterator = *list;
-
- working_list = g_slist_prepend (working_list, &i);
-
- while (i.iterator) {
- GList *l = i.iterator;
-
- func (&i.iterator, user_data);
-
- if (i.iterator == l)
- i.iterator = i.iterator->next;
- }
-
- working_list = g_slist_remove (working_list, &i);
-}
+++ /dev/null
-/*
- * AT-SPI - Assistive Technology Service Provider Interface
- * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
- *
- * Copyright 2001, 2002 Sun Microsystems Inc.,
- * Copyright 2001, 2002 Ximian, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef REENTRANT_LIST_H_
-#define REENTRANT_LIST_H_
-
-#include <glib/glist.h>
-
-G_BEGIN_DECLS
-
-typedef enum {
- SPI_RE_ENTRANT_CONTINUE = 0,
- SPI_RE_ENTRANT_TERMINATE
-} SpiReEntrantContinue;
-
-typedef SpiReEntrantContinue (*SpiReEntrantFn) (GList * const *list,
- gpointer user_data);
-
-void spi_re_entrant_list_delete_link (GList * const *element_ptr);
-void spi_re_entrant_list_foreach (GList **list,
- SpiReEntrantFn func,
- gpointer user_data);
-
-G_END_DECLS
-
-#endif /* REENTRANT_LIST_H_ */
static gchar *dbus_name = NULL;
-static GOptionEntry optentries[] =
+static GOptionEntry optentries[] =
{
{"dbus-name", 0, 0, G_OPTION_ARG_STRING, &dbus_name, "Well-known name to register with D-Bus", NULL},
{NULL}
main (int argc, char **argv)
{
SpiRegistry *registry;
+ /*SpiDEController *dec;*/
+
GMainLoop *mainloop;
+ DBusConnection *bus;
+
GOptionContext *opt;
GError *err = NULL;
if (dbus_name == NULL)
dbus_name = SPI_DBUS_NAME_REGISTRY;
- registry = spi_registry_new ();
+ dbus_error_init (&error);
+ bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
+ if (!bus)
+ {
+ g_warning("Couldn't connect to dbus: %s\n", error.message);
+ }
mainloop = g_main_loop_new (NULL, FALSE);
+ dbus_connection_setup_with_g_main(bus, g_main_context_default());
- dbus_error_init (&error);
- ret = dbus_bus_request_name(registry->droute.bus, dbus_name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
-
+ ret = dbus_bus_request_name(bus, dbus_name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
if (ret == DBUS_REQUEST_NAME_REPLY_EXISTS)
{
g_error("Could not obtain D-Bus name - %s\n", dbus_name);
else
{
g_print ("SpiRegistry daemon is running with well-known name - %s\n", dbus_name);
- g_main_loop_run (mainloop);
}
+ /*dec = spi_registry_dec_new (bus);*/
+ registry = spi_registry_new (bus);
+
+ g_main_loop_run (mainloop);
return 0;
}
* AT-SPI - Assistive Technology Service Provider Interface
* (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
*
+ * Copyright 2008, Codethink Ltd.
* Copyright 2001, 2002 Sun Microsystems Inc.,
* Copyright 2001, 2002 Ximian, Inc.
*
* Boston, MA 02111-1307, USA.
*/
-/* registry.c: the main accessibility service registry implementation */
-
-#undef SPI_LISTENER_DEBUG
-#undef SPI_DEBUG
-#undef SPI_QUEUE_DEBUG
-
#include <config.h>
-#ifdef SPI_DEBUG
-# include <stdio.h>
-#endif
-
#include <spi-common/spi-dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
#include "registry.h"
-#include "dbus/dbus-glib-lowlevel.h"
-
-/* Our parent GObject type */
-#define PARENT_TYPE G_OBJECT_TYPE
-
-int _dbg = 0;
-
-typedef enum {
- ETYPE_FOCUS,
- ETYPE_OBJECT,
- ETYPE_PROPERTY,
- ETYPE_WINDOW,
- ETYPE_TOOLKIT,
- ETYPE_KEYBOARD,
- ETYPE_MOUSE,
- ETYPE_LAST_DEFINED
-} EventTypeCategory;
-
-typedef struct {
- const char *event_name;
- EventTypeCategory type_cat;
- GQuark major; /* from string segment[1] */
- GQuark minor; /* from string segment[1]+segment[2] */
- GQuark detail; /* from string segment[3] (not concatenated) */
-} EventTypeStruct;
+
+/*---------------------------------------------------------------------------*/
G_DEFINE_TYPE(SpiRegistry, spi_registry, G_TYPE_OBJECT)
static void
-spi_registry_set_debug (const char *debug_flag_string)
-{
- if (debug_flag_string)
- _dbg = (int) g_ascii_strtod (debug_flag_string, NULL);
-}
-
-static void emit(SpiRegistry *registry, const char *name, int first_type, ...)
+spi_registry_class_init (SpiRegistryClass *klass)
{
- va_list arg;
+ GObjectClass * object_class = (GObjectClass *) klass;
- va_start(arg, first_type);
- spi_dbus_emit_valist(registry->droute.bus, SPI_DBUS_PATH_DESKTOP, SPI_DBUS_INTERFACE_REGISTRY, name, first_type, arg);
- va_end(arg);
+ spi_registry_parent_class = g_type_class_ref (G_TYPE_OBJECT);
}
static void
-desktop_add_application (SpiDesktop *desktop,
- guint index, gpointer data)
+spi_registry_init (SpiRegistry *registry)
{
- SpiRegistry *registry = SPI_REGISTRY (data);
- const SpiDesktopApplication *app = g_list_nth_data(desktop->applications, index);
-
- emit(registry, "applicationAdd", DBUS_TYPE_UINT32, &index, DBUS_TYPE_STRING, &app->bus_name, DBUS_TYPE_INVALID);
+ registry->apps = g_sequence_new (g_free);
}
+/*---------------------------------------------------------------------------*/
-
-static void
-desktop_remove_application (SpiDesktop *desktop,
- guint index, gpointer data)
+static void emit(SpiRegistry *reg, const char *itf, const char *name, int ftype, ...)
{
- SpiRegistry *registry = SPI_REGISTRY (data);
- SpiDesktopApplication *app = g_list_nth_data(desktop->applications, index);
-
- spi_dbus_remove_disconnect_match (registry->droute.bus, app->bus_name);
- emit(registry, "applicationRemove", DBUS_TYPE_UINT32, &index, DBUS_TYPE_STRING, &app->bus_name, DBUS_TYPE_INVALID);
+ va_list arg;
+
+ va_start(arg, ftype);
+ spi_dbus_emit_valist(reg->bus, SPI_DBUS_PATH_DEC, itf, name, ftype, arg);
+ va_end(arg);
}
+/*---------------------------------------------------------------------------*/
static void
-spi_registry_object_finalize (GObject *object)
+add_bus_name_cb (gpointer item, gpointer data)
{
- DBG (1, g_warning ("spi_registry_object_finalize called\n"));
- g_object_unref (SPI_REGISTRY (object)->de_controller);
+ DBusMessageIter *iter_array = (DBusMessageIter *) data;
- G_OBJECT_CLASS (spi_registry_parent_class)->finalize (object);
+ dbus_message_iter_append_basic (iter_array, DBUS_TYPE_STRING, (gchar *) item);
}
-/**
- * registerApplication:
- * @application: a reference to the requesting @Application
- * return values: void
- *
- * Register a new application with the accessibility broker.
- *
- **/
static DBusMessage *
-impl_accessibility_registry_register_application (DBusConnection *bus, DBusMessage *message, void *user_data)
+impl_getApplications (DBusConnection *bus, DBusMessage *message, void *user_data)
{
- SpiRegistry *registry = SPI_REGISTRY (user_data);
- const char *application = dbus_message_get_sender (message);
-
-#ifdef SPI_DEBUG
- fprintf (stderr, "registering app %s\n", application);
-#endif
- spi_desktop_add_application (registry->desktop, application);
+ DBusMessage *reply;
+ DBusMessageIter iter, iter_array;
+ SpiRegistry *reg = SPI_REGISTRY (user_data);
- spi_dbus_add_disconnect_match (registry->droute.bus, application);
+ reply = dbus_message_new_method_return (message);
- /*
- * TODO: change the implementation below to a WM-aware one;
- * e.g. don't add all apps to the SpiDesktop
- */
- return dbus_message_new_method_return (message);
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &iter_array);
+ g_sequence_foreach (reg->apps, add_bus_name_cb, &iter_array);
+ dbus_message_iter_close_container(&iter, &iter_array);
+ return reply;
}
-/**
- * deregisterApplication:
- * @application: a reference to the @Application
- * to be deregistered.
- * return values: void
- *
- * De-register an application previously registered with the broker.
- *
- **/
-static DBusMessage *
-impl_accessibility_registry_deregister_application (DBusConnection *bus, DBusMessage *message, void *user_data)
-{
- SpiRegistry *registry = SPI_REGISTRY (user_data);
- const char *application = dbus_message_get_sender (message);
-
- spi_desktop_remove_application (registry->desktop, application);
-
-#ifdef SPI_DEBUG
- fprintf (stderr, "de-registered app %s\n", application);
-#endif
- return dbus_message_new_method_return (message);
+static DBusHandlerResult
+message_handler (DBusConnection *bus, DBusMessage *message, void *user_data)
+{
+ DBusMessage *reply = NULL;
+
+ if (dbus_message_is_method_call (message, SPI_DBUS_INTERFACE_REGISTRY, "getApplications"))
+ {
+ reply = impl_getApplications (bus, message, user_data);
+ if (reply)
+ {
+ dbus_connection_send (bus, reply, NULL);
+ dbus_message_unref (reply);
+ }
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ else
+ {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
}
-/**
- * getDesktopCount:
- * return values: a short integer indicating the current number of
- * @Desktops.
- *
- * Get the current number of desktops.
- *
- **/
-static DBusMessage *
-impl_accessibility_registry_get_desktop_count (DBusConnection *bus, DBusMessage *message, void *user_data)
+/*---------------------------------------------------------------------------*/
+
+static gint
+data_str_cmp (gpointer a, gpointer b, gpointer data)
{
- dbus_int16_t n_desktops = 1;
- DBusMessage *reply;
+ return g_strcmp0(a, b);
+}
- /* TODO: implement support for multiple virtual desktops */
- reply = dbus_message_new_method_return (message);
- if (reply)
- {
- dbus_message_append_args (reply, DBUS_TYPE_INT16, &n_desktops, DBUS_TYPE_INVALID);
- }
- return reply;
+static gboolean
+seq_remove_string (GSequence *seq, gchar *str)
+{
+ GSequenceIter *iter;
+ gchar *item;
+ gboolean res = FALSE;
+
+ iter = g_sequence_search (seq, str, (GCompareDataFunc) data_str_cmp, NULL);
+ iter = g_sequence_iter_prev (iter);
+
+ if (!g_sequence_iter_is_end (iter))
+ {
+ item = g_sequence_get (iter);
+ if (!g_strcmp0 (item, str))
+ {
+ g_sequence_remove (iter);
+ res = TRUE;
+ }
+ }
+ return res;
}
-/**
- * getDesktop:
- * @n: the index of the requested @Desktop.
- * return values: a reference to the requested @Desktop.
- *
- * Get the nth accessible desktop.
- *
- **/
-static DBusMessage *
-impl_accessibility_registry_get_desktop (DBusConnection *bus, DBusMessage *message, void *user_data)
+static void
+handle_register_application (SpiRegistry *reg, DBusMessage *message)
{
- DBusError error;
- dbus_int16_t n;
- const char *path;
- DBusMessage *reply;
+ gchar *app_name;
- /* TODO: implement support for multiple virtual desktops */
- dbus_error_init (&error);
- if (!dbus_message_get_args (message, &error, DBUS_TYPE_INT16, &n, DBUS_TYPE_INVALID))
- {
- return spi_dbus_general_error (message);
- }
- path = (n == 0? SPI_DBUS_PATH_DESKTOP: "/");
- reply = dbus_message_new_method_return (message);
- if (reply)
- {
- dbus_message_append_args (reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID);
- }
- return reply;
+ if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &app_name, DBUS_TYPE_INVALID))
+ g_sequence_insert_sorted (reg->apps, app_name, (GCompareDataFunc) data_str_cmp, NULL);
}
-
-/**
- * getDesktopList:
- * return values: a sequence containing references to
- * the @Desktops.
- *
- * Get a list of accessible desktops.
- *
- **/
-static DBusMessage *
-impl_accessibility_registry_get_desktop_list (DBusConnection *bus, DBusMessage *message, void *user_data)
+static void
+handle_deregister_application (SpiRegistry *reg, DBusMessage *message)
{
- DBusMessage *reply;
- DBusMessageIter iter, iter_array;
- const char *path = SPI_DBUS_PATH_DESKTOP;
+ gchar *app_name;
- reply = dbus_message_new_method_return (message);
- if (!reply) return NULL;
- dbus_message_iter_init_append(reply, &iter);
- if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &iter_array)) goto oom;
- dbus_message_iter_append_basic(&iter_array, DBUS_TYPE_OBJECT_PATH, &path);
- if (!dbus_message_iter_close_container (&iter, &iter_array)) goto oom;
- return reply;
-oom:
- // TODO: handle out-of-memory
- return reply;
+ if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &app_name, DBUS_TYPE_INVALID))
+ seq_remove_string (reg->apps, app_name);
}
-
-static DBusMessage *
-impl_accessibility_registry_get_device_event_controller (DBusConnection *bus, DBusMessage *message, void *user_data)
+static void
+handle_disconnection (SpiRegistry *reg, DBusMessage *message)
{
- DBusMessage *reply;
- const char *path = SPI_DBUS_PATH_DEC;
+ char *name, *old, *new;
- reply = dbus_message_new_method_return (message);
- if (reply)
+ if (dbus_message_get_args (message, NULL,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &old,
+ DBUS_TYPE_STRING, &new,
+ DBUS_TYPE_INVALID))
{
- dbus_message_append_args (reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID);
+ if (*old != '\0' && *new == '\0')
+ {
+ if (seq_remove_string (reg->apps, old))
+ {
+ /*Emit deregistered signal here*/
+ emit (reg, SPI_DBUS_INTERFACE_TREE, "deregisterApplication", DBUS_TYPE_STRING, old);
+ /*TODO spi_remove_device_listeners (registry->de_controller, old);*/
+ }
+ }
}
- return reply;
}
-
-static void
-spi_registry_class_init (SpiRegistryClass *klass)
+static DBusHandlerResult
+signal_handler (DBusConnection *bus, DBusMessage *message, void *user_data)
{
- GObjectClass * object_class = (GObjectClass *) klass;
+ SpiRegistry *registry = SPI_REGISTRY (user_data);
+ guint res = DBUS_HANDLER_RESULT_HANDLED;
+ const char *iface = dbus_message_get_interface (message);
+ const char *member = dbus_message_get_member (message);
+
+ g_print ("\n%s", iface);
+ g_print ("\n%d", dbus_message_get_type (message));
+ g_print ("\n%s\n", member);
+
+#if 0
+ if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
+ handle_disconnection (registry, message);
+ else if (dbus_message_is_signal (message, SPI_DBUS_INTERFACE_TREE, "registerApplication"))
+ handle_register_application (registry, message);
+ else if (dbus_message_is_signal (message, SPI_DBUS_INTERFACE_TREE, "deregisterApplication"))
+ handle_deregister_application (registry, message);
+ else
+ res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+#endif
- spi_registry_parent_class = g_type_class_ref (G_TYPE_OBJECT);
-
- object_class->finalize = spi_registry_object_finalize;
+ if (!g_strcmp0(iface, DBUS_INTERFACE_DBUS) && !g_strcmp0(member, "NameOwnerChanged"))
+ handle_disconnection (registry, message);
+ else if (!g_strcmp0(iface, SPI_DBUS_INTERFACE_TREE) && !g_strcmp0(member, "registerApplication"))
+ handle_register_application (registry, message);
+ else if (!g_strcmp0(iface, SPI_DBUS_INTERFACE_TREE) && !g_strcmp0(member, "deregisterApplication"))
+ handle_deregister_application (registry, message);
+ else
+ res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ return res;
}
-static DBusObjectPathVTable droute_vtable =
+/*---------------------------------------------------------------------------*/
+
+static gchar *app_reg_sig_match = "type='signal', interface='org.freedesktop.atspi.Tree', member='registerApplication'";
+static gchar *app_dereg_sig_match = "type='signal', interface='org.freedesktop.atspi.Tree', member='deregisterApplication'";
+
+static DBusObjectPathVTable reg_vtable =
{
NULL,
- &droute_message,
+ &message_handler,
NULL, NULL, NULL, NULL
};
-DBusHandlerResult
-disconnect_watch (DBusConnection *bus, DBusMessage *message, void *user_data)
-{
- SpiRegistry *registry = SPI_REGISTRY (user_data);
- const char *name, *old, *new;
-
- if (!dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
- {
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
- if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old, DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID))
- {
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
- if (*old != '\0' && *new == '\0')
- {
- spi_desktop_remove_application (registry->desktop, old);
- spi_remove_device_listeners (registry->de_controller, old);
- }
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static void
-spi_registry_init (SpiRegistry *registry)
+SpiRegistry *
+spi_registry_new (DBusConnection *bus)
{
- DBusError error;
-
- spi_registry_set_debug (g_getenv ("AT_SPI_DEBUG"));
- /*
- * TODO: FIXME, this module makes the foolish assumptions that
- * registryd uses the same display as the apps, and that the
- * DISPLAY environment variable is set.
- */
- gdk_init (NULL, NULL);
-
- registry->exit_notify_timeout = 200;
- registry->queue_handler_id = 0;
-
- dbus_error_init (&error);
- registry->droute.bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
- if (!registry->droute.bus)
- {
- g_warning("Couldn't connect to dbus: %s\n", error.message);
- return;
- }
- registry->droute.user_data = registry;
- spi_registry_initialize_registry_interface (®istry->droute);
- spi_registry_initialize_desktop_interface (®istry->droute);
- spi_registry_initialize_dec_interface (®istry->droute);
- // todo: initialize accessible and component interfaces, for desktop?
- if (!dbus_connection_try_register_fallback (registry->droute.bus, "/org/freedesktop/atspi", &droute_vtable, ®istry->droute, &error))
- {
- g_warning("Couldn't register droute.\n");
- }
- dbus_connection_setup_with_g_main(registry->droute.bus, g_main_context_default());
+ SpiRegistry *reg = g_object_new (SPI_REGISTRY_TYPE, NULL);
- // TODO: decide whether focus_object is still relevant
- registry->desktop = spi_desktop_new ();
- /* Register callback notification for application addition and removal */
- g_signal_connect (G_OBJECT (registry->desktop),
- "application_added",
- G_CALLBACK (desktop_add_application),
- registry);
+ reg->bus = bus;
- g_signal_connect (G_OBJECT (registry->desktop),
- "application_removed",
- G_CALLBACK (desktop_remove_application),
- registry);
+ dbus_connection_register_object_path(bus, SPI_DBUS_PATH_REGISTRY, ®_vtable, reg);
- registry->de_controller = spi_device_event_controller_new (registry);
+ dbus_bus_add_match (bus, app_reg_sig_match, NULL);
+ dbus_bus_add_match (bus, app_dereg_sig_match, NULL);
+ dbus_connection_add_filter (bus, signal_handler, reg, NULL);
- dbus_connection_add_filter (registry->droute.bus, disconnect_watch, registry, NULL);
-}
-
-SpiRegistry *
-spi_registry_new (void)
-{
- SpiRegistry *retval = g_object_new (SPI_REGISTRY_TYPE, NULL);
- return retval;
+ return reg;
}
-
-static DRouteMethod methods[] =
-{
- { impl_accessibility_registry_register_application , "registerApplication" },
- { impl_accessibility_registry_deregister_application, "deregisterApplication" },
- { impl_accessibility_registry_get_desktop_count, "getDesktopCount" },
- { impl_accessibility_registry_get_desktop, "getDesktop" },
- { impl_accessibility_registry_get_desktop_list, "getDesktopList" },
- { impl_accessibility_registry_get_device_event_controller, "getDeviceEventController" },
- { NULL, NULL }
-};
-
-void
-spi_registry_initialize_registry_interface (DRouteData * data)
-{
- droute_add_interface (data, "org.freedesktop.atspi.Registry", methods,
- NULL, NULL, NULL);
-};
#ifndef SPI_REGISTRY_H_
#define SPI_REGISTRY_H_
-#include <glib/gmain.h>
-#include <droute/droute.h>
+#include <glib.h>
+#include <glib-object.h>
typedef struct _SpiRegistry SpiRegistry;
-
-#include "desktop.h"
-#include "deviceeventcontroller.h"
+typedef struct _SpiRegistryClass SpiRegistryClass;
G_BEGIN_DECLS
struct _SpiRegistry {
GObject parent;
+ GSequence *apps;
- GList *object_listeners;
- GList *window_listeners;
- GList *toolkit_listeners;
- GQueue *deferred_event_queue;
- gboolean is_queueing;
- guint exit_notify_timeout;
- guint queue_handler_id;
- char *focus_object_bus;
- char *focus_object_path;
- SpiDEController *de_controller;
- SpiDesktop *desktop;
- DRouteData droute;
+ DBusConnection *bus;
};
-typedef struct {
+struct _SpiRegistryClass {
GObjectClass parent_class;
-} SpiRegistryClass;
+};
GType spi_registry_get_type (void);
-SpiRegistry *spi_registry_new (void);
-
-void spi_registry_emit(SpiRegistry *registry, const char *name, int first_arg_type, ...);
+SpiRegistry *spi_registry_new (DBusConnection *bus);
-void spi_registry_initialize_registry_interface (DRouteData * data);
-void spi_registry_initialize_dec_interface (DRouteData * data);
-void spi_registry_initialize_desktop_interface (DRouteData * data);
G_END_DECLS
#endif /* SPI_REGISTRY_H_ */