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 */
28 #include <libbonobo.h>
30 #include <atk/atkcomponent.h>
31 #include <gdk/gdkscreen.h>
34 /* SpiDesktop signals */
40 static guint spi_desktop_signals[LAST_SIGNAL];
43 /* Our parent Gtk object type */
44 #define PARENT_TYPE SPI_ACCESSIBLE_TYPE
48 Accessibility_Application ref;
51 static gboolean exiting = FALSE;
53 /* A pointer to our parent object class */
54 static SpiAccessibleClass *parent_class;
56 #define SPI_TYPE_ATK_DESKTOP (spi_atk_desktop_get_type ())
57 #define SPI_ATK_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_TYPE_ATK_DESKTOP, SpiAtkDesktop))
58 #define SPI_IS_ATK_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_TYPE_ATK_DESKTOP))
67 AtkObjectClass parent;
70 static void spi_atk_desktop_init (SpiAtkDesktop *desktop);
71 static void atk_component_interface_init (AtkComponentIface *iface);
72 static void spi_atk_desktop_get_extents (AtkComponent *component,
77 AtkCoordType coord_type);
80 spi_atk_desktop_get_type (void)
82 static GType type = 0;
86 static const GTypeInfo typeInfo =
88 sizeof (SpiAtkDesktopClass),
90 (GBaseFinalizeFunc) NULL,
91 (GClassInitFunc) NULL,
92 (GClassFinalizeFunc) NULL,
94 sizeof (SpiAtkDesktop),
96 (GInstanceInitFunc) spi_atk_desktop_init,
98 static const GInterfaceInfo atk_component_info =
100 (GInterfaceInitFunc) atk_component_interface_init,
101 (GInterfaceFinalizeFunc) NULL,
105 type = g_type_register_static (ATK_TYPE_OBJECT,
106 "SpiAtkDesktop", &typeInfo, 0);
107 g_type_add_interface_static (type, ATK_TYPE_COMPONENT,
108 &atk_component_info);
114 spi_atk_desktop_init (SpiAtkDesktop *desktop)
118 atk_object_set_name (ATK_OBJECT (desktop), "main");
119 display = gdk_x11_lookup_xdisplay (GDK_DISPLAY ());
120 desktop->screen = gdk_display_get_default_screen (display);
124 atk_component_interface_init (AtkComponentIface *iface)
126 g_return_if_fail (iface != NULL);
128 iface->get_extents = spi_atk_desktop_get_extents;
132 spi_atk_desktop_get_extents (AtkComponent *component,
137 AtkCoordType coord_type)
139 SpiAtkDesktop *desktop;
141 g_return_if_fail (SPI_IS_ATK_DESKTOP (component));
142 desktop = SPI_ATK_DESKTOP (component);
145 *width = gdk_screen_get_width (desktop->screen);
146 *height = gdk_screen_get_height (desktop->screen);
150 spi_desktop_init (SpiDesktop *desktop)
152 desktop->applications = NULL;
153 bonobo_object_set_immortal (BONOBO_OBJECT (desktop), TRUE);
157 spi_desktop_dispose (GObject *object)
159 SpiDesktop *desktop = (SpiDesktop *) object;
161 while (desktop->applications)
163 Application *app = desktop->applications->data;
164 g_assert (app->ref != CORBA_OBJECT_NIL);
165 spi_desktop_remove_application (desktop, app->ref);
168 G_OBJECT_CLASS (parent_class)->dispose (object);
172 impl_desktop_get_child_count (PortableServer_Servant servant,
173 CORBA_Environment *ev)
175 SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
177 if (desktop->applications)
179 return g_list_length (desktop->applications);
187 static Accessibility_Accessible
188 impl_desktop_get_child_at_index (PortableServer_Servant servant,
189 const CORBA_long index,
190 CORBA_Environment *ev)
192 SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
196 app = g_list_nth_data (desktop->applications, index);
200 retval = bonobo_object_dup_ref (app->ref, ev);
203 retval = CORBA_OBJECT_NIL;
208 retval = CORBA_OBJECT_NIL;
211 return (Accessibility_Accessible) retval;
215 spi_desktop_exiting (void)
221 spi_desktop_class_init (SpiDesktopClass *klass)
223 GObjectClass * object_class = (GObjectClass *) klass;
224 SpiAccessibleClass * spi_accessible_class = (SpiAccessibleClass *) klass;
225 POA_Accessibility_Accessible__epv *epv = &spi_accessible_class->epv;
227 object_class->dispose = spi_desktop_dispose;
229 parent_class = g_type_class_ref (SPI_ACCESSIBLE_TYPE);
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 epv->_get_childCount = impl_desktop_get_child_count;
250 epv->getChildAtIndex = impl_desktop_get_child_at_index;
251 g_atexit (spi_desktop_exiting);
254 BONOBO_TYPE_FUNC_FULL (SpiDesktop,
255 Accessibility_Desktop,
260 spi_desktop_new (void)
263 SpiAccessible *accessible;
265 accessible = spi_accessible_construct (SPI_DESKTOP_TYPE, g_object_new (SPI_TYPE_ATK_DESKTOP, NULL));
266 g_assert (SPI_IS_DESKTOP (accessible));
267 desktop = SPI_DESKTOP (accessible);
273 abnormal_application_termination (gpointer object, Application *app)
275 g_return_if_fail (SPI_IS_DESKTOP (app->desktop));
278 spi_desktop_remove_application (app->desktop, app->ref);
282 spi_desktop_add_application (SpiDesktop *desktop,
283 const Accessibility_Application application)
285 CORBA_Environment ev;
287 Accessibility_Application ref;
289 g_return_if_fail (SPI_IS_DESKTOP (desktop));
291 spi_desktop_remove_application (desktop, application);
293 CORBA_exception_init (&ev);
295 ref = bonobo_object_dup_ref (application, &ev);
297 if (!BONOBO_EX (&ev))
299 app = g_new (Application, 1);
300 app->desktop = desktop;
303 desktop->applications = g_list_append (desktop->applications, app);
305 ORBit_small_listen_for_broken (
306 app->ref, G_CALLBACK (abnormal_application_termination), app);
308 g_signal_emit (G_OBJECT (desktop),
309 spi_desktop_signals[APPLICATION_ADDED], 0,
310 g_list_index (desktop->applications, app));
313 CORBA_exception_free (&ev);
317 spi_desktop_remove_application (SpiDesktop *desktop,
318 const Accessibility_Application app_ref)
322 CORBA_Environment ev;
324 g_return_if_fail (app_ref != CORBA_OBJECT_NIL);
325 g_return_if_fail (SPI_IS_DESKTOP (desktop));
327 CORBA_exception_init (&ev);
330 for (l = desktop->applications; l; l = l->next)
332 Application *app = (Application *) l->data;
334 if (CORBA_Object_is_equivalent (app->ref, app_ref, &ev))
341 CORBA_exception_free (&ev);
345 Application *app = (Application *) l->data;
347 desktop->applications = g_list_delete_link (desktop->applications, l);
349 ORBit_small_unlisten_for_broken (app->ref, G_CALLBACK (abnormal_application_termination));
350 bonobo_object_release_unref (app->ref, NULL);
353 g_signal_emit (G_OBJECT (desktop), spi_desktop_signals[APPLICATION_REMOVED], 0, idx);