2002-01-16 Bill Haneman <bill.haneman@sun.com>
+ * registryd/deviceeventcontroller.c:
+ Regression fix for keylistener de-registration; global keygrabs
+ were not being released when deregisterKeystrokeListener was
+ called in cspi, since
+ Accessibility_DeviceEventController_deregisterKeystrokeListener
+ was called with a zero-length keyset. That is because the cspi
+ method, SPI_deregisterKeystrokeListener, does not take a keyset
+ parameter but instead should remove all the key grabs held be a
+ keystroke listener.
+ The code in impl_deregister_keystroke_listener was changed to copy
+ the keylist from the listener instance previously registered with
+ the DeviceEventController before releasing the grabs.
+
+ * registryd/registry.c:
+ * registryd/deviceeventcontroller.c:
+ * libspi/spi-private.h:
+ * libspi/util.c:
+ Changed spelling of "re-enterant" to "re-entrant" globally.
+
+2002-01-16 Bill Haneman <bill.haneman@sun.com>
+
* test/test-simple.c:
Changed key listeners test - the test was slightly mis-using the
(admittedly poorly documented) SPI_generateKeyboardEvent API.
**/
SPIBoolean
SPI_deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
- AccessibleKeyMaskType modmask)
+ AccessibleKeyMaskType modmask)
{
Accessibility_ControllerEventMask controller_event_mask;
Accessibility_KeySet key_set;
G_BEGIN_DECLS
typedef enum {
- SPI_RE_ENTERANT_CONTINUE = 0,
- SPI_RE_ENTERANT_TERMINATE
-} SpiReEnterantContinue;
+ SPI_RE_ENTRANT_CONTINUE = 0,
+ SPI_RE_ENTRANT_TERMINATE
+} SpiReEntrantContinue;
-typedef SpiReEnterantContinue (*SpiReEnterantFn) (GList * const *list,
- gpointer user_data);
+typedef SpiReEntrantContinue (*SpiReEntrantFn) (GList * const *list,
+ gpointer user_data);
-void spi_re_enterant_list_delete_link (GList * const *element_ptr);
-void spi_re_enterant_list_foreach (GList **list,
- SpiReEnterantFn func,
- 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
static GSList *working_list = NULL; /* of Iteration */
/*
- * deletes an element from the list - in a re-enterant
+ * deletes an element from the list - in a re-entrant
* safe fashion; advances the element pointer to the next
* element.
*/
void
-spi_re_enterant_list_delete_link (GList * const *element_ptr)
+spi_re_entrant_list_delete_link (GList * const *element_ptr)
{
GSList *l;
GList *next;
}
void
-spi_re_enterant_list_foreach (GList **list,
- SpiReEnterantFn func,
- gpointer user_data)
+spi_re_entrant_list_foreach (GList **list,
+ SpiReEntrantFn func,
+ gpointer user_data)
{
Iteration i;
DEControllerKeyListener *key_listener;
} RemoveKeyListenerClosure;
-static SpiReEnterantContinue
+static SpiReEntrantContinue
remove_key_listener_cb (GList * const *list,
gpointer user_data)
{
if (CORBA_Object_is_equivalent (ctx->key_listener->listener.object,
key_listener->listener.object, ctx->ev))
{
- spi_re_enterant_list_delete_link (list);
+ spi_re_entrant_list_delete_link (list);
spi_dec_key_listener_free (key_listener, ctx->ev);
}
- return SPI_RE_ENTERANT_CONTINUE;
+ return SPI_RE_ENTRANT_CONTINUE;
+}
+
+static SpiReEntrantContinue
+copy_key_listener_cb (GList * const *list,
+ gpointer user_data)
+{
+ DEControllerKeyListener *key_listener = (*list)->data;
+ RemoveKeyListenerClosure *ctx = user_data;
+
+ if (CORBA_Object_is_equivalent (ctx->key_listener->listener.object,
+ key_listener->listener.object, ctx->ev))
+ {
+ /* TODO: FIXME aggregate keys in case the listener is registered twice */
+ CORBA_free (ctx->key_listener->keys);
+ ctx->key_listener->keys = ORBit_copy_value (key_listener->keys, TC_Accessibility_KeySet);
+ }
+
+ return SPI_RE_ENTRANT_CONTINUE;
}
/*
(void *) l, (unsigned long) mask->value);
#endif
- spi_controller_deregister_global_keygrabs (controller, key_listener);
-
ctx.ev = ev;
ctx.key_listener = key_listener;
- spi_re_enterant_list_foreach (&controller->key_listeners,
+ /* special case, copy keyset from existing controller list entry */
+ if (keys->_length == 0)
+ {
+ spi_re_entrant_list_foreach (&controller->key_listeners,
+ copy_key_listener_cb, &ctx);
+ }
+
+ spi_controller_deregister_global_keygrabs (controller, key_listener);
+
+ spi_re_entrant_list_foreach (&controller->key_listeners,
remove_key_listener_cb, &ctx);
spi_dec_key_listener_free (key_listener, ev);
}
}
-static SpiReEnterantContinue
+static SpiReEntrantContinue
remove_listener_cb (GList * const *list, gpointer user_data)
{
SpiListenerStruct *ls = (SpiListenerStruct *) (*list)->data;
if (CORBA_Object_is_equivalent (ls->listener, listener, &ev))
{
- spi_re_enterant_list_delete_link (list);
+ spi_re_entrant_list_delete_link (list);
spi_listener_struct_free (ls, &ev);
}
CORBA_exception_free (&ev);
- return SPI_RE_ENTERANT_CONTINUE;
+ return SPI_RE_ENTRANT_CONTINUE;
}
/*
for (i = 0; i < sizeof (lists) / sizeof (lists[0]); i++)
{
- spi_re_enterant_list_foreach (lists [i], remove_listener_cb, listener);
+ spi_re_entrant_list_foreach (lists [i], remove_listener_cb, listener);
}
}
parse_event_type (&etype, (char *) event_name);
- spi_re_enterant_list_foreach (get_listener_list (registry, etype.type_cat),
+ spi_re_entrant_list_foreach (get_listener_list (registry, etype.type_cat),
remove_listener_cb, listener);
}
Accessibility_Event e_out;
} NotifyContext;
-static SpiReEnterantContinue
+static SpiReEntrantContinue
notify_listeners_cb (GList * const *list, gpointer user_data)
{
SpiListenerStruct *ls;
ctx->e_out.source = bonobo_object_dup_ref (ctx->source, ctx->ev);
if (BONOBO_EX (ctx->ev))
{
- return SPI_RE_ENTERANT_CONTINUE;;
+ return SPI_RE_ENTRANT_CONTINUE;;
}
if ((*list) && (*list)->data == ls)
}
}
- return SPI_RE_ENTERANT_CONTINUE;
+ return SPI_RE_ENTRANT_CONTINUE;
}
static void
ctx.source = e->source;
parse_event_type (&ctx.etype, e->type);
- spi_re_enterant_list_foreach (list, notify_listeners_cb, &ctx);
+ spi_re_entrant_list_foreach (list, notify_listeners_cb, &ctx);
}
if (e->source != CORBA_OBJECT_NIL)