Added support for atk object:bounds-changed signals (bug #135253).
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 11 Jun 2004 16:13:03 +0000 (16:13 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 11 Jun 2004 16:13:03 +0000 (16:13 +0000)
git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@674 e2bd861d-eb25-0410-b326-f6ed22b6b98c

ChangeLog
atk-bridge/bridge.c
cspi/spi.h
cspi/spi_event.c
cspi/spi_main.c
libspi/spi-private.h
libspi/util.c
test/event-listener-test.c

index 7d96a9d..5970814 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2004-06-11  Bill Haneman <bill.haneman@sun.com>
+
+       * atk-bridge/bridge.c:
+       (spi_atk_bridge_do_registration): 
+       Register with ATK for AtkComponent:bounds-changed events.
+       (api_atk_bridge_signal_listener): 
+       Marshal the AtkRectangle info into the event notification
+       for object:bounds-changed events.
+       
+       * libspi/util.c:
+       (spi_init_any_rect): New method, inits a corba struct of
+       type Accessibility_BoundingBox from an AtkRectangle.
+
+       * libspi/spi-private.h: Declared spi_init_any_rect (above).
+       
+       * cspi/spi.h:
+       (SPIRect): New struct definition.
+       (SPI_freeRect): New declaration.
+       (AccessibleBoundsChangedEvent_getNewBounds): New, see below.
+
+       * cspi/spi_event.c:
+       (AccessibleBoundsChangedEvent_getNewBounds): New method,
+       implemented.  Gets the bounding box data from the CORBA_any
+       associated with a bounds-changed event notification.
+       (cspi_internal_event_get_rect): New, used internally by above method.
+       
+       * cspi/spi_main.c:
+       (SPI_freeRect): Implemented this new method, for freeing
+       SPIRect structs.
+       
+       * test/event-listener-test.c:
+       (main, report_bounds_event):
+       Added a test for object:bounds-changed events.
+       
 2004-06-01  Bill Haneman <bill.haneman@sun.com>
 
        * test/login-helper-server-test.c:
index c363a08..9d0db85 100644 (file)
@@ -64,6 +64,7 @@ static guint atk_signal_text_selection_changed;
 */
 
 static guint atk_signal_link_selected;
+static guint atk_signal_bounds_changed;
 
 static Accessibility_Registry spi_atk_bridge_get_registry (void);
 static void     spi_atk_bridge_do_registration         (void);
@@ -130,9 +131,11 @@ spi_atk_bridge_init_event_type_consts ()
                                              ATK_TYPE_OBJECT);
   atk_signal_text_changed = g_signal_lookup ("text_changed", 
                                             ATK_TYPE_TEXT);
+  atk_signal_bounds_changed = g_signal_lookup ("bounds_changed", 
+                                             ATK_TYPE_COMPONENT);
   atk_signal_active_descendant_changed = 
          g_signal_lookup ("active_descendant_changed", 
-                         ATK_TYPE_OBJECT);
+                         ATK_TYPE_OBJECT); 
   atk_signal_link_selected = g_signal_lookup ("link_selected", 
                                              ATK_TYPE_HYPERTEXT);
   atk_signal_text_selection_changed = g_signal_lookup ("text_selection_changed", 
@@ -384,6 +387,7 @@ spi_atk_register_event_listeners (void)
   add_signal_listener ("Gtk:AtkObject:children-changed");
   add_signal_listener ("Gtk:AtkObject:visible-data-changed");
   add_signal_listener ("Gtk:AtkObject:active-descendant-changed");
+  add_signal_listener ("Gtk:AtkComponent:bounds-changed");
   add_signal_listener ("Gtk:AtkSelection:selection-changed");
   add_signal_listener ("Gtk:AtkText:text-selection-changed");
   add_signal_listener ("Gtk:AtkText:text-changed");
@@ -903,6 +907,14 @@ spi_atk_bridge_signal_listener (GSignalInvocationHint *signal_hint,
         detail1 = g_value_get_int (param_values + 1);
       spi_init_any_nil (&any);
     }
+  else if (signal_query.signal_id == atk_signal_bounds_changed)
+    {
+      AtkRectangle *atk_rect = NULL;
+
+      if (G_VALUE_HOLDS_BOXED (param_values + 1))
+         atk_rect = g_value_get_boxed (param_values + 1);
+      spi_init_any_rect (&any, atk_rect);
+    }
   else if ((signal_query.signal_id == atk_signal_children_changed) && gobject)
     {
       ao = atk_object_ref_accessible_child (ATK_OBJECT (gobject), 
index f31ad45..9b341d6 100644 (file)
@@ -221,6 +221,13 @@ typedef enum {
 typedef unsigned long AccessibleKeyEventMask;
 typedef unsigned long AccessibleDeviceEventMask;
 
+typedef struct {
+       long x;
+       long y;
+       long width;
+       long height;
+} SPIRect;
+
 /**
  *AccessibleComponentLayer:
  *@SPI_LAYER_INVALID: The layer cannot be determined or is somehow undefined.
@@ -1015,12 +1022,15 @@ char *       AccessibleTableColumnDescriptionChangedEvent_getDescriptionString (
 char *       AccessibleDescriptionChangedEvent_getDescriptionString (const AccessibleEvent *e);
 
 char *       AccessibleNameChangedEvent_getNameString (const AccessibleEvent *e);
+SPIRect *    AccessibleBoundsChangedEvent_getNewBounds (const AccessibleEvent *e);
 
 /* Misc methods and error handling */
 void SPI_freeString (char *s);
 
 char* SPI_dupString (char *s);
 
+void SPI_freeRect (SPIRect *rect);
+
 SPIBoolean SPI_exceptionHandlerPush (SPIExceptionHandler *handler);
 
 SPIExceptionHandler* SPI_exceptionHandlerPop (void);
index 695f1a2..1474e75 100644 (file)
@@ -365,6 +365,33 @@ cspi_internal_event_get_object (const InternalEvent *e)
     return NULL;
 }
 
+static SPIRect *
+cspi_internal_event_get_rect (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 (CORBA_TypeCode_equivalent (any->_type, TC_Accessibility_BoundingBox, NULL)) 
+    {
+      SPIRect *rect = g_new (SPIRect, 1);
+      Accessibility_BoundingBox *bounds = (Accessibility_BoundingBox *) any->_value;
+      rect->x = bounds->x;
+      rect->y = bounds->y;
+      rect->width = bounds->width;
+      rect->height = bounds->height;
+      return rect;
+    } 
+  else
+    {
+#ifdef EVENT_CONTEXT_DEBUG
+      fprintf (stderr, "requested string, TC is not TC_Accessible_RectBounds! (%u)\n",
+              (unsigned) any->_type);
+#endif
+      return NULL;
+    }
+}
+
 /**
  * AccessibleTextChangedEvent_getChangeString:
  * @e: a pointer to the #AccessibleEvent being queried.
@@ -593,6 +620,26 @@ AccessibleDescriptionChangedEvent_getDescriptionString (const AccessibleEvent *e
   return cspi_internal_event_get_text (foo);
 }
 
+/**
+ * AccessibleBoundsChangedEvent_getNewBounds:
+ * @e: a pointer to the #AccessibleEvent being queried.
+ *
+ * Queries an #AccessibleEvent of type "object:bounds-changed", 
+ *         returning a pointer to an SPIRect structure containing the
+ *         new bounds, or NULL on error.
+ *         The returned structure should be freed with SPI_freeRect when 
+ *         the caller has finished referencing it.
+ *
+ * Returns: a pointer to an SPIRect defining the new object bounds.
+ **/
+SPIRect *
+AccessibleBoundsChangedEvent_getNewBounds (const AccessibleEvent *e)
+{
+  const InternalEvent *foo = (InternalEvent *) e;
+  /* TODO: check the event type. */
+  return cspi_internal_event_get_rect (foo);
+}
+
 static gint
 cspi_event_compare (gconstpointer p1, gconstpointer p2)
 {
index d4aa993..e179059 100644 (file)
@@ -536,6 +536,27 @@ SPI_freeString (char *s)
 }
 
 /**
+ * SPI_freeRect:
+ * @r: a pointer to an SPIRect returned from another at-spi call.
+ *
+ * Free a SPIRect structure returned from an at-spi call.  Clients of
+ * at-spi should use this function instead of free () or g_free().
+ * A NULL rect @r will be silently ignored.
+ * This API should not be used to free data
+ * from other libraries or allocated by the client.
+ **/
+void
+SPI_freeRect (SPIRect *r)
+{
+  if (r)
+    {
+      /* err, okay, in this case the client _could_ 
+        have called g_free, but we don't want to guarantee it */
+      g_free (r);
+    }
+}
+
+/**
  * DOCUMENT_ME!
  **/
 char *
index f881ced..b0288be 100644 (file)
@@ -25,6 +25,7 @@
 #define SPI_PRIVATE_H_
 
 #include <glib/glist.h>
+#include <atk/atk.h>
 #include <orbit/orbit.h>
 
 G_BEGIN_DECLS
@@ -48,6 +49,7 @@ void spi_re_entrant_list_foreach     (GList         **list,
 void spi_init_any_nil                (CORBA_any *any);
 void spi_init_any_string             (CORBA_any *any, char **string);
 void spi_init_any_object             (CORBA_any *any, CORBA_Object *o);
+void spi_init_any_rect               (CORBA_any *any, AtkRectangle *rect);
 
 G_END_DECLS
 
index 8a021fa..39a682f 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <glib/gmessages.h>
 #include <glib/gslist.h>
+#include <Accessibility.h>
 
 #include "spi-private.h"
 
@@ -135,3 +136,16 @@ spi_init_any_string (CORBA_any *any, char **string_pointer)
     any->_value = &spi_atk_bridge_null_string;
   any->_release = FALSE;
 }
+
+void
+spi_init_any_rect (CORBA_any *any, AtkRectangle *rect)
+{
+    Accessibility_BoundingBox *box = Accessibility_BoundingBox__alloc ();
+    box->x = rect->x;
+    box->y = rect->y;
+    box->width = rect->width;
+    box->height = rect->height;
+    any->_type = TC_Accessibility_BoundingBox;
+    any->_value = box;
+    any->_release = TRUE;
+}
index 72fc9d8..a6b7a93 100644 (file)
@@ -29,6 +29,7 @@
 static void traverse_accessible_tree (Accessible *accessible);
 
 static void report_event  (const AccessibleEvent *event, void *user_data);
+static void report_bounds_event  (const AccessibleEvent *event, void *user_data);
 static void report_detail_event  (const AccessibleEvent *event, void *user_data);
 static void report_detail1_event  (const AccessibleEvent *event, void *user_data);
 static void report_text_event  (const AccessibleEvent *event, void *user_data);
@@ -49,6 +50,7 @@ static SPIBoolean report_mouse_event  (const AccessibleDeviceEvent *event, void
 
 static AccessibleEventListener *generic_listener;
 static AccessibleEventListener *specific_listener;
+static AccessibleEventListener *bounds_listener;
 static AccessibleEventListener *detail1_listener;
 static AccessibleEventListener *test_listener;
 static AccessibleEventListener *text_listener;
@@ -117,6 +119,8 @@ main (int argc, char **argv)
          report_event, NULL); 
   specific_listener = SPI_createAccessibleEventListener (
          report_detail_event, NULL); 
+  bounds_listener = SPI_createAccessibleEventListener (
+         report_bounds_event, NULL);
   text_listener = SPI_createAccessibleEventListener (
          report_text_event, NULL);
   text_selection_listener = SPI_createAccessibleEventListener (
@@ -208,6 +212,8 @@ main (int argc, char **argv)
                                   "object:model-changed"); 
   SPI_registerGlobalEventListener (detail1_listener,
                                   "object:link-selected"); 
+  SPI_registerGlobalEventListener (bounds_listener,
+                                  "object:bounds-changed");
   SPI_registerGlobalEventListener (window_listener,
                                   "window:minimize");
   SPI_registerGlobalEventListener (window_listener,
@@ -347,6 +353,18 @@ report_detail1_event (const AccessibleEvent *event, void *user_data)
 }
 
 void
+report_bounds_event (const AccessibleEvent *event, void *user_data)
+{
+  char *s = Accessible_getName (event->source);
+  SPIRect *bounds = AccessibleBoundsChangedEvent_getNewBounds (event);
+  if (!bounds) fprintf (stderr, "bounds-changed event with no bounds?\n");
+  fprintf (stderr, "(bounds-changed) %s %s %d,%d - %d,%d\n", event->type, s,
+          bounds->x, bounds->y, bounds->x + bounds->width, bounds->y + bounds->height);
+  SPI_freeRect (bounds);
+  if (s) SPI_freeString (s);
+}
+
+void
 report_text_event (const AccessibleEvent *event, void *user_data)
 {
   char *s = Accessible_getName (event->source);