2001-21-11 Bill Haneman <bill.haneman@sun.com>
+ * libspi/deviceeventcontroller.c:
+ * libspi/keystrokelistener.c:
+ * cspi/spi_event.c:
+ * cspi/spi_registry.c:
+ Added filters for KeySets, KeyEventSeq, and event types to key
+ event dispatching, so listeners should only receive those events
+ that they requested :-)
+
+2001-21-11 Bill Haneman <bill.haneman@sun.com>
+
* configure.in:
* docs/Makefile.am:
* docs/reference:
SPI_COORD_TYPE_WINDOW
} AccessibleCoordType;
+/* XXX: must be single bits since they are used as masks in keylistener API */
typedef enum {
- SPI_KEY_PRESSED,
- SPI_KEY_RELEASED
+ SPI_KEY_PRESSED = 1,
+ SPI_KEY_RELEASED = 2
} AccessibleKeyEventType;
typedef enum {
AccessibleKeystrokeListener_removeCallback (AccessibleKeystrokeListener *listener,
AccessibleKeystrokeListenerCB callback)
{
- keystroke_listener_remove_callback (listener, callback);
+ spi_keystroke_listener_remove_callback (listener, callback);
return TRUE;
}
Accessibility_ControllerEventMask__alloc();
Accessibility_DeviceEventController device_event_controller =
Accessibility_Registry_getDeviceEventController (registry, &ev);
- Accessibility_KeySet *all_keys = Accessibility_KeySet__alloc();
+ Accessibility_KeySet *key_set = Accessibility_KeySet__alloc();
Accessibility_KeyEventTypeSeq *key_events = Accessibility_KeyEventTypeSeq__alloc();
Accessibility_KeystrokeListener spi_listener_corba_ref;
+ gint i, mask;
Accessibility_DeviceEventController_ref (device_event_controller, &ev);
+
+ /* copy the keyval filter values from the C api into the CORBA KeySet */
+ if (keys)
+ {
+ key_set->_buffer = Accessibility_KeySet_allocbuf (
+ (unsigned long) keys->len);
+ key_set->_length = (unsigned long) keys->len;
+ for (i=0; i < key_set->_length; ++i)
+ {
+ /* we overload the keyset long w/keycodes, the - bit acts as a flag */
+ key_set->_buffer[i] = (keys->keysyms[i]) ? keys->keysyms[i] :
+ -keys->keycodes[i];
+ }
+ }
+ /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
+ mask=1;
+ i=0;
+ do
+ {
+ if (mask & eventmask) ++i;
+ mask <<= 1;
+ } while (mask & 0xFFFF);
+
+ key_events->_buffer = Accessibility_KeyEventTypeSeq_allocbuf (i);
+ i=0;
+ if (eventmask & SPI_KEY_PRESSED)
+ {
+ key_events->_buffer[i++] = Accessibility_KEY_PRESSED;
+ }
+ if (eventmask & SPI_KEY_RELEASED)
+ {
+ key_events->_buffer[i++] = Accessibility_KEY_RELEASED;
+ }
+ key_events->_length = i;
+
controller_event_mask->value = (CORBA_unsigned_long) modmask;
controller_event_mask->refcount = (CORBA_unsigned_short) 1;
Accessibility_DeviceEventController_registerKeystrokeListener (
device_event_controller,
spi_listener_corba_ref,
- all_keys,
+ key_set,
controller_event_mask,
key_events,
(CORBA_boolean) ((sync_type | SPI_KEYLISTENER_ALL_WINDOWS)!=0),
key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
key_listener->keys = ORBit_copy_value (keys, TC_Accessibility_KeySet);
key_listener->mask = ORBit_copy_value (mask, TC_Accessibility_ControllerEventMask);
+ key_listener->typeseq = ORBit_copy_value (typeseq, TC_Accessibility_KeyEventTypeSeq);
key_listener->is_system_global = is_system_global;
+#ifdef SPI_DEBUG
g_print ("new listener, with mask %x, is_global %d, keys %p\n",
(unsigned int) key_listener->mask->value,
(int) key_listener->is_system_global,
(void *) key_listener->keys);
-
+#endif
return key_listener;
}
return retval;
}
+static gboolean
+key_set_contains_key (Accessibility_KeySet *key_set, Accessibility_KeyStroke *key_event)
+{
+ gint i;
+ gint len;
+
+ /* g_assert (key_set); */
+ if (!key_set) { g_print ("null key set!"); return TRUE; }
+
+ len = key_set->_length;
+
+ if (len == 0) /* special case, means "all keys/any key" */
+ {
+ return TRUE;
+ }
+
+ for (i=0; i<len; ++i)
+ {
+ g_print ("key_set[%d] = %d\n", i, (int) key_set->_buffer[i]);
+ if (key_set->_buffer[i] == (CORBA_long) key_event->keyID) return TRUE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+key_eventtype_seq_contains_event (Accessibility_KeyEventTypeSeq *type_seq,
+ Accessibility_KeyStroke *key_event)
+{
+ gint i;
+ gint len;
+
+ /* g_assert (type_seq); */
+ if (!type_seq) { g_print ("null type seq!"); return TRUE; }
+
+ len = type_seq->_length;
+
+ if (len == 0) /* special case, means "all events/any event" */
+ {
+ return TRUE;
+ }
+
+ for (i=0; i<len; ++i)
+ {
+ g_print ("type_seq[%d] = %d\n", i, (int) type_seq->_buffer[i]);
+ if (type_seq->_buffer[i] == (CORBA_long) key_event->type) return TRUE;
+ }
+
+ return TRUE;
+}
static gboolean
key_event_matches_listener (Accessibility_KeyStroke *key_event,
DEControllerKeyListener *listener,
CORBA_boolean is_system_global)
{
- g_print ("mask=%x, listener mask= %x\n", (unsigned int) key_event->modifiers,
- (unsigned int) (listener->mask->value & 0xFFFF));
- if ((key_event->modifiers == (CORBA_unsigned_short) (listener->mask->value && 0xFFFF)) &&
- ((listener->keys == NULL) || (1)) && /* in keyset seq */
- (1) && /* in event type seq */
+ if ((key_event->modifiers == (CORBA_unsigned_short) (listener->mask->value & 0xFFFF)) &&
+ key_set_contains_key (listener->keys, key_event) &&
+ key_eventtype_seq_contains_event (listener->typeseq, key_event) &&
(is_system_global == listener->is_system_global))
{
return TRUE;
#endif
}
-void keystroke_listener_remove_callback (SpiKeystrokeListener *listener,
- BooleanKeystrokeListenerCB callback)
+void spi_keystroke_listener_remove_callback (SpiKeystrokeListener *listener,
+ BooleanKeystrokeListenerCB callback)
{
listener->callbacks = g_list_remove (listener->callbacks, callback);
}
(char) toupper((int) key->keyID) : (char) tolower((int) key->keyID));
}
#endif
+ /* TODO: convert from the CORBA-based struct to a c-type-based one ? */
+ fprintf (stderr, "Key:\tsym %ld\n\tmods %x\n\tcode %d\n\ttime %ld\n",
+ (long) key->keyID,
+ (unsigned int) key->modifiers,
+ (int) key->keycode,
+ (long int) key->timestamp);
+
while (callbacks)
{
BooleanKeystrokeListenerCB cb = (BooleanKeystrokeListenerCB) callbacks->data;
key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
key_listener->keys = ORBit_copy_value (keys, TC_Accessibility_KeySet);
key_listener->mask = ORBit_copy_value (mask, TC_Accessibility_ControllerEventMask);
+ key_listener->typeseq = ORBit_copy_value (typeseq, TC_Accessibility_KeyEventTypeSeq);
key_listener->is_system_global = is_system_global;
+#ifdef SPI_DEBUG
g_print ("new listener, with mask %x, is_global %d, keys %p\n",
(unsigned int) key_listener->mask->value,
(int) key_listener->is_system_global,
(void *) key_listener->keys);
-
+#endif
return key_listener;
}
return retval;
}
+static gboolean
+key_set_contains_key (Accessibility_KeySet *key_set, Accessibility_KeyStroke *key_event)
+{
+ gint i;
+ gint len;
+
+ /* g_assert (key_set); */
+ if (!key_set) { g_print ("null key set!"); return TRUE; }
+
+ len = key_set->_length;
+
+ if (len == 0) /* special case, means "all keys/any key" */
+ {
+ return TRUE;
+ }
+
+ for (i=0; i<len; ++i)
+ {
+ g_print ("key_set[%d] = %d\n", i, (int) key_set->_buffer[i]);
+ if (key_set->_buffer[i] == (CORBA_long) key_event->keyID) return TRUE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+key_eventtype_seq_contains_event (Accessibility_KeyEventTypeSeq *type_seq,
+ Accessibility_KeyStroke *key_event)
+{
+ gint i;
+ gint len;
+
+ /* g_assert (type_seq); */
+ if (!type_seq) { g_print ("null type seq!"); return TRUE; }
+
+ len = type_seq->_length;
+
+ if (len == 0) /* special case, means "all events/any event" */
+ {
+ return TRUE;
+ }
+
+ for (i=0; i<len; ++i)
+ {
+ g_print ("type_seq[%d] = %d\n", i, (int) type_seq->_buffer[i]);
+ if (type_seq->_buffer[i] == (CORBA_long) key_event->type) return TRUE;
+ }
+
+ return TRUE;
+}
static gboolean
key_event_matches_listener (Accessibility_KeyStroke *key_event,
DEControllerKeyListener *listener,
CORBA_boolean is_system_global)
{
- g_print ("mask=%x, listener mask= %x\n", (unsigned int) key_event->modifiers,
- (unsigned int) (listener->mask->value & 0xFFFF));
- if ((key_event->modifiers == (CORBA_unsigned_short) (listener->mask->value && 0xFFFF)) &&
- ((listener->keys == NULL) || (1)) && /* in keyset seq */
- (1) && /* in event type seq */
+ if ((key_event->modifiers == (CORBA_unsigned_short) (listener->mask->value & 0xFFFF)) &&
+ key_set_contains_key (listener->keys, key_event) &&
+ key_eventtype_seq_contains_event (listener->typeseq, key_event) &&
(is_system_global == listener->is_system_global))
{
return TRUE;