+2001-18-11 Bill Haneman <bill.haneman@sun.com>
+
+ * libspi/spi_accessible.c: Added docs and C bindings for
+ AccessibleStateSet. (No implementations yet). Documentation
+ coverage for C bindings now 100%. Made docs for event listeners
+ more explicit.
+
+ * idl/Registry.idl:
+ Added methods
+ boolean notifyListenersSync (in DeviceEventListener listener,
+ in DeviceEvent event);
+
+ oneway void notifyListenersAsync (in DeviceEventListener listener,
+ in DeviceEvent event);
+
+ Added DeviceEventListener and DeviceEvent structs (may deprecate
+ KeyStroke and KeystrokeListener in favor of this generic
+ event/listener framework for devices).
+
+ * libspi/deviceeventcontroller.c:
+
+ Changed some key listener code to take masks, etc., and paved the
+ way for integration of toolkit/non-preemptive key events. Changed
+ signatures of some internal methods.
+
+ * at-bridge/bridge.c:
+ Fixed regression connecting to interface signals, apparently
+ caused by GTK+ changes.
+
+ Added an internal bridge_state_listener to deal with
+ property-change:accessible-state signals.
+
+ Changed the key_listeners GList to store structs (including masks,
+ etc.) instead of just CORBA_Objects (required for full
+ implementation of key listener API).
+
+ Connected the bridge to all currently supported Atk signals.
+ Events now supported:
+ object:property-change
+ object:property-change:accessible-name
+ object:property-change:accessible-state
+ object:property-change:accessible-description
+ object:property-change:accessible-parent
+ object:property-change:accessible-value
+ object:property-change:accessible-role
+ object:property-change:accessible-table-caption
+ object:property-change:accessible-table-column-description
+ object:property-change:accessible-table-column-header
+ object:property-change:accessible-table-row-description
+ object:property-change:accessible-table-row-header
+ object:property-change:accessible-table-summary
+ object:children-changed
+ object:visible-data-changed
+ object:selection-changed
+ object:text-selection-changed
+ object:text-changed
+ object:text-caret-moved
+ object:row-inserted
+ object:row-reordered
+ object:row-deleted
+ object:column-inserted
+ object:column-reordered
+ object:column-deleted
+ object:model-changed
+
2001-16-11 Bill Haneman <bill.haneman@sun.com>
+ * libspi/hyperlink.c,h:
+ Fixed some broken stuff in hyperlink.
+
* libspi/relation.h:
* libspi/relation.c:
* cspi/spi_accessible.c:
#include <orbit/orbit.h>
#include <atk/atk.h>
#include <atk/atkobject.h>
+#include <atk/atknoopobject.h>
#include <libspi/Accessibility.h>
#include "accessible.h"
#include "application.h"
guint n_param_values,
const GValue *param_values,
gpointer data);
+static gboolean bridge_state_event_listener (GSignalInvocationHint *signal_hint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
static gboolean bridge_signal_listener (GSignalInvocationHint *signal_hint,
guint n_param_values,
const GValue *param_values,
static void
register_atk_event_listeners ()
{
- /* Register for focus event notifications, and register app with central registry */
+ GType t;
+
+ /*
+ * kludge to make sure the Atk interface types are registered, otherwise
+ * the AtkText signal handlers below won't get registered
+ */
-/* kludge to make sure the Atk interface types are registered, otherwise
- the AtkText signal handlers below won't get registered */
+ AtkNoOpObject *o = atk_no_op_object_new (g_object_new (ATK_TYPE_OBJECT, NULL));
+
+ /* Register for focus event notifications, and register app with central registry */
- ATK_TYPE_TEXT;
+ g_type_class_ref (ATK_TYPE_TEXT);
+ g_type_class_ref (ATK_TYPE_SELECTION);
+ g_type_class_ref (ATK_TYPE_TABLE);
atk_add_focus_tracker (bridge_focus_tracker);
atk_add_global_event_listener (bridge_property_event_listener, "Gtk:AtkObject:property-change");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:children-changed");
- atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:model-changed");
- atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:selection-changed");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:visible-data-changed");
+ atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkSelection:selection-changed");
+ atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-selection-changed");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-changed");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-caret-moved");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:row-inserted");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-inserted");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-reordered");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-deleted");
+ atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:model-changed");
atk_add_key_event_listener (bridge_key_listener, NULL);
}
return TRUE;
}
+static gboolean
+bridge_state_event_listener (GSignalInvocationHint *signal_hint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ Accessibility_Event *e = Accessibility_Event__alloc();
+ Bonobo_Unknown source = NULL;
+ AtkObject *aobject;
+ AtkPropertyValues *values;
+ GObject *gobject;
+ GSignalQuery signal_query;
+ gchar *name;
+ char sbuf[APP_STATIC_BUFF_SZ];
+
+ g_signal_query (signal_hint->signal_id, &signal_query);
+ name = signal_query.signal_name;
+#ifdef SPI_BRIDGE_DEBUG
+ fprintf (stderr, "Received (state) signal %s:%s\n",
+ g_type_name (signal_query.itype), name);
+#endif
+ gobject = g_value_get_object (param_values + 0);
+ values = (AtkPropertyValues*) g_value_get_pointer (param_values + 1);
+
+ /* notify the actual listeners */
+ if (ATK_IS_IMPLEMENTOR (gobject))
+ {
+ aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject));
+ source = CORBA_Object_duplicate (BONOBO_OBJREF (spi_accessible_new (aobject)), &ev);
+ g_object_unref (G_OBJECT(aobject));
+ }
+ else if (ATK_IS_OBJECT (gobject))
+ {
+ aobject = ATK_OBJECT (gobject);
+ source = CORBA_Object_duplicate (BONOBO_OBJREF (spi_accessible_new (aobject)), &ev);
+ }
+ else
+ {
+ g_error("received property-change event from non-AtkImplementor");
+ }
+
+ snprintf(sbuf, APP_STATIC_BUFF_SZ, "object:%s:%s", values->property_name, "?");
+ e->type = CORBA_string_dup (sbuf);
+ e->source = source;
+ e->detail1 = (unsigned long) values->old_value.data[0].v_ulong;
+ e->detail2 = (unsigned long) values->new_value.data[0].v_ulong;
+ if (source)
+ Accessibility_Registry_notifyEvent (registry, e, &ev);
+ return TRUE;
+}
+
static gint
bridge_key_listener (AtkImplementor *atk_impl, AtkKeyEventStruct *event, gpointer data)
{
- g_print ("bridge key listener!\n");
+ Accessibility_KeyStroke *key_event;
+ static Accessibility_DeviceEventController controller = CORBA_OBJECT_NIL;
+ if (controller == CORBA_OBJECT_NIL)
+ {
+ controller = Accessibility_Registry_getDeviceEventController (registry, &ev);
+ }
+ g_print ("bridge key listener fired!\n");
+/* Accessibility_DeviceEventController_notifyListenersSync (controller, key_event, &ev); */
}
static gboolean
g_signal_query (signal_hint->signal_id, &signal_query);
name = signal_query.signal_name;
#ifdef SPI_BRIDGE_DEBUG
- fprintf (stderr, "Received (property) signal %s:%s\n",
+ fprintf (stderr, "Received signal %s:%s\n",
g_type_name (signal_query.itype), name);
#endif
gobject = g_value_get_object (param_values + 0);
#include <orbit/orbit.h>
#include <atk/atk.h>
#include <atk/atkobject.h>
+#include <atk/atknoopobject.h>
#include <libspi/Accessibility.h>
#include "accessible.h"
#include "application.h"
guint n_param_values,
const GValue *param_values,
gpointer data);
+static gboolean bridge_state_event_listener (GSignalInvocationHint *signal_hint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
static gboolean bridge_signal_listener (GSignalInvocationHint *signal_hint,
guint n_param_values,
const GValue *param_values,
static void
register_atk_event_listeners ()
{
- /* Register for focus event notifications, and register app with central registry */
+ GType t;
+
+ /*
+ * kludge to make sure the Atk interface types are registered, otherwise
+ * the AtkText signal handlers below won't get registered
+ */
-/* kludge to make sure the Atk interface types are registered, otherwise
- the AtkText signal handlers below won't get registered */
+ AtkNoOpObject *o = atk_no_op_object_new (g_object_new (ATK_TYPE_OBJECT, NULL));
+
+ /* Register for focus event notifications, and register app with central registry */
- ATK_TYPE_TEXT;
+ g_type_class_ref (ATK_TYPE_TEXT);
+ g_type_class_ref (ATK_TYPE_SELECTION);
+ g_type_class_ref (ATK_TYPE_TABLE);
atk_add_focus_tracker (bridge_focus_tracker);
atk_add_global_event_listener (bridge_property_event_listener, "Gtk:AtkObject:property-change");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:children-changed");
- atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:model-changed");
- atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:selection-changed");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:visible-data-changed");
+ atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkSelection:selection-changed");
+ atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-selection-changed");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-changed");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-caret-moved");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:row-inserted");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-inserted");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-reordered");
atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-deleted");
+ atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:model-changed");
atk_add_key_event_listener (bridge_key_listener, NULL);
}
return TRUE;
}
+static gboolean
+bridge_state_event_listener (GSignalInvocationHint *signal_hint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ Accessibility_Event *e = Accessibility_Event__alloc();
+ Bonobo_Unknown source = NULL;
+ AtkObject *aobject;
+ AtkPropertyValues *values;
+ GObject *gobject;
+ GSignalQuery signal_query;
+ gchar *name;
+ char sbuf[APP_STATIC_BUFF_SZ];
+
+ g_signal_query (signal_hint->signal_id, &signal_query);
+ name = signal_query.signal_name;
+#ifdef SPI_BRIDGE_DEBUG
+ fprintf (stderr, "Received (state) signal %s:%s\n",
+ g_type_name (signal_query.itype), name);
+#endif
+ gobject = g_value_get_object (param_values + 0);
+ values = (AtkPropertyValues*) g_value_get_pointer (param_values + 1);
+
+ /* notify the actual listeners */
+ if (ATK_IS_IMPLEMENTOR (gobject))
+ {
+ aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject));
+ source = CORBA_Object_duplicate (BONOBO_OBJREF (spi_accessible_new (aobject)), &ev);
+ g_object_unref (G_OBJECT(aobject));
+ }
+ else if (ATK_IS_OBJECT (gobject))
+ {
+ aobject = ATK_OBJECT (gobject);
+ source = CORBA_Object_duplicate (BONOBO_OBJREF (spi_accessible_new (aobject)), &ev);
+ }
+ else
+ {
+ g_error("received property-change event from non-AtkImplementor");
+ }
+
+ snprintf(sbuf, APP_STATIC_BUFF_SZ, "object:%s:%s", values->property_name, "?");
+ e->type = CORBA_string_dup (sbuf);
+ e->source = source;
+ e->detail1 = (unsigned long) values->old_value.data[0].v_ulong;
+ e->detail2 = (unsigned long) values->new_value.data[0].v_ulong;
+ if (source)
+ Accessibility_Registry_notifyEvent (registry, e, &ev);
+ return TRUE;
+}
+
static gint
bridge_key_listener (AtkImplementor *atk_impl, AtkKeyEventStruct *event, gpointer data)
{
- g_print ("bridge key listener!\n");
+ Accessibility_KeyStroke *key_event;
+ static Accessibility_DeviceEventController controller = CORBA_OBJECT_NIL;
+ if (controller == CORBA_OBJECT_NIL)
+ {
+ controller = Accessibility_Registry_getDeviceEventController (registry, &ev);
+ }
+ g_print ("bridge key listener fired!\n");
+/* Accessibility_DeviceEventController_notifyListenersSync (controller, key_event, &ev); */
}
static gboolean
g_signal_query (signal_hint->signal_id, &signal_query);
name = signal_query.signal_name;
#ifdef SPI_BRIDGE_DEBUG
- fprintf (stderr, "Received (property) signal %s:%s\n",
+ fprintf (stderr, "Received signal %s:%s\n",
g_type_name (signal_query.itype), name);
#endif
gobject = g_value_get_object (param_values + 0);
#include "accessibleeventlistener.h"
#include "keystrokelistener.h"
-#define SPI_KEYSET_ALL_KEYS ((void *)NULL)
-
-
/*
*
* Structure used to encapsulate event information
* @SPI_KEYSET_ALL_KEYS: A special value for an AccessibleKeySet type, which tacitly
* includes all keycodes and keyvals for the specified modifier set.
**/
-#define SPI_KEYSET_ALL_KEYS ((void *)NULL)
+#define SPI_KEYSET_ALL_KEYS NULL
typedef unsigned long AccessibleKeyMaskType;
{
return NULL;
}
+
+/**
+ * AccessibleStateSet_ref:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ *
+ * Increment the reference count for an #AccessibleStateSet object.
+ *
+ * Returns: (no return code implemented yet).
+ *
+ **/
+int
+AccessibleStateSet_ref (AccessibleStateSet *obj)
+{
+/* Accessibility_StateSet_ref (*obj, &ev); */
+ spi_check_ev (&ev, "ref");
+ return 0;
+}
+
+/**
+ * AccessibleStateSet_unref:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ *
+ * Decrement the reference count for an #AccessibleStateSet object.
+ *
+ * Returns: (no return code implemented yet).
+ *
+ **/
+int
+AccessibleStateSet_unref (AccessibleStateSet *obj)
+{
+/* Accessibility_StateSet_unref (*obj, &ev); */
+ spi_check_ev (&ev, "unref");
+ return 0;
+}
+
+
+/**
+ * AccessibleStateSet_contains:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ * @state: an #AccessibleState for which the specified #AccessibleStateSet
+ * will be queried.
+ *
+ * Determine whether a given #AccessibleStateSet includes a given state; that is,
+ * whether @state is true for the stateset in question.
+ *
+ * Returns: #TRUE if @state is true/included in the given #AccessibleStateSet,
+ * otherwise #FALSE.
+ *
+ **/
+boolean
+AccessibleStateSet_contains (AccessibleStateSet *obj,
+ AccessibleState state)
+{
+ CORBA_boolean retval = Accessibility_StateSet_contains (*obj, state, &ev);
+ spi_check_ev (&ev, "contains");
+ return (boolean) retval;
+}
+
+/**
+ * AccessibleStateSet_add:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ * @state: an #AccessibleState to be added to the specified #AccessibleStateSet
+ *
+ * Add a particular #AccessibleState to an #AccessibleStateSet (i.e. set the
+ * given state to #TRUE in the stateset.
+ *
+ **/
+void
+AccessibleStateSet_add (AccessibleStateSet *obj,
+ AccessibleState state)
+{
+ Accessibility_StateSet_add (*obj, state, &ev);
+ spi_check_ev (&ev, "contains");
+}
+
+
+/**
+ * AccessibleStateSet_remove:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ * @state: an #AccessibleState to be removed from the specified #AccessibleStateSet
+ *
+ * Remove a particular #AccessibleState to an #AccessibleStateSet (i.e. set the
+ * given state to #FALSE in the stateset.)
+ *
+ **/
+void
+AccessibleStateSet_remove (AccessibleStateSet *obj,
+ AccessibleState state)
+{
+ Accessibility_StateSet_remove (*obj, state, &ev);
+ spi_check_ev (&ev, "contains");
+}
+
+/**
+ * AccessibleStateSet_equals:
+ * @obj: a pointer to the first #AccessibleStateSet object on which to operate.
+ * @obj2: a pointer to the second #AccessibleStateSet object on which to operate.
+ *
+ * Determine whether two instances of #AccessibleStateSet are equivalent (i.e.
+ * consist of the same #AccessibleStates). Useful for checking multiple
+ * state variables at once; construct the target state then compare against it.
+ *
+ * @see AccessibleStateSet_compare().
+ *
+ * Returns: #TRUE if the two #AccessibleStateSets are equivalent,
+ * otherwise #FALSE.
+ *
+ **/
+boolean
+AccessibleStateSet_equals (AccessibleStateSet *obj,
+ AccessibleStateSet *obj2)
+{
+ return Accessibility_StateSet_equals (*obj, *obj2, &ev);
+}
+
+/**
+ * AccessibleStateSet_compare:
+ * @obj: a pointer to the first #AccessibleStateSet object on which to operate.
+ * @obj2: a pointer to the second #AccessibleStateSet object on which to operate.
+ *
+ * Determine the differences between two instances of #AccessibleStateSet.
+ *.
+ * @see AccessibleStateSet_equals().
+ *
+ * Returns: an #AccessibleStateSet object containing all states contained on one of
+ * the two sets but not the other.
+ *
+ **/
+void
+AccessibleStateSet_compare (AccessibleStateSet *obj,
+ AccessibleStateSet *obj2,
+ AccessibleStateSet **differenceSet);
+
+
+/**
+ * AccessibleStateSet_isEmpty:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ *
+ * Determine whether a given #AccessibleStateSet is the empty set.
+ *
+ * Returns: #TRUE if the given #AccessibleStateSet contains no (true) states,
+ * otherwise #FALSE.
+ *
+ **/
+boolean
+AccessibleStateSet_isEmpty (AccessibleStateSet *obj)
+{
+ return TRUE;
+ /* return Accessibility_StateSet_isEmpty (*obj, &ev);*/
+}
+
+
+
+
* notification is requested. Format is
* EventClass:major_type:minor_type:detail
* where all subfields other than EventClass are optional.
- * EventClasses include "Focus", "Window", "Mouse",
+ * EventClasses include "object", "window", "mouse",
* and toolkit events (e.g. "Gtk", "AWT").
* Examples: "focus:", "Gtk:GtkWidget:button_press_event".
*
+ * Legal object event types:
+ *
+ * (property change events)
+ *
+ * object:property-change
+ * object:property-change:accessible-name
+ * object:property-change:accessible-state
+ * object:property-change:accessible-description
+ * object:property-change:accessible-parent
+ * object:property-change:accessible-value
+ * object:property-change:accessible-role
+ * object:property-change:accessible-table-caption
+ * object:property-change:accessible-table-column-description
+ * object:property-change:accessible-table-column-header
+ * object:property-change:accessible-table-row-description
+ * object:property-change:accessible-table-row-header
+ * object:property-change:accessible-table-summary
+ *
+ * (other object events)
+ *
+ * object:children-changed
+ * object:visible-data-changed
+ * object:selection-changed
+ * object:text-selection-changed
+ * object:text-changed
+ * object:text-caret-moved
+ * object:row-inserted
+ * object:row-reordered
+ * object:row-deleted
+ * object:column-inserted
+ * object:column-reordered
+ * object:column-deleted
+ * object:model-changed
+ *
* NOTE: this string may be UTF-8, but should not contain byte value 56
* (ascii ':'), except as a delimiter, since non-UTF-8 string
* delimiting functions are used internally.
AccessibleKeyMaskType
AccessibleKeyEventType
AccessibleKeyListenerSyncType
-SPI_KEYSET_ALL_KEYS
createAccessibleKeystrokeListener
registerGlobalEventListener
deregisterGlobalEventListener
KEY_RELEASED
};
+ enum EventType {
+ KEY_PRESSED_EVENT,
+ KEY_RELEASED_EVENT
+ };
+
enum KeySynthType {
KEY_PRESS,
KEY_RELEASE,
struct KeyStroke {
long keyID;
short keycode;
+ unsigned long timestamp;
KeyEventType type;
unsigned short modifiers;
};
+ struct DeviceEvent {
+ long eventID;
+ short hw_code;
+ unsigned long timestamp;
+ EventType type;
+ unsigned short modifiers;
+ };
+
typedef sequence< long > KeySet;
typedef sequence< KeyEventType > KeyEventTypeSeq;
boolean keyEvent (in KeyStroke key);
};
+ interface DeviceEventListener : Bonobo::Unknown {
+ boolean notifyEvent (in DeviceEvent event);
+ };
+
interface DeviceEventController : Bonobo::Unknown {
/**
in KeyEventTypeSeq type,
in boolean is_synchronous);
+ boolean notifyListenersSync (in DeviceEventListener listener,
+ in DeviceEvent event);
+
+ oneway void notifyListenersAsync (in DeviceEventListener listener,
+ in DeviceEvent event);
+
/**
* generateKeyEvent:
* @keycode: a long integer indicating the keycode of
KEY_RELEASED
};
+ enum EventType {
+ KEY_PRESSED_EVENT,
+ KEY_RELEASED_EVENT
+ };
+
enum KeySynthType {
KEY_PRESS,
KEY_RELEASE,
struct KeyStroke {
long keyID;
short keycode;
+ unsigned long timestamp;
KeyEventType type;
unsigned short modifiers;
};
+ struct DeviceEvent {
+ long eventID;
+ short hw_code;
+ unsigned long timestamp;
+ EventType type;
+ unsigned short modifiers;
+ };
+
typedef sequence< long > KeySet;
typedef sequence< KeyEventType > KeyEventTypeSeq;
boolean keyEvent (in KeyStroke key);
};
+ interface DeviceEventListener : Bonobo::Unknown {
+ boolean notifyEvent (in DeviceEvent event);
+ };
+
interface DeviceEventController : Bonobo::Unknown {
/**
in KeyEventTypeSeq type,
in boolean is_synchronous);
+ boolean notifyListenersSync (in DeviceEventListener listener,
+ in DeviceEvent event);
+
+ oneway void notifyListenersAsync (in DeviceEventListener listener,
+ in DeviceEvent event);
+
/**
* generateKeyEvent:
* @keycode: a long integer indicating the keycode of
static Window root_window;
typedef enum {
- DEVICE_TYPE_KBD,
- DEVICE_TYPE_MOUSE,
- DEVICE_TYPE_LAST_DEFINED
-} DeviceTypeCategory;
+ SPI_DEVICE_TYPE_KBD,
+ SPI_DEVICE_TYPE_MOUSE,
+ SPI_DEVICE_TYPE_LAST_DEFINED
+} SpiDeviceTypeCategory;
+
+struct _DEControllerListener {
+ CORBA_Object object;
+ SpiDeviceTypeCategory type;
+};
+
+typedef struct _DEControllerListener DEControllerListener;
+
+struct _DEControllerKeyListener {
+ DEControllerListener listener;
+ Accessibility_KeySet *keys;
+ Accessibility_ControllerEventMask *mask;
+ Accessibility_KeyEventTypeSeq *typeseq;
+ gboolean is_system_global;
+};
+
+typedef struct _DEControllerKeyListener DEControllerKeyListener;
static gboolean _controller_register_with_devices (SpiDeviceEventController *controller);
static gboolean _controller_grab_keyboard (SpiDeviceEventController *controller);
-static void _controller_register_device_listener (SpiDeviceEventController *controller,
- const CORBA_Object l,
- DeviceTypeCategory type,
- const Accessibility_KeySet *keys,
- const Accessibility_ControllerEventMask *mask,
- CORBA_Environment *ev);
+static void controller_register_device_listener (SpiDeviceEventController *controller,
+ DEControllerListener *l,
+ CORBA_Environment *ev);
/*
* Private methods
*/
static gint
+_compare_listeners (gconstpointer p1, gconstpointer p2)
+{
+ DEControllerListener *l1 = (DEControllerListener *) p1;
+ DEControllerListener *l2 = (DEControllerListener *) p2;
+ return _compare_corba_objects (l1->object, l2->object);
+}
+
+static gint
_compare_corba_objects (gconstpointer p1, gconstpointer p2)
{
CORBA_Environment ev;
return (gint) d;
}
+static DEControllerKeyListener *
+dec_key_listener_new (CORBA_Object l,
+ const Accessibility_KeySet *keys,
+ const Accessibility_ControllerEventMask *mask,
+ const Accessibility_KeyEventTypeSeq *typeseq,
+ const CORBA_boolean is_system_global,
+ CORBA_Environment *ev)
+{
+ DEControllerKeyListener *key_listener = g_new0 (DEControllerKeyListener, 1);
+ key_listener->listener.object = CORBA_Object_duplicate (l, ev);
+ key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
+ key_listener->keys = keys;
+ key_listener->mask = mask;
+ key_listener->is_system_global = is_system_global;
+
+ return key_listener;
+}
+
static void
-_controller_register_device_listener (SpiDeviceEventController *controller,
- const CORBA_Object l,
- DeviceTypeCategory type,
- const Accessibility_KeySet *keys,
- const Accessibility_ControllerEventMask *mask,
- CORBA_Environment *ev)
+controller_register_device_listener (SpiDeviceEventController *controller,
+ DEControllerListener *listener,
+ CORBA_Environment *ev)
{
Accessibility_ControllerEventMask *mask_ptr = NULL;
+ DEControllerKeyListener *key_listener;
- switch (type) {
- case DEVICE_TYPE_KBD:
- controller->key_listeners = g_list_append (controller->key_listeners,
- CORBA_Object_duplicate (l, ev));
+ switch (listener->type) {
+ case SPI_DEVICE_TYPE_KBD:
+ key_listener = (DEControllerKeyListener *) listener;
+ controller->key_listeners = g_list_append (controller->key_listeners, key_listener);
mask_ptr = (Accessibility_ControllerEventMask *)
- g_list_find_custom (controller->keymask_list, (gpointer) mask,
+ g_list_find_custom (controller->keymask_list, (gpointer) key_listener->mask,
_eventmask_compare_value);
if (mask_ptr)
++(mask_ptr->refcount);
else
{
- if (mask->refcount != (CORBA_unsigned_short) 1)
+ if (key_listener->mask->refcount != (CORBA_unsigned_short) 1)
fprintf (stderr, "mask initial refcount is not 1!\n");
- if (mask->value > (CORBA_unsigned_long) 2048)
+ if (key_listener->mask->value > (CORBA_unsigned_long) 2048)
fprintf (stderr, "mask value looks invalid (%lu)\n",
- (unsigned long) mask->value);
+ (unsigned long) key_listener->mask->value);
else
fprintf (stderr, "appending mask with val=%lu\n",
- (unsigned long) mask->value);
+ (unsigned long) key_listener->mask->value);
mask_ptr = Accessibility_ControllerEventMask__alloc();
- mask_ptr->value = mask->value;
+ mask_ptr->value = key_listener->mask->value;
mask_ptr->refcount = (CORBA_unsigned_short) 1;
controller->keymask_list = g_list_append (controller->keymask_list,
(gpointer) mask_ptr);
}
break;
- case DEVICE_TYPE_MOUSE:
+ case SPI_DEVICE_TYPE_MOUSE:
/* controller->mouse_listeners = g_list_append (controller->mouse_listeners,
CORBA_Object_duplicate (l, ev));*/
}
static void
-_controller_deregister_device_listener (SpiDeviceEventController *controller,
- const CORBA_Object l,
- const Accessibility_ControllerEventMask *mask,
- DeviceTypeCategory type,
- CORBA_Environment *ev)
+controller_deregister_device_listener (SpiDeviceEventController *controller,
+ DEControllerListener *listener,
+ CORBA_Environment *ev)
{
Accessibility_ControllerEventMask *mask_ptr;
+ DEControllerKeyListener *key_listener;
GList *list_ptr;
- switch (type) {
- case DEVICE_TYPE_KBD:
- list_ptr = g_list_find_custom (controller->key_listeners, l, _compare_corba_objects);
+ switch (listener->type) {
+ case SPI_DEVICE_TYPE_KBD:
+ key_listener = (DEControllerKeyListener *) listener;
+ list_ptr = g_list_find_custom (controller->key_listeners, listener, _compare_listeners);
+ /* TODO: need a different custom compare func */
if (list_ptr)
controller->key_listeners = g_list_remove (controller->key_listeners, list_ptr);
list_ptr = (GList *)
- g_list_find_custom (controller->keymask_list, (gpointer) mask,
+ g_list_find_custom (controller->keymask_list, (gpointer) key_listener->mask,
_eventmask_compare_value);
if (list_ptr)
{
}
}
break;
- case DEVICE_TYPE_MOUSE:
+ case SPI_DEVICE_TYPE_MOUSE:
/* controller->mouse_listeners = g_list_append (controller->mouse_listeners,
CORBA_Object_duplicate (l, ev));*/
return retval;
}
+
+static gboolean
+notify_keylisteners (GList *key_listeners, Accessibility_KeyStroke *key_event, CORBA_Environment *ev)
+{
+ int i, n_listeners = g_list_length (key_listeners);
+ gboolean is_consumed = FALSE;
+ for (i=0; i<n_listeners && !is_consumed; ++i)
+ {
+ Accessibility_KeystrokeListener ls;
+ ls = (Accessibility_KeystrokeListener)
+ g_list_nth_data (key_listeners, i);
+ if (!CORBA_Object_is_nil(ls, ev))
+ {
+ is_consumed = Accessibility_KeystrokeListener_keyEvent (ls, key_event, ev);
+ }
+ }
+ return is_consumed;
+}
+
+
static gboolean
_check_key_event (SpiDeviceEventController *controller)
{
gboolean is_consumed = FALSE;
char key_name[16];
int i;
- int n_listeners = g_list_length (controller->key_listeners);
Accessibility_KeyStroke key_event;
static CORBA_Environment ev;
#endif
}
/* relay to listeners, and decide whether to consume it or not */
- for (i=0; i<n_listeners && !is_consumed; ++i)
- {
- Accessibility_KeystrokeListener ls;
- ls = (Accessibility_KeystrokeListener)
- g_list_nth_data (controller->key_listeners, i);
- if (!CORBA_Object_is_nil(ls, &ev))
- {
- is_consumed = Accessibility_KeystrokeListener_keyEvent (ls, &key_event, &ev);
- }
- }
+ is_consumed = notify_keylisteners (controller->key_listeners, &key_event, &ev);
+
if (is_consumed)
{
XAllowEvents (display, SyncKeyboard, CurrentTime);
{
SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
bonobo_object_from_servant (servant));
+ DEControllerKeyListener *dec_listener;
#ifdef SPI_DEBUG
fprintf (stderr, "registering keystroke listener %p with maskVal %lu\n",
(void *) l, (unsigned long) mask->value);
#endif
- /* TODO: change this to an enum, indicating if event is caught at OS level */
- if (is_system_global)
- _controller_register_device_listener(controller, l, DEVICE_TYPE_KBD, keys, mask, ev);
- else
- ; /* register with toolkit instead */
+ dec_listener = dec_key_listener_new (l, keys, mask, type, is_system_global, ev);
+ controller_register_device_listener (controller, (DEControllerListener *) dec_listener, ev);
}
/*
const Accessibility_KeySet *keys,
const Accessibility_ControllerEventMask *mask,
const Accessibility_KeyEventTypeSeq *type,
- const CORBA_boolean is_synchronous,
+ const CORBA_boolean is_system_global,
CORBA_Environment *ev)
{
SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
bonobo_object_from_servant (servant));
+ DEControllerKeyListener *key_listener = dec_key_listener_new (l,
+ keys,
+ mask,
+ type,
+ is_system_global,
+ ev);
#ifdef SPI_DEBUG
fprintf (stderr, "deregistering keystroke listener %p with maskVal %lu\n",
(void *) l, (unsigned long) mask->value);
#endif
- _controller_deregister_device_listener(controller, l, mask, DEVICE_TYPE_KBD, ev);
+ controller_deregister_device_listener(controller,
+ (DEControllerListener *) key_listener,
+ ev);
}
/*
#ifdef SPI_DEBUG
fprintf (stderr, "registering mouse listener %p\n", l);
#endif
- _controller_register_device_listener(controller, DEVICE_TYPE_MOUSE, l, keys, mask, ev);
+ controller_register_device_listener(controller, DEVICE_TYPE_MOUSE, l, keys, mask, ev);
}
*/
ETYPE_PROPERTY,
ETYPE_WINDOW,
ETYPE_TOOLKIT,
+ ETYPE_KEYBOARD,
+
ETYPE_LAST_DEFINED
} EventTypeCategory;
case (ETYPE_TOOLKIT) :
_registry_notify_listeners (registry->toolkit_listeners, e, ev);
break;
+ case (ETYPE_KEYBOARD) :
default:
break;
}
static Window root_window;
typedef enum {
- DEVICE_TYPE_KBD,
- DEVICE_TYPE_MOUSE,
- DEVICE_TYPE_LAST_DEFINED
-} DeviceTypeCategory;
+ SPI_DEVICE_TYPE_KBD,
+ SPI_DEVICE_TYPE_MOUSE,
+ SPI_DEVICE_TYPE_LAST_DEFINED
+} SpiDeviceTypeCategory;
+
+struct _DEControllerListener {
+ CORBA_Object object;
+ SpiDeviceTypeCategory type;
+};
+
+typedef struct _DEControllerListener DEControllerListener;
+
+struct _DEControllerKeyListener {
+ DEControllerListener listener;
+ Accessibility_KeySet *keys;
+ Accessibility_ControllerEventMask *mask;
+ Accessibility_KeyEventTypeSeq *typeseq;
+ gboolean is_system_global;
+};
+
+typedef struct _DEControllerKeyListener DEControllerKeyListener;
static gboolean _controller_register_with_devices (SpiDeviceEventController *controller);
static gboolean _controller_grab_keyboard (SpiDeviceEventController *controller);
-static void _controller_register_device_listener (SpiDeviceEventController *controller,
- const CORBA_Object l,
- DeviceTypeCategory type,
- const Accessibility_KeySet *keys,
- const Accessibility_ControllerEventMask *mask,
- CORBA_Environment *ev);
+static void controller_register_device_listener (SpiDeviceEventController *controller,
+ DEControllerListener *l,
+ CORBA_Environment *ev);
/*
* Private methods
*/
static gint
+_compare_listeners (gconstpointer p1, gconstpointer p2)
+{
+ DEControllerListener *l1 = (DEControllerListener *) p1;
+ DEControllerListener *l2 = (DEControllerListener *) p2;
+ return _compare_corba_objects (l1->object, l2->object);
+}
+
+static gint
_compare_corba_objects (gconstpointer p1, gconstpointer p2)
{
CORBA_Environment ev;
return (gint) d;
}
+static DEControllerKeyListener *
+dec_key_listener_new (CORBA_Object l,
+ const Accessibility_KeySet *keys,
+ const Accessibility_ControllerEventMask *mask,
+ const Accessibility_KeyEventTypeSeq *typeseq,
+ const CORBA_boolean is_system_global,
+ CORBA_Environment *ev)
+{
+ DEControllerKeyListener *key_listener = g_new0 (DEControllerKeyListener, 1);
+ key_listener->listener.object = CORBA_Object_duplicate (l, ev);
+ key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
+ key_listener->keys = keys;
+ key_listener->mask = mask;
+ key_listener->is_system_global = is_system_global;
+
+ return key_listener;
+}
+
static void
-_controller_register_device_listener (SpiDeviceEventController *controller,
- const CORBA_Object l,
- DeviceTypeCategory type,
- const Accessibility_KeySet *keys,
- const Accessibility_ControllerEventMask *mask,
- CORBA_Environment *ev)
+controller_register_device_listener (SpiDeviceEventController *controller,
+ DEControllerListener *listener,
+ CORBA_Environment *ev)
{
Accessibility_ControllerEventMask *mask_ptr = NULL;
+ DEControllerKeyListener *key_listener;
- switch (type) {
- case DEVICE_TYPE_KBD:
- controller->key_listeners = g_list_append (controller->key_listeners,
- CORBA_Object_duplicate (l, ev));
+ switch (listener->type) {
+ case SPI_DEVICE_TYPE_KBD:
+ key_listener = (DEControllerKeyListener *) listener;
+ controller->key_listeners = g_list_append (controller->key_listeners, key_listener);
mask_ptr = (Accessibility_ControllerEventMask *)
- g_list_find_custom (controller->keymask_list, (gpointer) mask,
+ g_list_find_custom (controller->keymask_list, (gpointer) key_listener->mask,
_eventmask_compare_value);
if (mask_ptr)
++(mask_ptr->refcount);
else
{
- if (mask->refcount != (CORBA_unsigned_short) 1)
+ if (key_listener->mask->refcount != (CORBA_unsigned_short) 1)
fprintf (stderr, "mask initial refcount is not 1!\n");
- if (mask->value > (CORBA_unsigned_long) 2048)
+ if (key_listener->mask->value > (CORBA_unsigned_long) 2048)
fprintf (stderr, "mask value looks invalid (%lu)\n",
- (unsigned long) mask->value);
+ (unsigned long) key_listener->mask->value);
else
fprintf (stderr, "appending mask with val=%lu\n",
- (unsigned long) mask->value);
+ (unsigned long) key_listener->mask->value);
mask_ptr = Accessibility_ControllerEventMask__alloc();
- mask_ptr->value = mask->value;
+ mask_ptr->value = key_listener->mask->value;
mask_ptr->refcount = (CORBA_unsigned_short) 1;
controller->keymask_list = g_list_append (controller->keymask_list,
(gpointer) mask_ptr);
}
break;
- case DEVICE_TYPE_MOUSE:
+ case SPI_DEVICE_TYPE_MOUSE:
/* controller->mouse_listeners = g_list_append (controller->mouse_listeners,
CORBA_Object_duplicate (l, ev));*/
}
static void
-_controller_deregister_device_listener (SpiDeviceEventController *controller,
- const CORBA_Object l,
- const Accessibility_ControllerEventMask *mask,
- DeviceTypeCategory type,
- CORBA_Environment *ev)
+controller_deregister_device_listener (SpiDeviceEventController *controller,
+ DEControllerListener *listener,
+ CORBA_Environment *ev)
{
Accessibility_ControllerEventMask *mask_ptr;
+ DEControllerKeyListener *key_listener;
GList *list_ptr;
- switch (type) {
- case DEVICE_TYPE_KBD:
- list_ptr = g_list_find_custom (controller->key_listeners, l, _compare_corba_objects);
+ switch (listener->type) {
+ case SPI_DEVICE_TYPE_KBD:
+ key_listener = (DEControllerKeyListener *) listener;
+ list_ptr = g_list_find_custom (controller->key_listeners, listener, _compare_listeners);
+ /* TODO: need a different custom compare func */
if (list_ptr)
controller->key_listeners = g_list_remove (controller->key_listeners, list_ptr);
list_ptr = (GList *)
- g_list_find_custom (controller->keymask_list, (gpointer) mask,
+ g_list_find_custom (controller->keymask_list, (gpointer) key_listener->mask,
_eventmask_compare_value);
if (list_ptr)
{
}
}
break;
- case DEVICE_TYPE_MOUSE:
+ case SPI_DEVICE_TYPE_MOUSE:
/* controller->mouse_listeners = g_list_append (controller->mouse_listeners,
CORBA_Object_duplicate (l, ev));*/
return retval;
}
+
+static gboolean
+notify_keylisteners (GList *key_listeners, Accessibility_KeyStroke *key_event, CORBA_Environment *ev)
+{
+ int i, n_listeners = g_list_length (key_listeners);
+ gboolean is_consumed = FALSE;
+ for (i=0; i<n_listeners && !is_consumed; ++i)
+ {
+ Accessibility_KeystrokeListener ls;
+ ls = (Accessibility_KeystrokeListener)
+ g_list_nth_data (key_listeners, i);
+ if (!CORBA_Object_is_nil(ls, ev))
+ {
+ is_consumed = Accessibility_KeystrokeListener_keyEvent (ls, key_event, ev);
+ }
+ }
+ return is_consumed;
+}
+
+
static gboolean
_check_key_event (SpiDeviceEventController *controller)
{
gboolean is_consumed = FALSE;
char key_name[16];
int i;
- int n_listeners = g_list_length (controller->key_listeners);
Accessibility_KeyStroke key_event;
static CORBA_Environment ev;
#endif
}
/* relay to listeners, and decide whether to consume it or not */
- for (i=0; i<n_listeners && !is_consumed; ++i)
- {
- Accessibility_KeystrokeListener ls;
- ls = (Accessibility_KeystrokeListener)
- g_list_nth_data (controller->key_listeners, i);
- if (!CORBA_Object_is_nil(ls, &ev))
- {
- is_consumed = Accessibility_KeystrokeListener_keyEvent (ls, &key_event, &ev);
- }
- }
+ is_consumed = notify_keylisteners (controller->key_listeners, &key_event, &ev);
+
if (is_consumed)
{
XAllowEvents (display, SyncKeyboard, CurrentTime);
{
SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
bonobo_object_from_servant (servant));
+ DEControllerKeyListener *dec_listener;
#ifdef SPI_DEBUG
fprintf (stderr, "registering keystroke listener %p with maskVal %lu\n",
(void *) l, (unsigned long) mask->value);
#endif
- /* TODO: change this to an enum, indicating if event is caught at OS level */
- if (is_system_global)
- _controller_register_device_listener(controller, l, DEVICE_TYPE_KBD, keys, mask, ev);
- else
- ; /* register with toolkit instead */
+ dec_listener = dec_key_listener_new (l, keys, mask, type, is_system_global, ev);
+ controller_register_device_listener (controller, (DEControllerListener *) dec_listener, ev);
}
/*
const Accessibility_KeySet *keys,
const Accessibility_ControllerEventMask *mask,
const Accessibility_KeyEventTypeSeq *type,
- const CORBA_boolean is_synchronous,
+ const CORBA_boolean is_system_global,
CORBA_Environment *ev)
{
SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
bonobo_object_from_servant (servant));
+ DEControllerKeyListener *key_listener = dec_key_listener_new (l,
+ keys,
+ mask,
+ type,
+ is_system_global,
+ ev);
#ifdef SPI_DEBUG
fprintf (stderr, "deregistering keystroke listener %p with maskVal %lu\n",
(void *) l, (unsigned long) mask->value);
#endif
- _controller_deregister_device_listener(controller, l, mask, DEVICE_TYPE_KBD, ev);
+ controller_deregister_device_listener(controller,
+ (DEControllerListener *) key_listener,
+ ev);
}
/*
#ifdef SPI_DEBUG
fprintf (stderr, "registering mouse listener %p\n", l);
#endif
- _controller_register_device_listener(controller, DEVICE_TYPE_MOUSE, l, keys, mask, ev);
+ controller_register_device_listener(controller, DEVICE_TYPE_MOUSE, l, keys, mask, ev);
}
*/
ETYPE_PROPERTY,
ETYPE_WINDOW,
ETYPE_TOOLKIT,
+ ETYPE_KEYBOARD,
+
ETYPE_LAST_DEFINED
} EventTypeCategory;
case (ETYPE_TOOLKIT) :
_registry_notify_listeners (registry->toolkit_listeners, e, ev);
break;
+ case (ETYPE_KEYBOARD) :
default:
break;
}