X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=registryd%2Fdesktop.c;h=be0e5b6c3b1bd9f49a5fa0794ef41b536dd4e222;hb=f6ca06461319b20463f96a5b37544a540aee11ca;hp=82dfd928c9a34823ab8e538d2be9621af9a10c8e;hpb=43e27124b49e819f8c3741915e140f7d0186d615;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/registryd/desktop.c b/registryd/desktop.c index 82dfd92..be0e5b6 100644 --- a/registryd/desktop.c +++ b/registryd/desktop.c @@ -2,7 +2,8 @@ * AT-SPI - Assistive Technology Service Provider Interface * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) * - * Copyright 2001 Sun Microsystems Inc. + * Copyright 2001, 2002 Sun Microsystems Inc., + * Copyright 2001, 2002 Ximian, Inc., Ximian Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -24,83 +25,321 @@ #include #include -#include -#include +#include +#include +#include +#include + +#include + +#include "desktop.h" +#include "registry.h" + +G_DEFINE_TYPE(SpiDesktop, spi_desktop, G_TYPE_OBJECT) + +/* SpiDesktop signals */ +enum { + APPLICATION_ADDED, + APPLICATION_REMOVED, +LAST_SIGNAL +}; +static guint spi_desktop_signals[LAST_SIGNAL]; + /* Our parent Gtk object type */ #define PARENT_TYPE SPI_ACCESSIBLE_TYPE +typedef struct { + SpiDesktop *desktop; + const char *path; +} Application; + +static gboolean exiting = FALSE; + /* A pointer to our parent object class */ -static SpiAccessibleClass *parent_class; +static GObjectClass *parent_class; + +#define SPI_TYPE_ATK_DESKTOP (spi_atk_desktop_get_type ()) +#define SPI_ATK_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_TYPE_ATK_DESKTOP, SpiAtkDesktop)) +#define SPI_IS_ATK_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_TYPE_ATK_DESKTOP)) + +typedef struct { + AtkObject parent; + + GdkScreen *screen; +} SpiAtkDesktop; + +typedef struct { + AtkObjectClass parent; +} SpiAtkDesktopClass; + +static void spi_atk_desktop_init (SpiAtkDesktop *desktop); +static void atk_component_interface_init (AtkComponentIface *iface); +static void spi_atk_desktop_get_extents (AtkComponent *component, + gint *x, + gint *y, + gint *width, + gint *height, + AtkCoordType coord_type); + +static GType +spi_atk_desktop_get_type (void) +{ + static GType type = 0; + + if (!type) + { + static const GTypeInfo typeInfo = + { + sizeof (SpiAtkDesktopClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) NULL, + (GClassFinalizeFunc) NULL, + NULL, + sizeof (SpiAtkDesktop), + 0, + (GInstanceInitFunc) spi_atk_desktop_init, + } ; + static const GInterfaceInfo atk_component_info = + { + (GInterfaceInitFunc) atk_component_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + + type = g_type_register_static (ATK_TYPE_OBJECT, + "SpiAtkDesktop", &typeInfo, 0); + g_type_add_interface_static (type, ATK_TYPE_COMPONENT, + &atk_component_info); + } + return type; +} + +static void +spi_atk_desktop_init (SpiAtkDesktop *desktop) +{ + GdkDisplay *display; + + atk_object_set_name (ATK_OBJECT (desktop), "main"); + display = gdk_x11_lookup_xdisplay (GDK_DISPLAY ()); + desktop->screen = gdk_display_get_default_screen (display); +} + +static void +atk_component_interface_init (AtkComponentIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->get_extents = spi_atk_desktop_get_extents; +} + +static void +spi_atk_desktop_get_extents (AtkComponent *component, + gint *x, + gint *y, + gint *width, + gint *height, + AtkCoordType coord_type) +{ + SpiAtkDesktop *desktop; + + g_return_if_fail (SPI_IS_ATK_DESKTOP (component)); + desktop = SPI_ATK_DESKTOP (component); + *x = 0; + *y = 0; + *width = gdk_screen_get_width (desktop->screen); + *height = gdk_screen_get_height (desktop->screen); +} static void -spi_desktop_init (SpiDesktop *desktop) +spi_desktop_init (SpiDesktop *desktop) { - SPI_ACCESSIBLE (desktop)->atko = g_object_new (ATK_TYPE_OBJECT, NULL); desktop->applications = NULL; - atk_object_set_name (ATK_OBJECT (SPI_ACCESSIBLE (desktop)->atko), "main"); } -static CORBA_long -impl_desktop_get_child_count (PortableServer_Servant servant, - CORBA_Environment * ev) +static void +spi_desktop_dispose (GObject *object) +{ + SpiDesktop *desktop = (SpiDesktop *) object; + + while (desktop->applications) + { + Application *app = desktop->applications->data; + g_assert (app != NULL); + spi_desktop_remove_application (desktop, app->path); + } + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static dbus_bool_t +impl_desktop_get_child_count (const char *path, DBusMessageIter * iter, + void *user_data) { - SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant)); + SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop; + if (desktop->applications) { - return g_list_length (desktop->applications); + return droute_return_v_int32(iter, g_list_length (desktop->applications)); } else { - return 0; + return droute_return_v_int32(iter, 0); } } -static Accessibility_Accessible -impl_desktop_get_child_at_index (PortableServer_Servant servant, - const CORBA_long index, - CORBA_Environment * ev) +static DBusMessage * +impl_desktop_get_child_at_index (DBusConnection *bus, DBusMessage *message, void *user_data) { - SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant)); - CORBA_Object retval; - if ((desktop->applications) && (index < g_list_length (desktop->applications))) - { - fprintf (stderr, "getting application %ld\n", (long) index); - /* */ - fprintf (stderr, "object address %p\n", - g_list_nth_data (desktop->applications, index)); - retval = CORBA_Object_duplicate ( - (CORBA_Object) g_list_nth_data (desktop->applications, index), ev); - } - else + SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop; + DBusError error; + dbus_int32_t index; + Application *app; + const char *path; + DBusMessage *reply; + + dbus_error_init (&error); + if (!dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID)) + { + return spi_dbus_general_error (message); + } + app = g_list_nth_data (desktop->applications, index); + path = (app? app->path: SPI_DBUS_PATH_NULL); + + reply = dbus_message_new_method_return (message); + if (reply) { - fprintf (stderr, "no %ldth child\n", (long) index); - retval = CORBA_OBJECT_NIL; + dbus_message_append_args (reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); } - return (Accessibility_Accessible) retval; + + return reply; } static void -spi_desktop_class_init (SpiDesktopClass *klass) +spi_desktop_exiting (void) { - SpiAccessibleClass * spi_accessible_class = (SpiAccessibleClass *) klass; - POA_Accessibility_Accessible__epv *epv = &spi_accessible_class->epv; + exiting = TRUE; +} - parent_class = g_type_class_ref (SPI_ACCESSIBLE_TYPE); +static void +spi_desktop_class_init (SpiDesktopClass *klass) +{ + GObjectClass * object_class = (GObjectClass *) klass; - epv->_get_childCount = impl_desktop_get_child_count; - epv->getChildAtIndex = impl_desktop_get_child_at_index; -} + object_class->dispose = spi_desktop_dispose; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); -BONOBO_TYPE_FUNC_FULL (SpiDesktop, - Accessibility_Desktop, - PARENT_TYPE, - spi_desktop); + spi_desktop_signals[APPLICATION_ADDED] = + g_signal_new ("application_added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (SpiDesktopClass, application_added), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, + 1, G_TYPE_UINT); + spi_desktop_signals[APPLICATION_REMOVED] = + g_signal_new ("application_removed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (SpiDesktopClass, application_removed), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, + 1, G_TYPE_UINT); + g_atexit (spi_desktop_exiting); +} SpiDesktop * spi_desktop_new (void) { - SpiDesktop *retval = g_object_new (SPI_DESKTOP_TYPE, NULL); + return g_object_new (SPI_DESKTOP_TYPE, NULL); +} + +static void +abnormal_application_termination (gpointer object, Application *app) +{ + g_return_if_fail (SPI_IS_DESKTOP (app->desktop)); + + if (!exiting) + spi_desktop_remove_application (app->desktop, app->path); +} + +void +spi_desktop_add_application (SpiDesktop *desktop, + const char *application) +{ + Application *app; + + g_return_if_fail (SPI_IS_DESKTOP (desktop)); + + spi_desktop_remove_application (desktop, application); + + app = g_new (Application, 1); + app->desktop = desktop; + app->path = application; + + desktop->applications = g_list_append (desktop->applications, app); + + // TODO: Listen for termination, and call abnormal_application_termination + + g_signal_emit (G_OBJECT (desktop), + spi_desktop_signals[APPLICATION_ADDED], 0, + g_list_index (desktop->applications, app)); +} + +void +spi_desktop_remove_application (SpiDesktop *desktop, + const char *path) +{ + guint idx; + GList *l; + + g_return_if_fail (path != NULL); + g_return_if_fail (SPI_IS_DESKTOP (desktop)); + + idx = 0; + for (l = desktop->applications; l; l = l->next) + { + Application *app = (Application *) l->data; + + if (!strcmp(app->path, path)) + { + break; + } + idx++; + } - return retval; + if (l) + { + Application *app = (Application *) l->data; + + desktop->applications = g_list_delete_link (desktop->applications, l); + + // TODO: unlisten for broken app, if appropriate + g_free (app); + + g_signal_emit (G_OBJECT (desktop), spi_desktop_signals[APPLICATION_REMOVED], 0, idx); + } } + +static DRouteMethod methods[] = +{ + { impl_desktop_get_child_at_index, "getChildAtIndex" }, + { NULL, NULL } +}; + +static DRouteProperty properties[] = +{ + { impl_desktop_get_child_count, NULL, "getChildCount" }, + { NULL, NULL, NULL } +}; + +void +spi_registry_initialize_desktop_interface (DRouteData * data) +{ + droute_add_interface (data, "org.freedesktop.atspi.Desktop", methods, + properties, NULL, NULL); +};