* AT-SPI - Assistive Technology Service Provider Interface
* (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
*
- * Copyright 2001 Sun Microsystems Inc.
+ * 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
/* registry.c: the main accessibility service registry implementation */
#undef SPI_LISTENER_DEBUG
+#undef SPI_DEBUG
#include <config.h>
#ifdef SPI_DEBUG
/* A pointer to our parent object class */
static SpiListenerClass *spi_registry_parent_class;
+int _dbg = 0;
+
typedef enum {
ETYPE_FOCUS,
ETYPE_OBJECT,
ETYPE_WINDOW,
ETYPE_TOOLKIT,
ETYPE_KEYBOARD,
-
+ ETYPE_MOUSE,
ETYPE_LAST_DEFINED
} EventTypeCategory;
typedef struct {
- char *event_name;
+ const char *event_name;
EventTypeCategory type_cat;
GQuark major; /* from string segment[1] */
GQuark minor; /* from string segment[1]+segment[2] */
EventTypeCategory event_type_cat;
} SpiListenerStruct;
+static void
+spi_registry_set_debug (const char *debug_flag_string)
+{
+ if (debug_flag_string)
+ _dbg = (int) g_ascii_strtod (debug_flag_string, NULL);
+}
SpiListenerStruct *
spi_listener_struct_new (Accessibility_EventListener listener, CORBA_Environment *ev)
g_free (ls);
}
+static void
+desktop_add_application (SpiDesktop *desktop,
+ guint index, gpointer data)
+{
+ BonoboObject *registry = BONOBO_OBJECT (data);
+ Accessibility_Event e;
+ CORBA_Environment ev;
+ Accessibility_Accessible a;
+
+ CORBA_exception_init (&ev);
+ e.type = "object:children-changed:add";
+ e.source = BONOBO_OBJREF (desktop);
+ e.detail1 = index;
+ e.detail2 = 0;
+ a = Accessibility_Accessible_getChildAtIndex (BONOBO_OBJREF (desktop),
+ index, &ev);
+ /* FIXME
+ spi_init_any_object (&e.any_data, a);
+ */
+ spi_init_any_nil (&e.any_data);
+ Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
+ &e, &ev);
+ bonobo_object_release_unref (a, &ev);
+ CORBA_exception_free (&ev);
+}
+
+
+
+static void
+desktop_remove_application (SpiDesktop *desktop,
+ guint index, gpointer data)
+{
+ BonoboObject *registry = BONOBO_OBJECT (data);
+ Accessibility_Event e;
+ Accessibility_Accessible a;
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ e.type = "object:children-changed:remove";
+ e.source = BONOBO_OBJREF (desktop);
+ e.detail1 = index;
+ e.detail2 = 0;
+ a = Accessibility_Accessible_getChildAtIndex (BONOBO_OBJREF (desktop),
+ index, &ev);
+ /* FIXME
+ spi_init_any_object (&e.any_data, a);
+ */
+ spi_init_any_nil (&e.any_data);
+ Accessibility_Accessible_unref (a, &ev);
+ Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
+ &e, &ev);
+ Accessibility_Desktop_unref (e.source, &ev);
+ CORBA_exception_free (&ev);
+}
+
static void
spi_registry_object_finalize (GObject *object)
{
- printf ("spi_registry_object_finalize called\n");
+ DBG (1, g_warning ("spi_registry_object_finalize called\n"));
/* TODO: unref deviceeventcontroller, which disconnects key listener */
G_OBJECT_CLASS (spi_registry_parent_class)->finalize (object);
gchar *s;
split_string = g_strsplit (event_name, ":", 4);
- etype->event_name = g_strdup (event_name);
+ etype->event_name = event_name;
if (!g_ascii_strncasecmp (event_name, "focus:", 6))
{
etype->type_cat = ETYPE_FOCUS;
}
+ else if (!g_ascii_strncasecmp (event_name, "mouse:", 6))
+ {
+ etype->type_cat = ETYPE_MOUSE;
+ }
else if (!g_ascii_strncasecmp (event_name, "object:", 7))
{
etype->type_cat = ETYPE_OBJECT;
{
etype->type_cat = ETYPE_WINDOW;
}
+ else if (!g_ascii_strncasecmp (event_name, "keyboard:", 9))
+ {
+ etype->type_cat = ETYPE_KEYBOARD;
+ }
else
{
etype->type_cat = ETYPE_TOOLKIT;
if (split_string[1])
{
+ etype->major = g_quark_from_string (split_string[1]);
if (split_string[2])
{
etype->minor = g_quark_from_string (s = g_strconcat (split_string[1], split_string[2], NULL));
if (split_string[3])
{
etype->detail = g_quark_from_string (split_string[3]);
- s = g_strconcat (split_string[1], split_string[2], split_string[3], NULL);
- etype->major = g_quark_from_string (s);
- g_free (s);
}
else
{
etype->detail = g_quark_from_static_string ("");
- s = g_strconcat (split_string[1], split_string[2], NULL);
- etype->major = g_quark_from_string (s);
- g_free (s);
}
}
else
{
- etype->major = g_quark_from_string (split_string[1]);
etype->minor = etype->major;
- etype->detail = etype->major;
+ etype->detail = g_quark_from_static_string (""); //etype->major;
}
}
else
case ETYPE_OBJECT:
case ETYPE_PROPERTY:
case ETYPE_FOCUS:
+ case ETYPE_KEYBOARD:
ret = ®istry->object_listeners;
break;
case ETYPE_WINDOW:
ret = ®istry->window_listeners;
break;
+ case ETYPE_MOUSE:
case ETYPE_TOOLKIT:
ret = ®istry->toolkit_listeners;
break;
- case ETYPE_KEYBOARD:
default:
ret = NULL;
break;
const CORBA_char *event_name,
CORBA_Environment *ev)
{
- SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant));
+ SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant));
SpiListenerStruct *ls = spi_listener_struct_new (listener, ev);
EventTypeStruct etype;
GList **list;
-#ifdef SPI_DEBUG
+#ifdef SPI_LISTENER_DEBUG
fprintf (stderr, "registering for events of type %s\n", event_name);
#endif
/* parse, check major event type and add listener accordingly */
parse_event_type (&etype, event_name);
- ls->event_type_quark = etype.major;
+ ls->event_type_quark = etype.minor;
ls->event_type_cat = etype.type_cat;
list = get_listener_list (registry, etype.type_cat);
CORBA_Environment *ev)
{
int i;
- GList **lists[2];
+ GList **lists[3];
SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant));
lists[0] = ®istry->object_listeners;
ls = (*list)->data;
#ifdef SPI_LISTENER_DEBUG
- fprintf (stderr, "event quarks: %lx %lx %lx\n", ls->event_type_quark, etype.major, etype.minor);
- fprintf (stderr, "event name: %s\n", etype.event_name);
+ fprintf (stderr, "event quarks: %lx %lx %lx\n", ls->event_type_quark, ctx->etype.major, ctx->etype.minor);
+ fprintf (stderr, "event name: %s\n", ctx->etype.event_name);
#endif
if ((ls->event_type_quark == ctx->etype.major) ||
(ls->event_type_quark == ctx->etype.minor))
{
#ifdef SPI_DEBUG
- fprintf (stderr, "notifying listener %d\n", g_list_index (listeners, l->data));
- s = Accessibility_Accessible__get_name (ctx->source, ev);
+ fprintf (stderr, "notifying listener %d\n", 0);
+/* g_list_index (list, l->data)); */
+ s = Accessibility_Accessible__get_name (ctx->source, ctx->ev);
fprintf (stderr, "event source name %s\n", s);
CORBA_free (s);
#endif
- ctx->e_out.source = bonobo_object_dup_ref (ctx->source, ctx->ev);
+ ctx->e_out.source = CORBA_Object_duplicate (ctx->source, ctx->ev);
if (BONOBO_EX (ctx->ev))
{
- return SPI_RE_ENTRANT_CONTINUE;;
+ return SPI_RE_ENTRANT_CONTINUE;
}
-
+
if ((*list) && (*list)->data == ls)
{
Accessibility_EventListener_notifyEvent (
(Accessibility_EventListener) ls->listener, &ctx->e_out, ctx->ev);
- if (ctx->ev->_major != CORBA_NO_EXCEPTION)
- {
- g_warning ("Accessibility app error: exception during "
- "event notification: %s\n",
- CORBA_exception_id (ctx->ev));
- }
+ if (ctx->ev->_major != CORBA_NO_EXCEPTION)
+ {
+ DBG (1, g_warning ("Accessibility app error: exception during "
+ "event notification: %s\n",
+ CORBA_exception_id (ctx->ev)));
+ if (ctx->ev->_major == CORBA_SYSTEM_EXCEPTION)
+ CORBA_exception_init (ctx->ev);
+ /* clear system exception on notify, it means listener is dead but
+ * that's no concern of the event source :-) */
+ }
}
else /* dup re-entered */
{
- bonobo_object_release_unref (ctx->e_out.source, ctx->ev);
+ CORBA_Object_release (ctx->e_out.source, ctx->ev);
}
}
list = get_listener_list (registry, ctx.etype.type_cat);
- if (list)
+ if (list && *list)
{
ctx.ev = ev;
ctx.e_out = *e;
+ CORBA_any__copy (&ctx.e_out.any_data, &e->any_data);
ctx.source = e->source;
- parse_event_type (&ctx.etype, e->type);
-
spi_re_entrant_list_foreach (list, notify_listeners_cb, &ctx);
}
-
- if (e->source != CORBA_OBJECT_NIL)
- {
- Accessibility_Accessible_unref (e->source, ev);
- }
}
-
static void
spi_registry_class_init (SpiRegistryClass *klass)
{
static void
spi_registry_init (SpiRegistry *registry)
{
+ spi_registry_set_debug (g_getenv ("AT_SPI_DEBUG"));
registry->object_listeners = NULL;
registry->window_listeners = NULL;
registry->toolkit_listeners = NULL;
registry->desktop = spi_desktop_new ();
- registry->de_controller = NULL;
+ /* Register callback notification for application addition and removal */
+ g_signal_connect (G_OBJECT (registry->desktop),
+ "application_added",
+ G_CALLBACK (desktop_add_application),
+ registry);
+
+ g_signal_connect (G_OBJECT (registry->desktop),
+ "application_removed",
+ G_CALLBACK (desktop_remove_application),
+ registry);
+
+ registry->de_controller = spi_device_event_controller_new (registry);
}
BONOBO_TYPE_FUNC_FULL (SpiRegistry,