X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=libspi%2Fapplication.c;h=40e09c790163982f258e0a55a42cb2bb70531a00;hb=af73589b8f6efcd457290b11e183769918cf3294;hp=6bba3a412c1c6ef5b42ee075b24a130ebc2f7c52;hpb=838ffbd98cd6acfaad67fd6b3a08ac69b9f68f9d;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/libspi/application.c b/libspi/application.c index 6bba3a4..40e09c7 100644 --- a/libspi/application.c +++ b/libspi/application.c @@ -20,209 +20,351 @@ * Boston, MA 02111-1307, USA. */ -/* - * application.c: implements Application.idl - * - */ +/* application.c: implements SpiApplication.idl */ + +#include #include -#include #include +#include -/* - * This pulls the CORBA definitions for the "Accessibility::Accessible" server - */ -#include +/* Our parent Gtk object type */ +#define PARENT_TYPE SPI_ACCESSIBLE_TYPE -/* - * This pulls the definition for the BonoboObject (GObject Type) - */ -#include "application.h" +/* A pointer to our parent object class */ +static SpiAccessibleClass *spi_application_parent_class; -/* - * Our parent Gtk object type - */ -#define PARENT_TYPE ACCESSIBLE_TYPE +static SpiApplication *the_app; -/* - * A pointer to our parent object class - */ -static AccessibleClass *application_parent_class; +/* static methods */ -Accessibility_EventListener the_toolkit_listener; +static void notify_listeners (GList *listeners, + SpiAccessible *source, + Accessibility_Event *e); + +static const char *reverse_lookup_name_for_toolkit_event (char *toolkit_name); + +static const char * +lookup_toolkit_event_for_name (const char *generic_name) +{ + char *toolkit_specific_name; + SpiApplicationClass *klass = g_type_class_peek (SPI_APPLICATION_TYPE); +#ifdef SPI_DEBUG + fprintf (stderr, "looking for %s in hash table.\n", generic_name); +#endif + toolkit_specific_name = + (char *) g_hash_table_lookup (klass->toolkit_event_names, generic_name); +#ifdef SPI_DEBUG + fprintf (stderr, "generic event %s converted to %s\n", generic_name, toolkit_specific_name); +#endif + return toolkit_specific_name; +} /* * Implemented GObject::finalize */ static void -accessible_application_finalize (GObject *object) +spi_accessible_application_finalize (GObject *object) { - /* TODO: any necessary cleanup */ - Accessible *accessible = ACCESSIBLE (object); + GList *l; + SpiApplication *application = (SpiApplication *) object; + CORBA_Environment ev; + + CORBA_exception_init (&ev); - g_object_unref (accessible->atko); - accessible->atko = NULL; + for (l = application->toolkit_listeners; l; l = l->next) + { + CORBA_Object_release ((CORBA_Object) l->data, &ev); + } + + CORBA_exception_free (&ev); + + g_list_free (application->toolkit_listeners); + application->toolkit_listeners = NULL; - /* TODO: chain to parent class instead */ + g_print ("application finalize called\n"); + (G_OBJECT_CLASS (spi_application_parent_class))->finalize (object); } static CORBA_string impl_accessibility_application_get_toolkit_name (PortableServer_Servant servant, - CORBA_Environment *ev) + CORBA_Environment *ev) { - CORBA_char *retval; - Application *application = APPLICATION (bonobo_object_from_servant (servant)); - retval = CORBA_string_dup (atk_get_toolkit_name ()); - return retval; + return CORBA_string_dup (atk_get_toolkit_name ()); } static CORBA_string impl_accessibility_application_get_version (PortableServer_Servant servant, - CORBA_Environment *ev) + CORBA_Environment *ev) { - CORBA_char *retval; - Application *application = APPLICATION (bonobo_object_from_servant (servant)); - retval = CORBA_string_dup (atk_get_toolkit_version ()); - return retval; + return CORBA_string_dup (atk_get_toolkit_version ()); } -static CORBA_string +static CORBA_long impl_accessibility_application_get_id (PortableServer_Servant servant, - CORBA_Environment *ev) + CORBA_Environment *ev) { - CORBA_char *retval; - Application *application = APPLICATION (bonobo_object_from_servant (servant)); - retval = CORBA_string_dup (application->id); - return retval; + SpiApplication *application = SPI_APPLICATION ( + bonobo_object_from_servant (servant)); + + return application->id; } static void impl_accessibility_application_set_id (PortableServer_Servant servant, - const CORBA_char *id, + const CORBA_long id, CORBA_Environment *ev) { - Application *application = APPLICATION (bonobo_object_from_servant (servant)); + SpiApplication *application = SPI_APPLICATION ( + bonobo_object_from_servant (servant)); + application->id = id; } -#define APP_STATIC_BUFF_SZ 64 +static AtkObject * +get_atk_object_ref (GObject *gobject) +{ + AtkObject *aobject; + + if (ATK_IS_IMPLEMENTOR (gobject)) + { + aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject)); + } + else if (ATK_IS_OBJECT (gobject)) + { + aobject = ATK_OBJECT (gobject); + g_object_ref (G_OBJECT (aobject)); + } + else + { + aobject = NULL; + g_error ("received event from non-AtkImplementor"); + } + + return aobject; +} static gboolean -application_toolkit_listener (GSignalInvocationHint *signal_hint, - guint n_param_values, - const GValue *param_values, - gpointer data) +spi_application_object_event_listener (GSignalInvocationHint *signal_hint, + guint n_param_values, + const GValue *param_values, + gpointer data) { - Accessibility_Event *e = g_new0(Accessibility_Event, 1); - AtkObject *aobject; - GObject *gobject; - CORBA_Environment ev; - GSignalQuery signal_query; - gchar *name; - char sbuf[APP_STATIC_BUFF_SZ]; + Accessibility_Event e; + AtkObject *aobject; + SpiAccessible *source; + GSignalQuery signal_query; + gchar *event_name; + const char *generic_name; + g_return_val_if_fail (the_app != NULL, FALSE); + g_signal_query (signal_hint->signal_id, &signal_query); - name = signal_query.signal_name; - fprintf (stderr, "Received signal %s:%s\n", g_type_name (signal_query.itype), name); - /* TODO: move GTK dependency out of app.c into bridge */ - snprintf(sbuf, APP_STATIC_BUFF_SZ, "Gtk:%s:%s", g_type_name (signal_query.itype), name); + /* TODO: move GTK reference out of app.c into bridge */ + event_name = g_strdup_printf ("Gtk:%s:%s", + g_type_name (signal_query.itype), + signal_query.signal_name); + generic_name = reverse_lookup_name_for_toolkit_event (event_name); + + fprintf (stderr, "Received (object) signal %s maps to '%s'\n", + event_name, generic_name); + + g_free (event_name); + + g_return_val_if_fail (generic_name, FALSE); + + aobject = get_atk_object_ref (g_value_get_object (param_values + 0)); + + source = spi_accessible_new (aobject); + e.type = CORBA_string_dup (generic_name); + e.source = CORBA_OBJECT_NIL; + e.detail1 = 0; + e.detail2 = 0; + + notify_listeners (the_app->toolkit_listeners, source, &e); + + bonobo_object_unref (BONOBO_OBJECT (source)); + + g_object_unref (G_OBJECT (aobject)); + + return TRUE; +} + +static gboolean +spi_application_toolkit_event_listener (GSignalInvocationHint *signal_hint, + guint n_param_values, + const GValue *param_values, + gpointer data) +{ + Accessibility_Event e; + AtkObject *aobject; + SpiAccessible *source; + GSignalQuery signal_query; + char *event_name; + + g_return_val_if_fail (the_app != NULL, FALSE); + + g_signal_query (signal_hint->signal_id, &signal_query); + + /* TODO: move GTK reference out of app.c into bridge */ + event_name = g_strdup_printf ("Gtk:%s:%s", + g_type_name (signal_query.itype), + signal_query.signal_name); + +#ifdef SPI_DEBUG + fprintf (stderr, "Received signal %s\n", event_name); +#endif + + aobject = get_atk_object_ref (g_value_get_object (param_values + 0)); + + source = spi_accessible_new (aobject); + e.type = CORBA_string_dup (event_name); + e.source = CORBA_OBJECT_NIL; + e.detail1 = 0; + e.detail2 = 0; + notify_listeners (the_app->toolkit_listeners, source, &e); + + bonobo_object_unref (BONOBO_OBJECT (source)); + g_object_unref (G_OBJECT (aobject)); + + g_free (event_name); - gobject = g_value_get_object (param_values + 0); - /* notify the actual listeners */ - if (ATK_IS_IMPLEMENTOR (gobject)) - { - aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject)); - e->type = CORBA_string_dup (sbuf); - e->source = bonobo_object_corba_objref (bonobo_object (accessible_new (aobject))); - e->detail1 = 0; - e->detail2 = 0; - Accessibility_EventListener_notifyEvent (the_toolkit_listener, e, &ev); - g_object_unref (aobject); - } return TRUE; } static void impl_accessibility_application_register_toolkit_event_listener (PortableServer_Servant servant, - Accessibility_EventListener listener, + Accessibility_EventListener listener, const CORBA_char *event_name, CORBA_Environment *ev) { - guint listener_id; - listener_id = - atk_add_global_event_listener (application_toolkit_listener, event_name); - the_toolkit_listener = CORBA_Object_duplicate (listener, ev); + guint spi_listener_id; + spi_listener_id = + atk_add_global_event_listener (spi_application_toolkit_event_listener, event_name); + the_app->toolkit_listeners = g_list_append (the_app->toolkit_listeners, + CORBA_Object_duplicate (listener, ev)); #ifdef SPI_DEBUG fprintf (stderr, "registered %d for toolkit events named: %s\n", - listener_id, + spi_listener_id, + event_name); +#endif +} + +static void +impl_accessibility_application_register_object_event_listener (PortableServer_Servant servant, + Accessibility_EventListener listener, + const CORBA_char *event_name, + CORBA_Environment *ev) +{ + guint spi_listener_id = 0; + const char *toolkit_specific_event_name = + lookup_toolkit_event_for_name (event_name); + if (toolkit_specific_event_name) + { + spi_listener_id = + atk_add_global_event_listener (spi_application_object_event_listener, + toolkit_specific_event_name); + the_app->toolkit_listeners = g_list_append (the_app->toolkit_listeners, + CORBA_Object_duplicate (listener, ev)); + } +#ifdef SPI_DEBUG + fprintf (stderr, "registered %d for object events named: %s\n", + spi_listener_id, event_name); #endif } static void -application_class_init (ApplicationClass *klass) +notify_listeners (GList *listeners, SpiAccessible *source, Accessibility_Event *e) +{ + GList *l; + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + for (l = listeners; l; l = l->next) + { + Accessibility_EventListener listener = l->data; + + e->source = bonobo_object_dup_ref (BONOBO_OBJREF (source), &ev); + + Accessibility_EventListener_notifyEvent (listener, e, &ev); + /* + * when this (oneway) call completes, the CORBA refcount and + * Bonobo_Unknown refcount will be decremented by the recipient + */ + CORBA_exception_free (&ev); + } +} + +static const char * +reverse_lookup_name_for_toolkit_event (char *toolkit_specific_name) +{ + const char *generic_name; + SpiApplicationClass *klass = g_type_class_peek (SPI_APPLICATION_TYPE); +#ifdef SPI_DEBUG + fprintf (stderr, "(reverse lookup) looking for %s in hash table.\n", toolkit_specific_name); +#endif + generic_name = + (const char *) g_hash_table_lookup (klass->generic_event_names, toolkit_specific_name); +#ifdef SPI_DEBUG + fprintf (stderr, "toolkit event %s converted to %s\n", toolkit_specific_name, generic_name); +#endif + return generic_name; +} + +static void +init_toolkit_names (GHashTable **generic_event_names, GHashTable **toolkit_event_names) +{ + *toolkit_event_names = g_hash_table_new (g_str_hash, g_str_equal); + *generic_event_names = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (*toolkit_event_names, + "object:property-change", + "Gtk:AtkObject:property-change"); + g_hash_table_insert (*generic_event_names, + "Gtk:AtkObject:property-change", + "object:property-change"); +#ifdef SPI_DEBUG + fprintf (stderr, "inserted spi_selection_changed hash\n"); +#endif +} + +static void +spi_application_class_init (SpiApplicationClass *klass) { GObjectClass * object_class = (GObjectClass *) klass; POA_Accessibility_Application__epv *epv = &klass->epv; - application_parent_class = g_type_class_ref (ACCESSIBLE_TYPE); + spi_application_parent_class = g_type_class_ref (SPI_ACCESSIBLE_TYPE); - object_class->finalize = accessible_application_finalize; + object_class->finalize = spi_accessible_application_finalize; epv->_get_toolkitName = impl_accessibility_application_get_toolkit_name; epv->_get_version = impl_accessibility_application_get_version; epv->_get_id = impl_accessibility_application_get_id; epv->_set_id = impl_accessibility_application_set_id; epv->registerToolkitEventListener = impl_accessibility_application_register_toolkit_event_listener; + init_toolkit_names (&klass->generic_event_names, &klass->toolkit_event_names); } static void -application_init (Application *application) -{ - ACCESSIBLE (application)->atko = g_object_new (atk_object_get_type(), NULL); -} - -GType -application_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo tinfo = { - sizeof (ApplicationClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) application_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class data */ - sizeof (Application), - 0, /* n preallocs */ - (GInstanceInitFunc) application_init, - NULL /* value table */ - }; - /* - * Bonobo_type_unique auto-generates a load of - * CORBA structures for us. All derived types must - * use bonobo_type_unique. - */ - type = bonobo_type_unique ( - PARENT_TYPE, - POA_Accessibility_Application__init, - NULL, - G_STRUCT_OFFSET (ApplicationClass, epv), - &tinfo, - "Application"); - } - - return type; -} - -Application * -application_new (AtkObject *app_root) -{ - Application *retval = - APPLICATION (g_object_new (application_get_type (), NULL)); - ACCESSIBLE (retval)->atko = app_root; - return retval; +spi_application_init (SpiApplication *application) +{ + application->toolkit_listeners = NULL; + the_app = application; +} + +BONOBO_TYPE_FUNC_FULL (SpiApplication, + Accessibility_Application, + PARENT_TYPE, spi_application); + +SpiApplication * +spi_application_new (AtkObject *app_root) +{ + SpiApplication *retval = g_object_new (SPI_APPLICATION_TYPE, NULL); + + spi_base_construct (SPI_BASE (retval), app_root); + + return retval; }