X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=cspi%2Fspi_main.c;h=b8e11bd1c5cde99e772cb2d5d9cc51fb3f209a95;hb=c90a8c8269d6e338e19519fa5f7b01098615ec7a;hp=36da0cdad6e1cdd42130816ee7842ee239ff6777;hpb=aa10b95a81858d2cbca663c501b00294ab54ef31;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/cspi/spi_main.c b/cspi/spi_main.c index 36da0cd..b8e11bd 100644 --- a/cspi/spi_main.c +++ b/cspi/spi_main.c @@ -31,12 +31,14 @@ #include #include #include +#include "spi.h" #undef DEBUG_OBJECTS -static CORBA_Environment ev = { 0 }; +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) @@ -52,7 +54,7 @@ cspi_object_equal (gconstpointer a, gconstpointer b) CORBA_Object objecta = (CORBA_Object) a; CORBA_Object objectb = (CORBA_Object) b; - return CORBA_Object_is_equivalent (objecta, objectb, &ev); + return CORBA_Object_is_equivalent (objecta, objectb, cspi_ev ()); } static void @@ -77,6 +79,34 @@ cspi_object_release (gpointer value) #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 */ +} + SPIBoolean cspi_accessible_is_a (Accessible *accessible, const char *interface_name) @@ -127,6 +157,12 @@ cspi_get_live_refs (void) } CORBA_Environment * +cspi_peek_ev (void) +{ + return &ev; +} + +CORBA_Environment * cspi_ev (void) { CORBA_exception_init (&ev); @@ -232,6 +268,7 @@ cspi_object_borrow (CORBA_Object corba_object) void cspi_object_return (Accessible *accessible) { + int old_ref_count; g_return_if_fail (accessible != NULL); if (!accessible->on_loan || @@ -242,8 +279,17 @@ cspi_object_return (Accessible *accessible) else /* Convert to a permanant ref */ { accessible->on_loan = FALSE; + old_ref_count = accessible->ref_count; accessible->objref = cspi_dup_ref (accessible->objref); - accessible->ref_count--; + if (old_ref_count != accessible->ref_count && + accessible->ref_count == 1) + { + cspi_object_unref (accessible); + } + else + { + accessible->ref_count--; + } } } @@ -284,6 +330,7 @@ cspi_object_unref (Accessible *accessible) return; } + g_return_if_fail (accessible->ref_count > 0); if (--accessible->ref_count == 0) { g_hash_table_remove (cspi_get_live_refs (), accessible->objref); @@ -295,6 +342,8 @@ cspi_cleanup (void) { GHashTable *refs; + cspi_streams_close_all (); + refs = live_refs; live_refs = NULL; if (refs) @@ -316,7 +365,7 @@ static gboolean SPI_inited = FALSE; * * Connects to the accessibility registry and initializes the SPI. * - * Returns: 0 on success, otherwise an integer error code. + * Returns: 0 on success, otherwise an integer error code. **/ int SPI_init (void) @@ -333,8 +382,13 @@ SPI_init (void) registry = cspi_init (); g_atexit (cspi_cleanup); - - return 0; + + /* fprintf (stderr, "registry=%x\n", (int) registry); */ + + if ((registry != CORBA_OBJECT_NIL) && (cspi_ping (registry))) + return 0; + else + return 2; } /** @@ -376,7 +430,7 @@ SPI_event_quit (void) * **/ SPIBoolean -SPI_eventIsReady () +SPI_eventIsReady (void) { return FALSE; } @@ -399,6 +453,7 @@ SPI_nextEvent (SPIBoolean waitForEvent) return NULL; } +#ifdef PRINT_LEAKS static void report_leaked_ref (gpointer key, gpointer val, gpointer user_data) { @@ -422,7 +477,7 @@ report_leaked_ref (gpointer key, gpointer val, gpointer user_data) SPI_freeString (name); } - +#endif /** * SPI_exit: @@ -447,27 +502,23 @@ SPI_exit (void) 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; } -#ifdef DEBUG_OBJECTS - if (leaked) - { - fprintf (stderr, "Leaked %d SPI handles\n", leaked); - } -#endif - cspi_cleanup (); - fprintf (stderr, "bye-bye!\n"); - return leaked; } @@ -489,3 +540,147 @@ SPI_freeString (char *s) CORBA_free (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. + * + * @Since: AT-SPI 1.6 + **/ +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); + } +} + +/** + * 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. + **/ +char * +SPI_dupString (char *s) +{ + if (s) + { + return CORBA_string_dup (s); + } + else + return NULL; +} + +/** + * SPI_exceptionHandlerPush: + * @handler: an #SPIExceptionHandler to install as the first code to deal with exceptions. + * + * 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. + * + * @Since: AT-SPI 1.4 + * + * Returns %TRUE if the result succeeded, %FALSE if @hander could not be registered. + **/ +SPIBoolean SPI_exceptionHandlerPush (SPIExceptionHandler *handler) +{ + if (!exception_handlers) + exception_handlers = g_queue_new (); + g_queue_push_head (exception_handlers, handler); + return TRUE; +} + +/** + * SPI_exceptionHandlerPop: + * + * Remove/pop an #SPIExceptionHandler off the error handler stack and return the new handler. + * + * @Since: AT-SPI 1.4 + * + * Returns the #SPIExceptionHandler which is now at the top of the error handler stack after the call. + **/ +SPIExceptionHandler* SPI_exceptionHandlerPop (void) +{ + return (SPIExceptionHandler *) g_queue_pop_head (exception_handlers); +} + +/** + * SPIException_getSourceType: + * @err: the exception being queried + * + * Get the #SPIExceptionType of an exception which has been thrown. + * + * @Since: AT-SPI 1.4 + * + * Returns: the #SPIExceptionType corresponding to exception @err. + **/ +SPIExceptionType SPIException_getSourceType (SPIException *err) +{ + if (err) + return err->type; + else + return SPI_EXCEPTION_SOURCE_UNSPECIFIED; +} + +/** + * SPIException_getExceptionCode: + * @err: the #SPIException being queried. + * + * Get the #SPIExceptionCode telling what type of exception condition has occurred. + * + * @Since: AT-SPI 1.4 + * + * Returns: the #SPIExceptionCode corresponding to exception @err. + **/ +SPIExceptionCode SPIException_getExceptionCode (SPIException *err) +{ + return err->code; +} + +/** + * SPIAccessibleException_getSource: + * @err: the #SPIException being queried. + * + * 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. + **/ +Accessible* SPIAccessibleException_getSource (SPIException *err) +{ + if (err->type == SPI_EXCEPTION_SOURCE_ACCESSIBLE) + return cspi_object_get_ref (err->source, FALSE); + return NULL; +} + +/** + * SPIException_getDescription: + * @err: the #SPIException being queried. + * + * 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. + **/ +char* SPIException_getDescription (SPIException *err) +{ + /* TODO: friendlier error messages? */ + if (err->ev) + return CORBA_exception_id (err->ev); + return NULL; +}