2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5 * Copyright 2001, 2002 Sun Microsystems Inc.,
6 * Copyright 2001, 2002 Ximian, Inc., Ximian Inc.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
24 /* desktop.c: implements SpiDesktop.idl */
31 #include <atk/atkcomponent.h>
32 #include <gdk/gdkscreen.h>
35 G_DEFINE_TYPE(SpiDesktop, spi_desktop, G_TYPE_OBJECT)
37 /* SpiDesktop signals */
43 static guint spi_desktop_signals[LAST_SIGNAL];
46 /* Our parent Gtk object type */
47 #define PARENT_TYPE SPI_ACCESSIBLE_TYPE
54 static gboolean exiting = FALSE;
56 /* A pointer to our parent object class */
57 static GObjectClass *parent_class;
59 #define SPI_TYPE_ATK_DESKTOP (spi_atk_desktop_get_type ())
60 #define SPI_ATK_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_TYPE_ATK_DESKTOP, SpiAtkDesktop))
61 #define SPI_IS_ATK_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_TYPE_ATK_DESKTOP))
70 AtkObjectClass parent;
73 static void spi_atk_desktop_init (SpiAtkDesktop *desktop);
74 static void atk_component_interface_init (AtkComponentIface *iface);
75 static void spi_atk_desktop_get_extents (AtkComponent *component,
80 AtkCoordType coord_type);
83 spi_atk_desktop_get_type (void)
85 static GType type = 0;
89 static const GTypeInfo typeInfo =
91 sizeof (SpiAtkDesktopClass),
93 (GBaseFinalizeFunc) NULL,
94 (GClassInitFunc) NULL,
95 (GClassFinalizeFunc) NULL,
97 sizeof (SpiAtkDesktop),
99 (GInstanceInitFunc) spi_atk_desktop_init,
101 static const GInterfaceInfo atk_component_info =
103 (GInterfaceInitFunc) atk_component_interface_init,
104 (GInterfaceFinalizeFunc) NULL,
108 type = g_type_register_static (ATK_TYPE_OBJECT,
109 "SpiAtkDesktop", &typeInfo, 0);
110 g_type_add_interface_static (type, ATK_TYPE_COMPONENT,
111 &atk_component_info);
117 spi_atk_desktop_init (SpiAtkDesktop *desktop)
121 atk_object_set_name (ATK_OBJECT (desktop), "main");
122 display = gdk_x11_lookup_xdisplay (GDK_DISPLAY ());
123 desktop->screen = gdk_display_get_default_screen (display);
127 atk_component_interface_init (AtkComponentIface *iface)
129 g_return_if_fail (iface != NULL);
131 iface->get_extents = spi_atk_desktop_get_extents;
135 spi_atk_desktop_get_extents (AtkComponent *component,
140 AtkCoordType coord_type)
142 SpiAtkDesktop *desktop;
144 g_return_if_fail (SPI_IS_ATK_DESKTOP (component));
145 desktop = SPI_ATK_DESKTOP (component);
148 *width = gdk_screen_get_width (desktop->screen);
149 *height = gdk_screen_get_height (desktop->screen);
153 spi_desktop_init (SpiDesktop *desktop)
155 desktop->applications = NULL;
159 spi_desktop_dispose (GObject *object)
161 SpiDesktop *desktop = (SpiDesktop *) object;
163 while (desktop->applications)
165 Application *app = desktop->applications->data;
166 g_assert (app != NULL);
167 spi_desktop_remove_application (desktop, app->path);
170 G_OBJECT_CLASS (parent_class)->dispose (object);
174 impl_desktop_get_child_count (const char *path, DBusMessageIter * iter,
177 SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop;
179 if (desktop->applications)
181 return droute_return_v_int32(iter, g_list_length (desktop->applications));
185 return droute_return_v_int32(iter, 0);
190 impl_desktop_get_child_at_index (DBusConnection *bus, DBusMessage *message, void *user_data)
192 SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop;
199 dbus_error_init (&error);
200 if (!dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
202 return spi_dbus_general_error (message);
204 app = g_list_nth_data (desktop->applications, index);
205 path = (app? app->path: SPI_DBUS_PATH_NULL);
207 reply = dbus_message_new_method_return (message);
210 dbus_message_append_args (reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID);
217 spi_desktop_exiting (void)
223 spi_desktop_class_init (SpiDesktopClass *klass)
225 GObjectClass * object_class = (GObjectClass *) klass;
227 object_class->dispose = spi_desktop_dispose;
229 parent_class = g_type_class_ref (G_TYPE_OBJECT);
231 spi_desktop_signals[APPLICATION_ADDED] =
232 g_signal_new ("application_added",
233 G_TYPE_FROM_CLASS (klass),
235 G_STRUCT_OFFSET (SpiDesktopClass, application_added),
237 g_cclosure_marshal_VOID__UINT,
240 spi_desktop_signals[APPLICATION_REMOVED] =
241 g_signal_new ("application_removed",
242 G_TYPE_FROM_CLASS (klass),
244 G_STRUCT_OFFSET (SpiDesktopClass, application_removed),
246 g_cclosure_marshal_VOID__UINT,
249 g_atexit (spi_desktop_exiting);
253 spi_desktop_new (void)
255 return g_object_new (SPI_DESKTOP_TYPE, NULL);
259 abnormal_application_termination (gpointer object, Application *app)
261 g_return_if_fail (SPI_IS_DESKTOP (app->desktop));
264 spi_desktop_remove_application (app->desktop, app->path);
268 spi_desktop_add_application (SpiDesktop *desktop,
269 const char *application)
273 g_return_if_fail (SPI_IS_DESKTOP (desktop));
275 spi_desktop_remove_application (desktop, application);
277 app = g_new (Application, 1);
278 app->desktop = desktop;
279 app->path = application;
281 desktop->applications = g_list_append (desktop->applications, app);
283 // TODO: Listen for termination, and call abnormal_application_termination
285 g_signal_emit (G_OBJECT (desktop),
286 spi_desktop_signals[APPLICATION_ADDED], 0,
287 g_list_index (desktop->applications, app));
291 spi_desktop_remove_application (SpiDesktop *desktop,
297 g_return_if_fail (path != NULL);
298 g_return_if_fail (SPI_IS_DESKTOP (desktop));
301 for (l = desktop->applications; l; l = l->next)
303 Application *app = (Application *) l->data;
305 if (!strcmp(app->path, path))
314 Application *app = (Application *) l->data;
316 desktop->applications = g_list_delete_link (desktop->applications, l);
318 // TODO: unlisten for broken app, if appropriate
321 g_signal_emit (G_OBJECT (desktop), spi_desktop_signals[APPLICATION_REMOVED], 0, idx);
325 static DRouteMethod methods[] =
327 { impl_desktop_get_child_at_index, "getChildAtIndex" },
331 static DRouteProperty properties[] =
333 { impl_desktop_get_child_count, NULL, "getChildCount" },
338 spi_registry_initialize_desktop_interface (DRouteData * data)
340 droute_add_interface (data, "org.freedesktop.atspi.Desktop", methods,
341 properties, NULL, NULL);