#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;
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,
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);
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))
{
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)
{
}
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;
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;
{
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",
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);
}
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,
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);
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 : "<NULL>", s ? s : "<NULL>" , s2);
+ detail ? detail : "<NULL>", s ? s : "<NULL>" , 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;
#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;
}
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",
}
}
+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);
}