X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=cspi%2Fspi_main.c;h=ad9bd7ba710d152ad800fdd69eac7a36393d1d08;hb=ebd9b297363b8b3bd6708e6f0c6c7673e5cc32d6;hp=fcf61d3d24e39030bc2cc48d7dc232bc712534a4;hpb=fdf87471b3d56d7a66d31f33c1ef3d631e9ef51c;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/cspi/spi_main.c b/cspi/spi_main.c index fcf61d3..ad9bd7b 100644 --- a/cspi/spi_main.c +++ b/cspi/spi_main.c @@ -1,313 +1,366 @@ -#include -#include -#include "spi.h" - -static CORBA_Environment ev; -static AccessibilityRegistry registry; - -Accessible * -Obj_Add (Accessible object) -{ - /* TODO: keep list of live object refs */ - Accessible *oref = g_malloc (sizeof (Accessible)); - *oref = object; - return oref; -} - /* * * Basic SPI initialization and event loop function prototypes * */ +#include +#include +#include -int -SPI_init (void) +#undef DEBUG_OBJECTS + +static CORBA_Environment ev = { 0 }; +static Accessibility_Registry registry = CORBA_OBJECT_NIL; +static GHashTable *live_refs = NULL; + +static guint +cspi_object_hash (gconstpointer key) { - int argc = 0; - CORBA_Object oclient; - char *obj_id; + CORBA_Object object = (CORBA_Object) key; + guint retval; + + retval = CORBA_Object_hash (object, 0, &ev); - CORBA_exception_init(&ev); + return retval; +} - if (!bonobo_init (&argc, NULL)) - { - g_error ("Could not initialize Bonobo"); - } +static gboolean +cspi_object_equal (gconstpointer a, gconstpointer b) +{ + CORBA_Object objecta = (CORBA_Object) a; + CORBA_Object objectb = (CORBA_Object) b; + gboolean retval; - obj_id = "OAFIID:Accessibility_Registry:proto0.1"; + retval = CORBA_Object_is_equivalent (objecta, objectb, &ev); - 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); - } + return retval; +} - if (CORBA_Object_is_nil (oclient, &ev)) - { - g_error ("Could not locate registry"); - exit(-1); - } +static void +cspi_object_release (gpointer value) +{ + Accessible *a = (Accessible *) value; - registry = (Accessibility_Registry) oclient; +#ifdef DEBUG_OBJECTS + g_print ("releasing %p => %p\n", a, a->objref); +#endif - bonobo_activate (); + cspi_release_unref (a->objref); - return 0; -} + memset (a, 0xaa, sizeof (Accessible)); + a->ref_count = -1; -void -SPI_event_main (boolean isGNOMEApp) -{ - if (isGNOMEApp) bonobo_main(); - else CORBA_ORB_run (bonobo_orb(), &ev); +#ifndef DEBUG_OBJECTS + free (a); +#endif } -/* Not Yet Implemented */ -boolean -SPI_eventIsReady () +SPIBoolean +cspi_accessible_is_a (Accessible *obj, + const char *interface_name) { - return FALSE; -} + SPIBoolean retval; + Bonobo_Unknown unknown; -/* Not Yet Implemented */ -AccessibleEvent * -SPI_nextEvent (boolean waitForEvent) -{ - return NULL; -} + if (obj == NULL) + { + return FALSE; + } -void -SPI_exit (void) -{ - exit(0); + unknown = Bonobo_Unknown_queryInterface (CSPI_OBJREF (obj), + interface_name, cspi_ev ()); + + if (ev._major != CORBA_NO_EXCEPTION) + { + g_error ("Exception '%s' checking if is '%s'", + cspi_exception_get_text (), + interface_name); + } + + if (unknown != CORBA_OBJECT_NIL) + { + retval = TRUE; + cspi_release_unref (unknown); + } + else + { + retval = FALSE; + } + + return retval; } -AccessibleEventListener * -CreateEventListener (AccessibleEventListenerCB callback) +static GHashTable * +cspi_get_live_refs (void) { - AccessibleEventListener *listener = accessible_event_listener_new (); - if (callback) + if (!live_refs) { - accessible_event_listener_add_callback (listener, callback); + live_refs = g_hash_table_new_full (cspi_object_hash, + cspi_object_equal, + NULL, + cspi_object_release); } - return listener; + return live_refs; } -boolean -EventListener_addCallback (AccessibleEventListener *listener, - AccessibleEventListenerCB callback) +CORBA_Environment * +cspi_ev (void) { - accessible_event_listener_add_callback (listener, callback); - return TRUE; + /* This method is an ugly hack */ + return &ev; } -boolean -EventListener_removeCallback (AccessibleEventListener *listener, - AccessibleEventListenerCB callback) +Accessibility_Registry +cspi_registry (void) { - accessible_event_listener_remove_callback (listener, callback); - return TRUE; + return registry; } -/* - * - * Global functions serviced by the registry - * - */ - -boolean -RegisterGlobalEventListener (AccessibleEventListener *listener, - char *eventType) +SPIBoolean +cspi_exception (void) { - Accessibility_Registry_registerGlobalEventListener ( - registry, - (Accessibility_EventListener) - bonobo_object_corba_objref (bonobo_object (listener)), - eventType, - &ev); + SPIBoolean retval; if (ev._major != CORBA_NO_EXCEPTION) { - return FALSE; + CORBA_exception_free (&ev); + retval = TRUE; } else { - return TRUE; + retval = FALSE; } -} -int -GetDesktopCount () -{ - return Accessibility_Registry_getDesktopCount (registry, &ev); + return retval; } -Accessible -*getDesktop (int n) +Accessible * +cspi_object_add (CORBA_Object corba_object) { - return Obj_Add (Accessibility_Registry_getDesktop (registry, (CORBA_short) n, &ev)); -} + Accessible *ref; -int -getDesktopList (Accessible **list) -{ - *list = NULL; - return 0; + if (corba_object == CORBA_OBJECT_NIL) + { + ref = NULL; + } + else if (!cspi_check_ev ("pre method check")) + { + ref = NULL; + } + else + { + if ((ref = g_hash_table_lookup (cspi_get_live_refs (), corba_object))) + { + g_assert (ref->ref_count > 0); + ref->ref_count++; + cspi_release_unref (corba_object); +#ifdef DEBUG_OBJECTS + g_print ("returning cached %p => %p\n", ref, ref->objref); +#endif + } + else + { + ref = malloc (sizeof (Accessible)); + +#ifdef DEBUG_OBJECTS + g_print ("allocating %p => %p\n", ref, corba_object); +#endif + + ref->objref = corba_object; + ref->ref_count = 1; + + g_hash_table_insert (cspi_get_live_refs (), ref->objref, ref); + } + } + + return ref; } -/* Not Yet Implemented */ void -registerKeystrokeListener (KeystrokeListener *listener) +cspi_object_ref (Accessible *accessible) { - ; + g_return_if_fail (accessible != NULL); + + accessible->ref_count++; } -/* Not Yet Implemented */ void -generateKeyEvent (long keyCode, long meta) +cspi_object_unref (Accessible *accessible) { - ; + if (accessible == NULL) + { + return; + } + + if (--accessible->ref_count == 0) + { + g_hash_table_remove (cspi_get_live_refs (), accessible->objref); + } } -/* Not Yet Implemented */ -void -generateMouseEvent (long x, long y, char *name) +static void +cspi_cleanup (void) { - ; -} + GHashTable *refs; -/* - * - * Accessible function prototypes - * - */ + refs = live_refs; + live_refs = NULL; + if (refs) + { + g_hash_table_destroy (refs); + } -int -Accessible_ref (Accessible *obj) -{ - Accessibility_Accessible_ref (*obj, &ev); - return 0; + if (registry != CORBA_OBJECT_NIL) + { + cspi_release_unref (registry); + registry = CORBA_OBJECT_NIL; + } } +static gboolean SPI_inited = FALSE; +/** + * SPI_init: + * + * Connects to the accessibility registry and initializes the SPI. + * + * Returns: 0 on success, otherwise an integer error code. + **/ int -Accessible_unref (Accessible *obj) +SPI_init (void) { - Accessibility_Accessible_unref (*obj, &ev); - return 0; -} + if (SPI_inited) + { + return 1; + } -char * -Accessible_getName (Accessible *obj) -{ - return Accessibility_Accessible__get_name (*obj, &ev); -} + SPI_inited = TRUE; -char * -Accessible_getDescription (Accessible *obj) -{ - return Accessibility_Accessible__get_description (*obj, &ev); -} + CORBA_exception_init (&ev); -Accessible * -Accessible_getParent (Accessible *obj) -{ - return Obj_Add (Accessibility_Accessible__get_parent (*obj, &ev)); -} + registry = cspi_init (); -long -Accessible_getChildCount (Accessible *obj) -{ - return Accessibility_Accessible__get_childCount (*obj, &ev); -} - -Accessible * -Accessible_getChildAtIndex (Accessible *obj, - long childIndex) -{ - return Obj_Add (Accessibility_Accessible_getChildAtIndex (*obj, childIndex, &ev)); + g_atexit (cspi_cleanup); + + return 0; } -long -Accessible_getIndexInParent (Accessible *obj) +/** + * SPI_event_main: + * + * 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). + * + **/ +void +SPI_event_main (void) { - return Accessibility_Accessible_getIndexInParent (*obj, &ev); + cspi_main (); } -/* Not Yet Implemented */ -AccessibleRelation ** -Accessible_getRelationSet (Accessible *obj) +/** + * SPI_event_quit: + * + * Quits the last main event loop for the SPI services, + * see SPI_event_main + **/ +void +SPI_event_quit (void) { - return NULL; + cspi_main_quit (); } -/* Not Yet Implemented */ -char * -Accessible_getRole (Accessible *obj) +/** + * SPI_eventIsReady: + * + * 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. + * + **/ +SPIBoolean +SPI_eventIsReady () { - return ""; + return FALSE; } -/* Not Yet Implemented */ -AccessibleStateSet * -Accessible_getStateSet (Accessible *obj) +/** + * SPI_nextEvent: + * @waitForEvent: a #SPIBoolean indicating whether to block or not. + * + * 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. + **/ +AccessibleEvent * +SPI_nextEvent (SPIBoolean waitForEvent) { return NULL; } - -/* +/** + * SPI_exit: * - * AccessibleApplication function prototypes + * 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_ref (AccessibleApplication *obj) +SPI_exit (void) { - Accessibility_Application_ref (*obj, &ev); - return 0; -} + int leaked; -int -AccessibleApplication_unref (AccessibleApplication *obj) -{ - Accessibility_Application_unref (*obj, &ev); - return 0; -} + if (!SPI_inited) + { + return 0; + } -char * -AccessibleApplication_getToolkitName (AccessibleApplication *obj) -{ - return Accessibility_Application__get_toolkitName (*obj, &ev); -} + SPI_inited = FALSE; -char * -AccessibleApplication_getVersion (AccessibleApplication *obj) -{ - return Accessibility_Application__get_version (*obj, &ev); -} + if (live_refs) + { + leaked = g_hash_table_size (live_refs); + } + else + { + leaked = 0; + } -long -AccessibleApplication_getID (AccessibleApplication *obj) -{ - return Accessibility_Application__get_id (*obj, &ev); -} +#ifdef DEBUG_OBJECTS + if (leaked) + { + fprintf (stderr, "Leaked %d SPI handles\n", leaked); + } +#endif -/* Not Yet Implemented */ -boolean -AccessibleApplication_pause (AccessibleApplication *obj) -{ - return FALSE; + cspi_cleanup (); + + fprintf (stderr, "bye-bye!\n"); + + return leaked; } -/* Not Yet Implemented */ -boolean -AccessibleApplication_resume (AccessibleApplication *obj) +/** + * 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(). + * This API should not be used to free strings + * from other libraries or allocated by the client. + **/ +void +SPI_freeString (char *s) { - return FALSE; + CORBA_free (s); } -