+
+ spi_re_entrant_list_foreach (list, notify_listeners_cb, ctx);
+ }
+}
+
+static NotifyContext*
+registry_clone_notify_context (NotifyContext *ctx)
+{
+ NotifyContext *new_ctx = g_new0 (NotifyContext, 1);
+
+ new_ctx->ev = NULL;
+ new_ctx->source = bonobo_object_dup_ref (ctx->source, NULL);
+ new_ctx->etype.event_name = CORBA_string_dup (ctx->etype.event_name);
+ new_ctx->etype.type_cat = ctx->etype.type_cat;
+ new_ctx->etype.major = ctx->etype.major;
+ new_ctx->etype.minor = ctx->etype.minor;
+ new_ctx->etype.detail = ctx->etype.detail;
+ new_ctx->e_out.type = CORBA_string_dup (ctx->e_out.type);
+ new_ctx->e_out.source = ctx->e_out.source;
+ new_ctx->e_out.detail1 = ctx->e_out.detail1;
+ new_ctx->e_out.detail2 = ctx->e_out.detail2;
+ CORBA_any__copy (&(new_ctx->e_out.any_data), &(ctx->e_out.any_data));
+ return new_ctx;
+}
+
+static void
+registry_flush_event_queue (SpiRegistry *registry,
+ gboolean discard,
+ CORBA_Environment *ev)
+{
+ NotifyContext *q_ctx;
+ while (!g_queue_is_empty (registry->deferred_event_queue)) {
+ q_ctx = g_queue_pop_tail (registry->deferred_event_queue);
+#ifdef SPI_QUEUE_DEBUG
+ fprintf (stderr, "%s! %s [n=%d] %p\n", (discard ? "discard" : "pop"),
+ q_ctx->etype.event_name,
+ (int) registry->deferred_event_queue->length, q_ctx);
+#endif
+ if (!discard) {
+ q_ctx->ev = ev;
+ registry_emit_event (registry, q_ctx);
+ }
+ if (discard &&
+ (q_ctx->etype.type_cat == ETYPE_OBJECT) &&
+ (q_ctx->etype.major == _state_quark) &&
+ (q_ctx->etype.minor == _state_changed_focused_quark)) {
+ registry->focus_object = q_ctx->source;
+#ifdef SPI_QUEUE_DEBUG
+ fprintf (stderr, "discard!: set focus_object %p\n", registry->focus_object);
+#endif
+ }
+ else {
+ bonobo_object_release_unref (q_ctx->source, NULL);
+ }
+ CORBA_free ((void *)q_ctx->etype.event_name);
+ CORBA_free ((void *)q_ctx->e_out.type);
+ g_free (q_ctx);
+ }
+ registry->is_queueing = FALSE;
+}
+
+static gboolean
+registry_timeout_flush_queue (gpointer data)
+{
+ SpiRegistry *registry = data;
+ CORBA_Environment ev;
+#ifdef SPI_QUEUE_DEBUG
+ fprintf (stderr, "timeout! flushing queue...\n");
+#endif
+ CORBA_exception_init (&ev);
+ registry->queue_handler_id = 0;
+ registry_flush_event_queue (registry, FALSE, &ev);
+ return FALSE;
+}
+
+static gboolean
+registry_discard_on_event (SpiRegistry *registry, NotifyContext *ctx)
+{
+ gboolean retval = FALSE;
+ NotifyContext *q_ctx = g_queue_peek_tail (registry->deferred_event_queue);
+ if ((q_ctx != NULL) &&
+ (ctx->etype.type_cat == ETYPE_WINDOW) &&
+ (ctx->etype.major == _activate_quark)) {
+ if (CORBA_Object_is_equivalent (ctx->source, q_ctx->source, NULL)) {
+ retval = TRUE;
+ }
+ }
+ return retval;
+}
+
+static gboolean
+registry_reset_on_event (SpiRegistry *registry, NotifyContext *ctx)
+{
+ return (ctx->etype.type_cat == ETYPE_WINDOW) ? TRUE : FALSE;
+}
+
+#ifdef SPI_QUEUE_DEBUG
+#include <sys/time.h>
+#endif
+
+static void
+registry_start_queue (SpiRegistry *registry)
+{
+#ifdef SPI_QUEUE_DEBUG
+ struct timeval tp;
+ gettimeofday (&tp, NULL);
+ fprintf (stderr, "start queueing at %i.%.6i\n", tp.tv_sec, tp.tv_usec);
+#endif
+ if (registry->queue_handler_id != 0)
+ g_source_remove (registry->queue_handler_id);
+
+ if (registry->focus_object)
+ {
+#ifdef SPI_QUEUE_DEBUG
+ fprintf (stderr, "registry_start_queue: release focus_object %p\n", registry->focus_object);