X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git;a=blobdiff_plain;f=cspi%2Fspi_main.c;h=b8e11bd1c5cde99e772cb2d5d9cc51fb3f209a95;hp=f39cfc75eee65880abe532647a470e8b88e71f75;hb=5d01be6ec7d2cb2e662c695bd4c28c50ac3f2dab;hpb=b1bb62ce99338b20865e1873af3cec45ce6871af diff --git a/cspi/spi_main.c b/cspi/spi_main.c index f39cfc7..b8e11bd 100644 --- a/cspi/spi_main.c +++ b/cspi/spi_main.c @@ -1,993 +1,686 @@ -#include +/* + * AT-SPI - Assistive Technology Service Provider Interface + * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) + * + * Copyright 2001, 2002 Sun Microsystems Inc., + * Copyright 2001, 2002 Ximian, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * + * Basic SPI initialization and event loop function prototypes + * + */ + #include +#include +#include +#include #include "spi.h" -static CORBA_Environment ev; -static AccessibilityRegistry registry; +#undef DEBUG_OBJECTS -static Accessible * -Obj_Add (Accessible object) +static CORBA_Environment ev = { NULL }; +static Accessibility_Registry registry = CORBA_OBJECT_NIL; +static GHashTable *live_refs = NULL; +static GQueue *exception_handlers = NULL; + +static guint +cspi_object_hash (gconstpointer key) { - /* TODO: keep list of live object refs */ - Accessible *oref = g_malloc (sizeof (Accessible)); - *oref = object; - return oref; + CORBA_Object object = (CORBA_Object) key; + + return CORBA_Object_hash (object, 0, &ev); } -/* - * - * Basic SPI initialization and event loop function prototypes - * - */ +static gboolean +cspi_object_equal (gconstpointer a, gconstpointer b) +{ + CORBA_Object objecta = (CORBA_Object) a; + CORBA_Object objectb = (CORBA_Object) b; -/** - * SPI_init: - * - * Connects to the accessibility registry and initializes the SPI. - * - * Returns: 0 on success, otherwise an integer error code. - **/ -int -SPI_init (void) + return CORBA_Object_is_equivalent (objecta, objectb, cspi_ev ()); +} + +static void +cspi_object_release (gpointer value) { - int argc = 0; - CORBA_Object oclient; - char *obj_id; + Accessible *a = (Accessible *) value; - CORBA_exception_init(&ev); +#ifdef DEBUG_OBJECTS + g_print ("releasing %p => %p\n", a, a->objref); +#endif - if (!bonobo_init (&argc, NULL)) + if (!a->on_loan) { - g_error ("Could not initialize Bonobo"); + cspi_release_unref (a->objref); } - obj_id = "OAFIID:Accessibility_Registry:proto0.1"; - - oclient = bonobo_activation_activate_from_id (obj_id, 0, NULL, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - fprintf (stderr, - ("AT-SPI error: during registry activation: %s\n"), - CORBA_exception_id(&ev)); - CORBA_exception_free(&ev); - exit(-1); + memset (a, 0xaa, sizeof (Accessible)); + a->ref_count = -1; + +#ifndef DEBUG_OBJECTS + free (a); +#endif +} + +gboolean +cspi_exception_throw (CORBA_Environment *ev, char *desc_prefix) +{ + SPIExceptionHandler *handler = NULL; + SPIException ex; + if (exception_handlers) handler = g_queue_peek_head (exception_handlers); + + ex.type = SPI_EXCEPTION_SOURCE_UNSPECIFIED; + ex.source = CORBA_OBJECT_NIL; /* can we get this from here? */ + ex.ev = CORBA_exception__copy (ev); + switch (ev->_major) { + case CORBA_SYSTEM_EXCEPTION: + ex.code = SPI_EXCEPTION_UNSPECIFIED; + break; + case CORBA_USER_EXCEPTION: /* help! how to interpret this? */ + ex.code = SPI_EXCEPTION_UNSPECIFIED; + break; + default: + ex.code = SPI_EXCEPTION_UNSPECIFIED; + break; } + + if (handler) + return (*handler) (&ex, FALSE); + else + return FALSE; /* means exception was not handled */ +} - if (CORBA_Object_is_nil (oclient, &ev)) +SPIBoolean +cspi_accessible_is_a (Accessible *accessible, + const char *interface_name) +{ + SPIBoolean retval; + Bonobo_Unknown unknown; + + if (accessible == NULL) { - g_error ("Could not locate registry"); - exit(-1); + return FALSE; } - registry = (Accessibility_Registry) oclient; + unknown = Bonobo_Unknown_queryInterface (CSPI_OBJREF (accessible), + interface_name, cspi_ev ()); - bonobo_activate (); + if (ev._major != CORBA_NO_EXCEPTION) + { + g_warning ("Exception '%s' checking if is '%s'", + cspi_exception_get_text (), + interface_name); + retval = FALSE; + } - return 0; -} + else if (unknown != CORBA_OBJECT_NIL) + { + retval = TRUE; + cspi_release_unref (unknown); + } + else + { + retval = FALSE; + } -/** - * SPI_event_main: - * @isGNOMEApp: a #boolean indicating whether the client of the SPI - * will use the Gnome event loop or not. - * - * Starts/enters the main event loop for the SPI services. - * - * (NOTE: This method does not return control, it is exited via a call to exit() - * from within an event handler). - * - **/ -void -SPI_event_main (boolean isGNOMEApp) -{ - if (isGNOMEApp) bonobo_main(); - else CORBA_ORB_run (bonobo_orb(), &ev); + return retval; } -/** - * SPI_event_is_ready: - * - * Checks to see if an SPI event is waiting in the event queue. - * Used by clients that don't wish to use SPI_event_main(). - * Not Yet Implemented. - * - * Returns: #TRUE if an event is waiting, otherwise #FALSE. - * - **/ -boolean -SPI_eventIsReady () +static GHashTable * +cspi_get_live_refs (void) { - return FALSE; + if (!live_refs) + { + live_refs = g_hash_table_new_full (cspi_object_hash, + cspi_object_equal, + NULL, + cspi_object_release); + } + return live_refs; } -/** - * SPI_nextEvent: - * - * Gets the next event in the SPI event queue; blocks if no event - * is pending. - * Used by clients that don't wish to use SPI_event_main(). - * Not Yet Implemented. - * - * Returns: the next #AccessibleEvent in the SPI event queue. - * - **/ -AccessibleEvent * -SPI_nextEvent (boolean waitForEvent) +CORBA_Environment * +cspi_peek_ev (void) { - return NULL; + return &ev; } -/** - * SPI_exit: - * - * Disconnects from the Accessibility Registry and releases resources. - * Not Yet Implemented. - * - **/ -void -SPI_exit (void) +CORBA_Environment * +cspi_ev (void) { - exit(0); + CORBA_exception_init (&ev); + return &ev; } -/** - * createEventListener: - * @callback : an #AccessibleEventListenerCB callback function, or NULL. - * - * Create a new #AccessibleEventListener with a specified callback function. - * - * Returns: a pointer to a newly-created #AccessibleEventListener. - * - **/ -AccessibleEventListener * -createEventListener (AccessibleEventListenerCB callback) +Accessibility_Registry +cspi_registry (void) { - AccessibleEventListener *listener = accessible_event_listener_new (); - if (callback) + if (!cspi_ping (registry)) { - accessible_event_listener_add_callback (listener, callback); + registry = cspi_init (); } - return listener; + return registry; } -/** - * EventListener_addCallback: - * @listener: the #AccessibleEventListener instance to modify. - * @callback: an #AccessibleEventListenerCB function pointer. - * - * Add an in-process callback function to an existing AccessibleEventListener. - * - * Returns: #TRUE if successful, otherwise #FALSE. - * - **/ -boolean -EventListener_addCallback (AccessibleEventListener *listener, - AccessibleEventListenerCB callback) +SPIBoolean +cspi_exception (void) { - accessible_event_listener_add_callback (listener, callback); - return TRUE; -} + SPIBoolean retval; -/** - * EventListener_removeCallback: - * @listener: the #AccessibleEventListener instance to modify. - * @callback: an #AccessibleEventListenerCB function pointer. - * - * Remove an in-process callback function from an existing AccessibleEventListener. - * - * Returns: #TRUE if successful, otherwise #FALSE. - * - **/ -boolean -EventListener_removeCallback (AccessibleEventListener *listener, - AccessibleEventListenerCB callback) -{ - accessible_event_listener_remove_callback (listener, callback); - return TRUE; + if (ev._major != CORBA_NO_EXCEPTION) + { + CORBA_exception_free (&ev); + retval = TRUE; + } + else + { + retval = FALSE; + } + + return retval; } /* - * - * Global functions serviced by the registry - * + * This method swallows the corba_object BonoboUnknown + * reference, and returns an Accessible associated with it. + * If the reference is loaned, it means it is only valid + * between a borrow / return pair. */ - -/** - * registerGlobalEventListener: - * @listener: the #AccessibleEventListener to be registered against an event type. - * @callback: a character string indicating the type of events for which - * notification is requested. Format is - * EventClass:major_type:minor_type:detail - * where all subfields other than EventClass are optional. - * EventClasses include "Focus", "Window", "Mouse", - * and toolkit events (e.g. "Gtk", "AWT"). - * Examples: "focus:", "Gtk:GtkWidget:button_press_event". - * - * NOTE: this string may be UTF-8, but should not contain byte value 56 (ascii ':'), - * except as a delimiter, since non-UTF-8 string delimiting - * functions are used internally. In general, listening to - * toolkit-specific events is not recommended. - * - * Add an in-process callback function to an existing AccessibleEventListener. - * - * Returns: #TRUE if successful, otherwise #FALSE. - * - **/ -boolean -registerGlobalEventListener (AccessibleEventListener *listener, - char *eventType) +static Accessible * +cspi_object_get_ref (CORBA_Object corba_object, gboolean on_loan) { - Accessibility_Registry_registerGlobalEventListener ( - registry, - (Accessibility_EventListener) - bonobo_object_corba_objref (bonobo_object (listener)), - eventType, - &ev); + Accessible *ref; - if (ev._major != CORBA_NO_EXCEPTION) + if (corba_object == CORBA_OBJECT_NIL) { - return FALSE; + ref = NULL; + } + else if (!cspi_check_ev ("pre method check: add")) + { + ref = NULL; } else { - return TRUE; + if ((ref = g_hash_table_lookup (cspi_get_live_refs (), corba_object))) + { + g_assert (ref->ref_count > 0); + ref->ref_count++; + if (!on_loan) + { + if (ref->on_loan) /* Convert to a permanant ref */ + { + ref->on_loan = FALSE; + } + else + { + cspi_release_unref (corba_object); + } + } +#ifdef DEBUG_OBJECTS + g_print ("returning cached %p => %p\n", ref, ref->objref); +#endif + } + else + { + ref = malloc (sizeof (Accessible)); + ref->objref = corba_object; + ref->ref_count = 1; + ref->on_loan = on_loan; +#ifdef DEBUG_OBJECTS + g_print ("allocated %p => %p\n", ref, corba_object); +#endif + g_hash_table_insert (cspi_get_live_refs (), ref->objref, ref); + } } -} -/** - * getDesktopCount: - * - * Get the number of virtual desktops. - * NOTE: currently multiple virtual desktops are not implemented, this - * function always returns '1'. - * - * Returns: an integer indicating the number of active virtual desktops. - * - **/ -int -getDesktopCount () -{ - return Accessibility_Registry_getDesktopCount (registry, &ev); + return ref; } -/** - * getDesktop: - * @i: an integer indicating which of the accessible desktops is to be returned. - * - * Get the virtual desktop indicated by index @i. - * NOTE: currently multiple virtual desktops are not implemented, this - * function always returns '1'. - * - * Returns: a pointer to the 'i-th' virtual desktop's #Accessible representation. - * - **/ -Accessible* -getDesktop (int n) +Accessible * +cspi_object_add (CORBA_Object corba_object) { - return Obj_Add (Accessibility_Registry_getDesktop (registry, (CORBA_short) n, &ev)); + return cspi_object_get_ref (corba_object, FALSE); } -/** - * getDesktopList: - * @list: a pointer to an array of #Accessible objects. - * - * Get the list of virtual desktops. On return, @list will point - * to a newly-created array of virtual desktop pointers. - * It is the responsibility of the caller to free this array when - * it is no longer needed. - * - * Not Yet Implemented. - * - * Returns: an integer indicating how many virtual desktops have been - * placed in the list pointed to by parameter @list. - **/ -int -getDesktopList (Accessible **list) +Accessible * +cspi_object_borrow (CORBA_Object corba_object) { - *list = NULL; - return 0; + return cspi_object_get_ref (corba_object, TRUE); } -/** - * registerKeystrokeListener: - * @listener: a pointer to the #KeystrokeListener for which - * keystroke events are requested. - * - * Not Yet Implemented. - * - **/ void -registerKeystrokeListener (KeystrokeListener *listener) +cspi_object_return (Accessible *accessible) { - ; + int old_ref_count; + g_return_if_fail (accessible != NULL); + + if (!accessible->on_loan || + accessible->ref_count == 1) + { + cspi_object_unref (accessible); + } + else /* Convert to a permanant ref */ + { + accessible->on_loan = FALSE; + old_ref_count = accessible->ref_count; + accessible->objref = cspi_dup_ref (accessible->objref); + if (old_ref_count != accessible->ref_count && + accessible->ref_count == 1) + { + cspi_object_unref (accessible); + } + else + { + accessible->ref_count--; + } + } } -/** - * generateKeyEvent: - * @keycode: a #long indicating the keycode of the key event - * being synthesized. - * @meta: a #long indicating the key modifiers to be sent - * with the event, if any. - * - * Synthesize a keyboard event (as if a hardware keyboard event occurred in the - * current UI context). - * Not Yet Implemented. - * - **/ -void -generateKeyEvent (long keyCode, long meta) -{ - ; +Accessible * +cspi_object_take (CORBA_Object corba_object) +{ + Accessible *accessible; + accessible = cspi_object_borrow (corba_object); + + cspi_object_ref (accessible); + /* + * if the remote object is dead, + * cspi_object_return will throw an exception. + * FIXME: what clears that exception context ever ? + */ + cspi_object_return (accessible); + if (cspi_exception ()) + { + cspi_object_unref (accessible); + accessible = NULL; + } + return accessible; } -/** - * generateMouseEvent: - * @x: a #long indicating the screen x coordinate of the mouse event. - * @y: a #long indicating the screen y coordinate of the mouse event. - * @name: a string indicating which mouse event to be synthesized - * (e.g. "button1", "button2", "mousemove"). - * - * Synthesize a mouse event at a specific screen coordinate. - * Not Yet Implemented. - * - **/ void -generateMouseEvent (long x, long y, char *name) +cspi_object_ref (Accessible *accessible) { - ; -} + g_return_if_fail (accessible != NULL); -/* - * - * Accessible function prototypes - * - */ - -/** - * Accessible_ref: - * @obj: a pointer to the #Accessible object on which to operate. - * - * Increment the reference count for an #Accessible object. - * - * Returns: (no return code implemented yet). - * - **/ -int -Accessible_ref (Accessible *obj) -{ - Accessibility_Accessible_ref (*obj, &ev); - return 0; + accessible->ref_count++; } - -/** - * Accessible_unref: - * @obj: a pointer to the #Accessible object on which to operate. - * - * Decrement the reference count for an #Accessible object. - * - * Returns: (no return code implemented yet). - * - **/ -int -Accessible_unref (Accessible *obj) +void +cspi_object_unref (Accessible *accessible) { - Accessibility_Accessible_unref (*obj, &ev); - return 0; -} + if (accessible == NULL) + { + return; + } -/** - * Accessible_getName: - * @obj: a pointer to the #Accessible object on which to operate. - * - * Get the name of an #Accessible object. - * - * Returns: a UTF-8 string indicating the name of the #Accessible object. - * - **/ -char * -Accessible_getName (Accessible *obj) -{ - return Accessibility_Accessible__get_name (*obj, &ev); + g_return_if_fail (accessible->ref_count > 0); + if (--accessible->ref_count == 0) + { + g_hash_table_remove (cspi_get_live_refs (), accessible->objref); + } } -/** - * Accessible_getDescription: - * @obj: a pointer to the #Accessible object on which to operate. - * - * Get the description of an #Accessible object. - * - * Returns: a UTF-8 string describing the #Accessible object. - * - **/ -char * -Accessible_getDescription (Accessible *obj) +static void +cspi_cleanup (void) { - return Accessibility_Accessible__get_description (*obj, &ev); -} + GHashTable *refs; -/** - * Accessible_getParent: - * @obj: a pointer to the #Accessible object to query. - * - * Get an #Accessible object's parent container. - * - * Returns: a pointer to the #Accessible object which contains the given - * #Accessible instance, or NULL if the @obj has no parent container. - * - **/ -Accessible * -Accessible_getParent (Accessible *obj) -{ - return Obj_Add (Accessibility_Accessible__get_parent (*obj, &ev)); -} + cspi_streams_close_all (); -/** - * Accessible_getChildCount: - * - * @obj: a pointer to the #Accessible object on which to operate. - * - * Get the number of children contained by an #Accessible object. - * - * Returns: a #long indicating the number of #Accessible children - * contained by an #Accessible object. - * - **/ -long -Accessible_getChildCount (Accessible *obj) -{ - return Accessibility_Accessible__get_childCount (*obj, &ev); -} + refs = live_refs; + live_refs = NULL; + if (refs) + { + g_hash_table_destroy (refs); + } -/** - * Accessible_getChildAtIndex: - * - * @obj: a pointer to the #Accessible object on which to operate. - * @childIndex: a #long indicating which child is specified. - * - * Get the #Accessible child of an #Accessible object at a given index. - * - * Returns: a pointer to the #Accessible child object at index - * @childIndex. - * - **/ -Accessible * -Accessible_getChildAtIndex (Accessible *obj, - long childIndex) -{ - return Obj_Add (Accessibility_Accessible_getChildAtIndex (*obj, childIndex, &ev)); + if (registry != CORBA_OBJECT_NIL) + { + cspi_release_unref (registry); + registry = CORBA_OBJECT_NIL; + } } -/** - * Accessible_getIndexInParent: - * - * @obj: a pointer to the #Accessible object on which to operate. - * - * Get the index of an #Accessible object in its containing #Accessible. - * - * Returns: a #long indicating the index of the #Accessible object - * in its parent (i.e. containing) #Accessible instance, - * or -1 if @obj has no containing parent. - * - **/ -long -Accessible_getIndexInParent (Accessible *obj) -{ - return Accessibility_Accessible_getIndexInParent (*obj, &ev); -} +static gboolean SPI_inited = FALSE; /** - * Accessible_getRelationSet: - * - * Not Yet Implemented. + * SPI_init: * - * Returns: a pointer to an array of #AccessibleRelations. + * Connects to the accessibility registry and initializes the SPI. * + * Returns: 0 on success, otherwise an integer error code. **/ -AccessibleRelation ** -Accessible_getRelationSet (Accessible *obj) +int +SPI_init (void) { - return NULL; -} + if (SPI_inited) + { + return 1; + } -/** - * Accessible_getRole: - * @obj: a pointer to the #Accessible object on which to operate. - * - * Get the UI role of an #Accessible object. - * - * Returns: a UTF-8 string indicating the UI role of the #Accessible object. - * - **/ -char * -Accessible_getRole (Accessible *obj) -{ - return ""; -} + SPI_inited = TRUE; -/** - * Accessible_getStateSet: - * - * Not Yet Implemented. - * - * Returns: a pointer to an #AccessibleStateSet representing the object's current state. - **/ -AccessibleStateSet * -Accessible_getStateSet (Accessible *obj) -{ - return NULL; -} + CORBA_exception_init (&ev); -/* Interface query methods */ + registry = cspi_init (); -/** - * Accessible_isAction: - * @obj: a pointer to the #Accessible instance to query. - * - * Query whether the specified #Accessible implements #AccessibleAction. - * Not Yet Implemented. - * - * Returns: #TRUE if @obj implements the #AccessibleAction interface, - * #FALSE otherwise. - **/ -boolean -Accessible_isAction (Accessible *obj) -{ - return FALSE; -} + g_atexit (cspi_cleanup); -/** - * Accessible_isComponent: - * @obj: a pointer to the #Accessible instance to query. - * - * Query whether the specified #Accessible implements #AccessibleComponent. - * - * Returns: #TRUE if @obj implements the #AccessibleComponent interface, - * #FALSE otherwise. - **/ -boolean -Accessible_isComponent (Accessible *obj) -{ - Bonobo_Unknown iface = - Accessibility_Accessible_queryInterface (*obj, - "IDL:Accessibility/Component:1.0", - &ev); - return (iface != NULL) ? TRUE : FALSE; + /* fprintf (stderr, "registry=%x\n", (int) registry); */ + + if ((registry != CORBA_OBJECT_NIL) && (cspi_ping (registry))) + return 0; + else + return 2; } /** - * Accessible_isEditableText: - * @obj: a pointer to the #Accessible instance to query. + * SPI_event_main: * - * Query whether the specified #Accessible implements #AccessibleEditableText. - * Not Yet Implemented. + * Starts/enters the main event loop for the SPI services. + * + * (NOTE: This method does not return control, it is exited via a call to + * SPI_event_quit () from within an event handler). * - * Returns: #TRUE if @obj implements the #AccessibleEditableText interface, - * #FALSE otherwise. **/ -boolean -Accessible_isEditableText (Accessible *obj) +void +SPI_event_main (void) { - return FALSE; + cspi_main (); } /** - * Accessible_isHypertext: - * @obj: a pointer to the #Accessible instance to query. - * - * Query whether the specified #Accessible implements #AccessibleHypertext. - * Not Yet Implemented. + * SPI_event_quit: * - * Returns: #TRUE if @obj implements the #AccessibleHypertext interface, - * #FALSE otherwise. + * Quits the last main event loop for the SPI services, + * see SPI_event_main **/ -boolean -Accessible_isHypertext (Accessible *obj) +void +SPI_event_quit (void) { - return FALSE; + cspi_main_quit (); } /** - * Accessible_isImage: - * @obj: a pointer to the #Accessible instance to query. + * SPI_eventIsReady: * - * Query whether the specified #Accessible implements #AccessibleImage. - * Not Yet Implemented. - * - * Returns: #TRUE if @obj implements the #AccessibleImage interface, - * #FALSE otherwise. -**/ -boolean -Accessible_isImage (Accessible *obj) -{ - return FALSE; -} - -/** - * Accessible_isSelection: - * @obj: a pointer to the #Accessible instance to query. + * Checks to see if an SPI event is waiting in the event queue. + * Used by clients that don't wish to use SPI_event_main(). * - * Query whether the specified #Accessible implements #AccessibleSelection. * Not Yet Implemented. * - * Returns: #TRUE if @obj implements the #AccessibleSelection interface, - * #FALSE otherwise. -**/ -boolean -Accessible_isSelection (Accessible *obj) -{ - return FALSE; -} - -/** - * Accessible_isTable: - * @obj: a pointer to the #Accessible instance to query. - * - * Query whether the specified #Accessible implements #AccessibleTable. - * Not Yet Implemented. + * Returns: #TRUE if an event is waiting, otherwise #FALSE. * - * Returns: #TRUE if @obj implements the #AccessibleTable interface, - * #FALSE otherwise. -**/ -boolean -Accessible_isTable (Accessible *obj) + **/ +SPIBoolean +SPI_eventIsReady (void) { return FALSE; } /** - * Accessible_isText: - * @obj: a pointer to the #Accessible instance to query. - * - * Query whether the specified #Accessible implements #AccessibleText. - * Not Yet Implemented. + * SPI_nextEvent: + * @waitForEvent: a #SPIBoolean indicating whether to block or not. * - * Returns: #TRUE if @obj implements the #AccessibleText interface, - * #FALSE otherwise. -**/ -boolean -Accessible_isText (Accessible *obj) -{ - return FALSE; -} - -/** - * Accessible_getAction: + * Gets the next event in the SPI event queue; blocks if no event + * is pending and @waitForEvent is #TRUE. + * Used by clients that don't wish to use SPI_event_main(). * * Not Yet Implemented. * + * Returns: the next #AccessibleEvent in the SPI event queue. **/ -AccessibleAction * -Accessible_getAction (Accessible *obj) +AccessibleEvent * +SPI_nextEvent (SPIBoolean waitForEvent) { return NULL; } -/** - * Accessible_getComponent: - * @obj: a pointer to the #Accessible instance to query. - * - * Get the #AccessibleComponent interface for an #Accessible. - * - * Returns: a pointer to an #AccessibleComponent interface instance, or - * NULL if @obj does not implement #AccessibleComponent. - **/ -AccessibleComponent * -Accessible_getComponent (Accessible *obj) +#ifdef PRINT_LEAKS +static void +report_leaked_ref (gpointer key, gpointer val, gpointer user_data) { - AccessibleComponent iface = - Accessibility_Accessible_queryInterface (*obj, - "IDL:Accessibility/Component:1.0", - &ev); - return Obj_Add (iface); -} + char *name, *role; + Accessible *a = (Accessible *) val; + + name = Accessible_getName (a); + if (cspi_exception ()) + { + name = NULL; + } -/** - * Accessible_queryInterface: - * @obj: a pointer to the #Accessible instance to query. - * @interface_name: a UTF-8 character string specifiying the requested interface. - * - * Query an #Accessible object to for a named interface. - * - * Returns: an instance of the named interface object, if it is implemented - * by @obj, or NULL otherwise. - * - **/ -GenericInterface * -Accessible_queryInterface (Accessible *obj, char *interface_name) -{ - GenericInterface iface; - iface = Accessibility_Accessible_queryInterface (*obj, - interface_name, - &ev); - return (iface != NULL) ? Obj_Add (iface) : NULL; -} + role = Accessible_getRoleName (a); + if (cspi_exception ()) + { + role = NULL; + } -/* - * - * AccessibleApplication function prototypes - * - */ + fprintf (stderr, "leaked %d references to object %s, role %s %p\n", + a->ref_count, name ? name : "", role ? role : "", a); -/** - * AccessibleApplication_ref: - * @obj: a pointer to the #AccessibleApplication on which to operate. - * - * Increment the reference count for an #AccessibleApplication. - * - * Returns: (no return code implemented yet). - * - **/ -int -AccessibleApplication_ref (AccessibleApplication *obj) -{ - Accessibility_Application_ref (*obj, &ev); - return 0; + SPI_freeString (name); } +#endif /** - * AccessibleApplication_unref: - * @obj: a pointer to the #AccessibleApplication object on which to operate. - * - * Decrement the reference count for an #AccessibleApplication. + * SPI_exit: * - * Returns: (no return code implemented yet). + * Disconnects from the Accessibility Registry and releases + * any floating resources. Call only once at exit. * + * Returns: 0 if there were no leaks, otherwise non zero. **/ int -AccessibleApplication_unref (AccessibleApplication *obj) +SPI_exit (void) { - Accessibility_Application_unref (*obj, &ev); - return 0; -} + int leaked; -/** - * AccessibleApplication_getToolkitName: - * @obj: a pointer to the #AccessibleApplication to query. - * - * Get the name of the UI toolkit used by an #AccessibleApplication. - * - * Returns: a UTF-8 string indicating which UI toolkit is - * used by an application. - * - **/ -char * -AccessibleApplication_getToolkitName (AccessibleApplication *obj) -{ - return Accessibility_Application__get_toolkitName (*obj, &ev); -} + if (!SPI_inited) + { + return 0; + } -/** - * AccessibleApplication_getVersion: - * @obj: a pointer to the #AccessibleApplication being queried. - * - * Get the version of the at-spi bridge exported by an - * #AccessibleApplication instance. - * - * Returns: a UTF-8 string indicating the application's - * at-spi version. - * - **/ -char * -AccessibleApplication_getVersion (AccessibleApplication *obj) -{ - return Accessibility_Application__get_version (*obj, &ev); -} + SPI_inited = FALSE; -/** - * AccessibleApplication_getID: - * @obj: a pointer to the #AccessibleApplication being queried. - * - * Get the unique ID assigned by the Registry to an - * #AccessibleApplication instance. - * (Not Yet Implemented by the registry). - * - * Returns: a unique #long integer associated with the application - * by the Registry, or 0 if the application is not registered. -long -AccessibleApplication_getID (AccessibleApplication *obj) -{ - return Accessibility_Application__get_id (*obj, &ev); + if (live_refs) + { + leaked = g_hash_table_size (live_refs); +#ifdef DEBUG_OBJECTS + fprintf (stderr, "Leaked %d SPI handles\n", leaked); + +#define PRINT_LEAKS +#ifdef PRINT_LEAKS + g_hash_table_foreach (live_refs, report_leaked_ref, NULL); +#endif + +#endif + } + else + { + leaked = 0; + } + + cspi_cleanup (); + + return leaked; } /** - * AccessibleApplication_pause: - * - * Attempt to pause the application (used when client event queue is - * over-full). - * Not Yet Implemented. - * - * Returns: #TRUE if the application was paused successfully, #FALSE otherwise. + * SPI_freeString: + * @s: a character string returned from another at-spi call. * + * Free a character string returned from an at-spi call. Clients of + * at-spi should use this function instead of free () or g_free(). + * A NULL string @s will be silently ignored. + * This API should not be used to free strings + * from other libraries or allocated by the client. **/ -boolean -AccessibleApplication_pause (AccessibleApplication *obj) +void +SPI_freeString (char *s) { - return FALSE; + if (s) + { + CORBA_free (s); + } } /** - * AccessibleApplication_resume: + * SPI_freeRect: + * @r: a pointer to an SPIRect returned from another at-spi call. * - * Attempt to resume the application (used after #AccessibleApplication_pause). - * Not Yet Implemented. - * - * Returns: #TRUE if application processing resumed successfully, #FALSE otherwise. + * 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. * + * @Since: AT-SPI 1.6 **/ -boolean -AccessibleApplication_resume (AccessibleApplication *obj) +void +SPI_freeRect (SPIRect *r) { - return FALSE; + 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); + } } -/* - * - * AccessibleComponent function implementations - * - */ - /** - * AccessibleComponent_ref: - * @obj: a pointer to an object implementing #AccessibleComponent on which to operate. - * - * Increment the reference count for an #AccessibleComponent. - * - * Returns: (no return code implemented yet). + * SPI_dupString: + * @s: a UTF-8 string to be duplicated + * + * @Since: AT-SPI 1.4 * + * Returns: a duplicate of the string passed as a parameter, which should + * be freed via SPI_freeString after use. **/ -int -AccessibleComponent_ref (AccessibleComponent *obj) +char * +SPI_dupString (char *s) { - Accessibility_Component_ref (*obj, &ev); - return 0; + if (s) + { + return CORBA_string_dup (s); + } + else + return NULL; } /** - * AccessibleComponent_unref: - * @obj: a pointer to the object implementing #AccessibleComponent on which to operate. + * SPI_exceptionHandlerPush: + * @handler: an #SPIExceptionHandler to install as the first code to deal with exceptions. * - * Decrement the reference count for an #AccessibleComponent. + * Install a client-side handler for #SPIException instances, which can see and handle any + * exceptions before chaining them to the next exception handler in the stack. * - * Returns: (no return code implemented yet). + * @Since: AT-SPI 1.4 * + * Returns %TRUE if the result succeeded, %FALSE if @hander could not be registered. **/ -int -AccessibleComponent_unref (AccessibleComponent *obj) +SPIBoolean SPI_exceptionHandlerPush (SPIExceptionHandler *handler) { - Accessibility_Component_unref (*obj, &ev); - return 0; + if (!exception_handlers) + exception_handlers = g_queue_new (); + g_queue_push_head (exception_handlers, handler); + return TRUE; } /** - * AccessibleComponent_contains: - * @obj: a pointer to the #AccessibleComponent to query. - * @x: a #long specifying the x coordinate in question. - * @y: a #long specifying the y coordinate in question. - * @ctype: the desired coordinate system of the point (@x, @y) - * (e.g. COORD_TYPE_WINDOW, COORD_TYPE_SCREEN). + * SPI_exceptionHandlerPop: + * + * Remove/pop an #SPIExceptionHandler off the error handler stack and return the new handler. * - * Query whether a given #AccessibleComponent contains a particular point. + * @Since: AT-SPI 1.4 * + * Returns the #SPIExceptionHandler which is now at the top of the error handler stack after the call. **/ -boolean -AccessibleComponent_contains (AccessibleComponent *obj, - long x, - long y, - AccessibleCoordType ctype) +SPIExceptionHandler* SPI_exceptionHandlerPop (void) { - return Accessibility_Component_contains (*obj, - (CORBA_long) x, - (CORBA_long) y, - ctype, - &ev); + return (SPIExceptionHandler *) g_queue_pop_head (exception_handlers); } /** - * AccessibleComponent_getAccessibleAtPoint: - * @obj: a pointer to the #AccessibleComponent to query. - * @x: a #long specifying the x coordinate of the point in question. - * @y: a #long specifying the y coordinate of the point in question. - * @ctype: the coordinate system of the point (@x, @y) - * (e.g. COORD_TYPE_WINDOW, COORD_TYPE_SCREEN). + * SPIException_getSourceType: + * @err: the exception being queried + * + * Get the #SPIExceptionType of an exception which has been thrown. * - * Get the accessible child at a given coordinate within an #AccessibleComponent. + * @Since: AT-SPI 1.4 * - * Returns: a pointer to an #Accessible child of the specified component which - * contains the point (@x, @y), or NULL of no child contains the point. + * Returns: the #SPIExceptionType corresponding to exception @err. **/ -Accessible * -AccessibleComponent_getAccessibleAtPoint (AccessibleComponent *obj, - long x, - long y, - AccessibleCoordType ctype) +SPIExceptionType SPIException_getSourceType (SPIException *err) { - Accessible child; - child = Accessibility_Component_getAccessibleAtPoint(*obj, - (CORBA_long) x, - (CORBA_long) y, - ctype, - &ev); - return (child != NULL) ? Obj_Add (child) : NULL; + if (err) + return err->type; + else + return SPI_EXCEPTION_SOURCE_UNSPECIFIED; } /** - * AccessibleComponent_getExtents: - * @obj: a pointer to the #AccessibleComponent to query. - * @x: a pointer to a #long into which the minimum x coordinate will be returned. - * @y: a pointer to a #long into which the minimum y coordinate will be returned. - * @width: a pointer to a #long into which the x extents (width) will be returned. - * @height: a pointer to a #long into which the y extents (height) will be returned. - * @ctype: the desired coordinate system into which to return the results, - * (e.g. COORD_TYPE_WINDOW, COORD_TYPE_SCREEN). + * SPIException_getExceptionCode: + * @err: the #SPIException being queried. * - * Get the bounding box of the specified #AccessibleComponent. + * Get the #SPIExceptionCode telling what type of exception condition has occurred. * + * @Since: AT-SPI 1.4 + * + * Returns: the #SPIExceptionCode corresponding to exception @err. **/ -void -AccessibleComponent_getExtents (AccessibleComponent *obj, - long *x, - long *y, - long *width, - long *height, - AccessibleCoordType ctype) -{ - /* TODO: remove assumption that CORBA_long == long in typecast */ - Accessibility_Component_getExtents (*obj, - (CORBA_long *) x, - (CORBA_long *) y, - (CORBA_long *) width, - (CORBA_long *) height, - ctype, - &ev); +SPIExceptionCode SPIException_getExceptionCode (SPIException *err) +{ + return err->code; } /** - * AccessibleComponent_getPosition: - * @obj: a pointer to the #AccessibleComponent to query. - * @x: a pointer to a #long into which the minimum x coordinate will be returned. - * @y: a pointer to a #long into which the minimum y coordinate will be returned. - * @ctype: the desired coordinate system into which to return the results, - * (e.g. COORD_TYPE_WINDOW, COORD_TYPE_SCREEN). + * SPIAccessibleException_getSource: + * @err: the #SPIException being queried. * - * Get the minimum x and y coordinates of the specified #AccessibleComponent. + * Get the identity of the object which threw an exception. * + * @Since: AT-SPI 1.4 + * + * Returns: a pointer to the #Accessible object which threw the exception. **/ -void -AccessibleComponent_getPosition (AccessibleComponent *obj, - long *x, - long *y, - AccessibleCoordType ctype) +Accessible* SPIAccessibleException_getSource (SPIException *err) { - Accessibility_Component_getPosition (*obj, - (CORBA_long *) x, - (CORBA_long *) y, - ctype, - &ev); + if (err->type == SPI_EXCEPTION_SOURCE_ACCESSIBLE) + return cspi_object_get_ref (err->source, FALSE); + return NULL; } /** - * AccessibleComponent_getSize: - * @obj: a pointer to the #AccessibleComponent to query. - * @width: a pointer to a #long into which the x extents (width) will be returned. - * @height: a pointer to a #long into which the y extents (height) will be returned. + * SPIException_getDescription: + * @err: the #SPIException being queried. * - * Get the size of the specified #AccessibleComponent. + * Get a text description of the exception that has been thrown. + * Unfortunately these descriptions tend to be terse and limited in + * the detail which they can provide. * + * Returns: a brief character string describing the exception. **/ -void -AccessibleComponent_getSize (AccessibleComponent *obj, - long *width, - long *height) -{ - Accessibility_Component_getSize (*obj, - (CORBA_long *) width, - (CORBA_long *) height, - &ev); -} - -/* Not Yet Implemented */ -void -AccessibleComponent_grabFocus (AccessibleComponent *obj) +char* SPIException_getDescription (SPIException *err) { - ; + /* TODO: friendlier error messages? */ + if (err->ev) + return CORBA_exception_id (err->ev); + return NULL; }