From 92458bbffd350b574b27f64a315653c94d847dcf Mon Sep 17 00:00:00 2001 From: billh Date: Thu, 21 Nov 2002 18:49:40 +0000 Subject: [PATCH] Revised recent patch, cleaned up internal APIs. Provide event-type specific APIs for getting text-change string and child-changed objects. git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@368 e2bd861d-eb25-0410-b326-f6ed22b6b98c --- atk-bridge/bridge.c | 231 +++++++++++++++++++-------------------------- cspi/spi.h | 4 +- cspi/spi_event.c | 87 ++++++++--------- registryd/registry.c | 6 +- test/event-listener-test.c | 2 +- 5 files changed, 146 insertions(+), 184 deletions(-) diff --git a/atk-bridge/bridge.c b/atk-bridge/bridge.c index dfb8d4f..d45f463 100644 --- a/atk-bridge/bridge.c +++ b/atk-bridge/bridge.c @@ -39,7 +39,8 @@ #define DBG(a,b) if(_dbg>=(a))b -static int _dbg; +static int _dbg = 0; +static char *spi_nil_string = ""; static CORBA_Environment ev; static Accessibility_Registry registry = NULL; @@ -72,25 +73,6 @@ static guint atk_signal_child_changed; static guint atk_signal_column_deleted; */ -#define ATK_BRIDGE_RESERVED_CONTEXT_SIZE 16 - -typedef enum { - ATK_BRIDGE_CONTEXT_TYPE_NONE = 0, - ATK_BRIDGE_CONTEXT_TYPE_STRING, - ATK_BRIDGE_CONTEXT_TYPE_OBJECT -} AtkBridgeEventContextType; - -typedef union { - gchar *string; - AtkObject *object; - gpointer *foo; -} AtkBridgeEventContextData; - -typedef struct { - AtkBridgeEventContextType _type; - AtkBridgeEventContextData _data; -} AtkBridgeEventContext; - static Accessibility_Registry spi_atk_bridge_get_registry (void); static void spi_atk_bridge_do_registration (void); static void spi_atk_bridge_toplevel_added (AtkObject *object, @@ -139,7 +121,7 @@ extern void gnome_accessibility_module_init (void); extern void gnome_accessibility_module_shutdown (void); static void -atk_bridge_init_event_type_consts () +spi_atk_bridge_init_event_type_consts () { atk_signal_child_changed = g_signal_lookup ("child_changed", ATK_TYPE_OBJECT); @@ -150,13 +132,16 @@ atk_bridge_init_event_type_consts () static int atk_bridge_init (gint *argc, gchar **argv[]) { + const char *debug_env_string = g_getenv ("AT_SPI_DEBUG"); + if (atk_bridge_initialized) { return 0; } atk_bridge_initialized = TRUE; - _dbg = g_ascii_digit_value (g_getenv ("AT_SPI_DEBUG")); + if (debug_env_string) + _dbg = (int) g_ascii_strtod (debug_env_string, NULL); if (!bonobo_init (argc, argv ? *argv : NULL)) { @@ -182,11 +167,12 @@ atk_bridge_init (gint *argc, gchar **argv[]) spi_atk_bridge_do_registration (); } - atk_bridge_init_event_type_consts (); + spi_atk_bridge_init_event_type_consts (); return 0; } + static void spi_atk_bridge_do_registration (void) { @@ -433,34 +419,6 @@ gnome_accessibility_module_shutdown (void) } static void -atk_bridge_event_context_init (CORBA_any *any, - AtkBridgeEventContext *ctx) -{ - SpiAccessible *accessible; - if (ctx) - { - switch (ctx->_type) - { - /* FIXME - case ATK_BRIDGE_CONTEXT_TYPE_OBJECT: - accessible = spi_accessible_new (ctx->_data.object); - spi_init_any_object (any, BONOBO_OBJREF (accessible)); - break; - */ - case ATK_BRIDGE_CONTEXT_TYPE_STRING: - spi_init_any_string (any, &ctx->_data.string); - break; - default: - spi_init_any_nil (any); - } - } - else - { - spi_init_any_nil (any); - } -} - -static void spi_atk_bridge_focus_tracker (AtkObject *object) { SpiAccessible *source; @@ -481,50 +439,12 @@ spi_atk_bridge_focus_tracker (AtkObject *object) CORBA_exception_free (&ev); } -static -AtkBridgeEventContext * -spi_atk_bridge_event_context_create (GObject *gobject, - long detail1, - long detail2, - GSignalQuery *signal_query, - const gchar *detail) -{ - AtkBridgeEventContext *ctx = g_new0 (AtkBridgeEventContext, 1); - /* - if (signal_query->signal_id == atk_signal_child_changed) - { - ctx->_type = ATK_BRIDGE_CONTEXT_TYPE_OBJECT; - ctx->_data.object = atk_object_ref_accessible_child (ATK_OBJECT (gobject), - (gint) detail1); - } - else */ if (signal_query->signal_id == atk_signal_text_changed) - { - ctx->_type = ATK_BRIDGE_CONTEXT_TYPE_STRING; - ctx->_data.string = atk_text_get_text (ATK_TEXT (gobject), - (gint) detail1, - (gint) detail1+detail2); - } - else - { - ctx->_type = ATK_BRIDGE_CONTEXT_TYPE_NONE; - } - return ctx; -} - -static void -spi_atk_bridge_event_context_free (AtkBridgeEventContext *ctx) -{ - if (ctx->_type == ATK_BRIDGE_CONTEXT_TYPE_OBJECT) - g_object_unref (ctx->_data.object); - g_free (ctx); -} - static void -spi_atk_emit_eventv (GObject *gobject, - unsigned long detail1, - unsigned long detail2, - AtkBridgeEventContext *context, - const char *format, ...) +spi_atk_emit_eventv (const GObject *gobject, + long detail1, + long detail2, + CORBA_any *any, + const char *format, ...) { va_list args; Accessibility_Event e; @@ -551,15 +471,18 @@ spi_atk_emit_eventv (GObject *gobject, { aobject = NULL; source = NULL; - g_error ("received property-change event from non-AtkImplementor"); + DBG (0, g_warning ("received property-change event from non-AtkImplementor")); } - if (source != NULL) + if (source) { e.type = g_strdup_vprintf (format, args); e.source = BONOBO_OBJREF (source); e.detail1 = detail1; e.detail2 = detail2; + if (any) e.any_data = *any; + else spi_init_any_nil (&e.any_data); + #ifdef SPI_BRIDGE_DEBUG s = Accessibility_Accessible__get_name (BONOBO_OBJREF (source), &ev); g_warning ("Emitting event '%s' (%lu, %lu) on %s", @@ -567,21 +490,20 @@ spi_atk_emit_eventv (GObject *gobject, CORBA_free (s); #endif CORBA_exception_init (&ev); - atk_bridge_event_context_init (&e.any_data, context); - Accessibility_Registry_notifyEvent (spi_atk_bridge_get_registry (), &e, &ev); - /* I haven't freed any_data._value when it's a char*, does it leak ? */ + Accessibility_Registry_notifyEvent (spi_atk_bridge_get_registry (), + &e, &ev); #ifdef SPI_BRIDGE_DEBUG if (ev._major != CORBA_NO_EXCEPTION) - g_warning ("error emitting event %s, (%d) %s", - e.type, - ev._major, - CORBA_exception_id(&ev)); + g_warning ("error emitting event %s, (%d) %s", + e.type, + ev._major, + CORBA_exception_id(&ev)); #endif if (BONOBO_EX (&ev)) registry_died = TRUE; Accessibility_Accessible_unref (e.source, &ev); - + CORBA_exception_free (&ev); - + g_free (e.type); } @@ -745,6 +667,57 @@ spi_atk_bridge_key_listener (AtkKeyEventStruct *event, gpointer data) return result; } + +static void +spi_atk_signal_emit_event (const GObject *gobject, + const GSignalQuery *signal_query, + long detail1, + long detail2, + const gchar *name, + const gchar *detail) +{ + CORBA_any any; + CORBA_char *sp = NULL; + AtkObject *ao; + + if (signal_query->signal_id == atk_signal_text_changed) + { + sp = atk_text_get_text (ATK_TEXT (gobject), + detail1, + detail1+detail2); + spi_init_any_string (&any, &sp); + } +#ifdef EXTENDED_OBJECT_EVENTS_ARE_WORKING + else if ((signal_query->signal_id == atk_signal_child_changed) && gobject) + { + ao = atk_object_ref_accessible_child (ATK_OBJECT (gobject), + detail1); + if (ao) + { + spi_init_any_object (&any, ao); + atk_object_unref (ao); + } + else + { + spi_init_any_nil (&any); + } + } +#endif + else + { + spi_init_any_nil (&any); + } + + if (detail) + spi_atk_emit_eventv (gobject, detail1, detail2, &any, + "object:%s:%s", name, detail); + else + spi_atk_emit_eventv (gobject, detail1, detail2, &any, + "object:%s", name); +} + + + static gboolean spi_atk_bridge_signal_listener (GSignalInvocationHint *signal_hint, guint n_param_values, @@ -755,12 +728,12 @@ spi_atk_bridge_signal_listener (GSignalInvocationHint *signal_hint, GSignalQuery signal_query; const gchar *name; const gchar *detail; - AtkBridgeEventContext *ctx = NULL; + CORBA_char *sp; gint detail1 = 0, detail2 = 0; #ifdef SPI_BRIDGE_DEBUG const gchar *s, *s2; -#endif +#endif g_signal_query (signal_hint->signal_id, &signal_query); @@ -775,44 +748,30 @@ spi_atk_bridge_signal_listener (GSignalInvocationHint *signal_hint, s = atk_object_get_name (ATK_OBJECT (g_value_get_object (param_values + 0))); fprintf (stderr, "Received signal %s:%s detail: %s from object %s (gail %s)\n", g_type_name (signal_query.itype), name, - detail ? detail : "", s ? s : "" , s2); + detail ? detail : "", s ? s : "" , s2); #endif - + gobject = g_value_get_object (param_values + 0); if (G_VALUE_TYPE (param_values + 1) == G_TYPE_INT) detail1 = g_value_get_int (param_values + 1); if (G_VALUE_TYPE (param_values + 2) == G_TYPE_INT) detail2 = g_value_get_int (param_values + 2); - - /* build some event context data, depending on the type */ - ctx = spi_atk_bridge_event_context_create (gobject, - detail1, detail2, - &signal_query, - detail); - - if (detail) - spi_atk_emit_eventv (gobject, detail1, detail2, ctx, - "object:%s:%s", name, detail); - else - spi_atk_emit_eventv (gobject, detail1, detail2, ctx, - "object:%s", name); - - if (ctx) - spi_atk_bridge_event_context_free (ctx); - + + spi_atk_signal_emit_event (gobject, &signal_query, + detail2, detail2, + name, detail); return TRUE; } static gboolean spi_atk_bridge_window_event_listener (GSignalInvocationHint *signal_hint, - guint n_param_values, - const GValue *param_values, - gpointer data) + guint n_param_values, + const GValue *param_values, + gpointer data) { GObject *gobject; GSignalQuery signal_query; - AtkBridgeEventContext ctx; - + CORBA_any any; const gchar *name, *s; #ifdef SPI_BRIDGE_DEBUG const gchar *s2; @@ -830,11 +789,11 @@ spi_atk_bridge_window_event_listener (GSignalInvocationHint *signal_hint, #endif gobject = g_value_get_object (param_values + 0); - ctx._type = ATK_BRIDGE_CONTEXT_TYPE_STRING; + s = atk_object_get_name (ATK_OBJECT (gobject)); - ctx._data.string = (gchar *) s; - /* cast from const silences compiler */ - spi_atk_emit_eventv (gobject, 0, 0, &ctx, "window:%s", name); - /* don't free the context, it's on the stack */ + spi_init_any_string (&any, &s); + + spi_atk_emit_eventv (gobject, 0, 0, &any, + "window:%s", name); return TRUE; } diff --git a/cspi/spi.h b/cspi/spi.h index 842599a..7850532 100644 --- a/cspi/spi.h +++ b/cspi/spi.h @@ -798,8 +798,8 @@ SPIBoolean AccessibleValue_setCurrentValue (AccessibleValue *obj, * information for accessible events. */ -char* AccessibleEvent_getContextString (const AccessibleEvent *e); -Accessible * AccessibleEvent_getContextObject (const AccessibleEvent *e); +char* AccessibleTextChangedEvent_getChangeString (const AccessibleEvent *e); +Accessible * AccessibleChildChangedEvent_getChildAccessible (const AccessibleEvent *e); /* Misc methods */ void SPI_freeString (char *s); diff --git a/cspi/spi_event.c b/cspi/spi_event.c index 0d63ac9..974ce41 100644 --- a/cspi/spi_event.c +++ b/cspi/spi_event.c @@ -327,36 +327,18 @@ AccessibleDeviceListener_unref (AccessibleDeviceListener *listener) cspi_device_listener_unref (listener); } -/** - * AccessibleEvent_getContextString: - * @event: a pointer to the #AccessibleEvent being queried. - * - * Queries an #AccessibleEvent for a string whose meaning depends - * on the event's context, that is, the event type and details. - * Not all events have context strings, in which case this - * query returns NULL. - * Context strings may be returned by: - * object:text-changed events, - * in which case they represent the text inserted or deleted; - * window: events, in which case they indicate the window title, - * or other events. - * - * Returns: the context string for the event, or %NULL if - * there is no context string for the event. - **/ -char * -AccessibleEvent_getContextString (const AccessibleEvent *e) +static char * +cspi_internal_event_get_text (const InternalEvent *e) { - InternalEvent *foo = (InternalEvent *) e; CORBA_any *any; - g_return_val_if_fail (foo, NULL); - g_return_val_if_fail (foo->data, NULL); - any = (CORBA_any *) foo->data; + g_return_val_if_fail (e, NULL); + g_return_val_if_fail (e->data, NULL); + any = (CORBA_any *) e->data; if (CORBA_TypeCode_equivalent (any->_type, TC_CORBA_string, NULL)) { return * (char **) any->_value; } - else + else { #ifdef EVENT_CONTEXT_DEBUG fprintf (stderr, "requested string, TC is not TC_CORBA_string! (%u)\n", @@ -366,35 +348,56 @@ AccessibleEvent_getContextString (const AccessibleEvent *e) } } +static char * +cspi_internal_event_get_object (const InternalEvent *e) +{ + CORBA_any *any; + g_return_val_if_fail (e, NULL); + g_return_val_if_fail (e->data, NULL); + any = (CORBA_any *) e->data; + if (any->_type == TC_CORBA_Object) + return cspi_object_add (* (CORBA_Object *) any->_value); + else + return NULL; +} + + /** - * AccessibleEvent_getContextObject: + * AccessibleTextChangedEvent_getChangeString: * @event: a pointer to the #AccessibleEvent being queried. * - * Queries an #AccessibleEvent for an #Accessible whose meaning depends - * on the event's context, that is, the event type and details. - * Not all events have context strings, in which case this - * query returns NULL. - * Context #Accessible objects may be returned by, for instance: - * object:child-changed events, - * in which case they represent the child added or deleted. + * Queries an #AccessibleEvent of type "object:text-changed", + * returning the text inserted or deleted. + * + * Returns: a UTF-8 text string indicating the text inserted, + * deleted, or substituted by this event. + **/ +char * +AccessibleTextChangedEvent_getChangeString (const AccessibleEvent *e) +{ + InternalEvent *foo = (InternalEvent *) e; + /* TODO: check the event type? expensive... */ + return cspi_internal_event_get_text (e); +} + +/** + * AccessibleChildChangedEvent_getChildAccessible: + * @event: a pointer to the #AccessibleEvent being queried. + * + * Queries an #AccessibleEvent of type "object:children_changed" + * to get a reference to the changed #Accessible. * Note that context #Accessibles are not guaranteed to outlive * event delivery, in which case this call may return %NULL * even if the object existed at the time of dispatch. * * Returns: the context #Accessible for the event, or %NULL if - * there is no context #Accessible object for the event. + * there is no longer a valid context #Accessible + * object for the event. **/ Accessible * -AccessibleEvent_getContextObject (const AccessibleEvent *e) +AccessibleChildChangedEvent_getChildAccessible (const AccessibleEvent *e) { InternalEvent *foo = (InternalEvent *) e; - CORBA_any *any; - g_return_val_if_fail (foo, NULL); - g_return_val_if_fail (foo->data, NULL); - any = (CORBA_any *) foo->data; - if (any->_type == TC_CORBA_Object) - return cspi_object_add (* (CORBA_Object *) any->_value); - else - return NULL; + return cspi_internal_event_get_object (e); } diff --git a/registryd/registry.c b/registryd/registry.c index 0fc99c1..b167362 100644 --- a/registryd/registry.c +++ b/registryd/registry.c @@ -41,7 +41,7 @@ /* A pointer to our parent object class */ static SpiListenerClass *spi_registry_parent_class; -extern int _dbg = 0; +int _dbg = 0; typedef enum { ETYPE_FOCUS, @@ -69,10 +69,10 @@ typedef struct { } SpiListenerStruct; static void -spi_registry_set_debug (char *debug_flag_string) +spi_registry_set_debug (const char *debug_flag_string) { if (debug_flag_string) - _dbg = g_ascii_digit_value(debug_flag_string); + _dbg = (int) g_ascii_strtod (debug_flag_string, NULL); } SpiListenerStruct * diff --git a/test/event-listener-test.c b/test/event-listener-test.c index c3374b0..247c6bf 100644 --- a/test/event-listener-test.c +++ b/test/event-listener-test.c @@ -275,7 +275,7 @@ report_text_event (const AccessibleEvent *event, void *user_data) fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s, event->detail1, event->detail2); if (s) SPI_freeString (s); - s = AccessibleEvent_getContextString (event); + s = AccessibleTextChangedEvent_getChangeString (event); fprintf (stderr, "context string %s\n", (s) ? s : ""); } -- 2.7.4