2001-12-10 Michael Meeks <michael@ximian.com>
[platform/core/uifw/at-spi2-atk.git] / libspi / desktop.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001 Sun Microsystems Inc., Ximian Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /* desktop.c: implements SpiDesktop.idl */
24
25 #include <config.h>
26 #include <stdio.h>
27 #include <libbonobo.h>
28 #include <libspi/desktop.h>
29
30 /* Our parent Gtk object type */
31 #define PARENT_TYPE SPI_ACCESSIBLE_TYPE
32
33 typedef struct {
34         SpiDesktop *desktop;
35         Accessibility_Application ref;
36 } Application;
37
38 /* A pointer to our parent object class */
39 static SpiAccessibleClass *parent_class;
40
41 static void
42 spi_desktop_init (SpiDesktop *desktop)
43 {
44   spi_base_construct_default (SPI_BASE (desktop));
45
46   desktop->applications = NULL;
47
48   atk_object_set_name (SPI_BASE (desktop)->atko, "main");
49 }
50
51 static void
52 spi_desktop_dispose (GObject *object)
53 {
54   SpiDesktop *desktop = (SpiDesktop *) object;
55
56   while (desktop->applications)
57     {
58       Application *app = (Application *) desktop->applications;
59       spi_desktop_remove_application (desktop, app->ref);
60     }
61
62   G_OBJECT_CLASS (parent_class)->dispose (object); 
63 }
64
65 static CORBA_long
66 impl_desktop_get_child_count (PortableServer_Servant servant,
67                               CORBA_Environment     *ev)
68 {
69   SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
70
71   if (desktop->applications)
72     {
73       return g_list_length (desktop->applications);
74     }
75   else
76     {
77       return 0;
78     }
79 }
80
81 static Accessibility_Accessible
82 impl_desktop_get_child_at_index (PortableServer_Servant servant,
83                                  const CORBA_long       index,
84                                  CORBA_Environment     *ev)
85 {
86   SpiDesktop  *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
87   CORBA_Object retval;
88   Application *app;
89
90   app = g_list_nth_data (desktop->applications, index);
91
92   if (app)
93     {
94       retval = bonobo_object_dup_ref (app->ref, ev);
95       if (BONOBO_EX (ev))
96         {
97           retval = CORBA_OBJECT_NIL;
98         }
99     }
100   else
101     {
102       retval = CORBA_OBJECT_NIL;
103     }
104
105   return (Accessibility_Accessible) retval;
106 }
107
108 static void
109 spi_desktop_class_init (SpiDesktopClass *klass)
110 {
111   GObjectClass * object_class = (GObjectClass *) klass;
112   SpiAccessibleClass * spi_accessible_class = (SpiAccessibleClass *) klass;
113   POA_Accessibility_Accessible__epv *epv = &spi_accessible_class->epv;
114
115   object_class->dispose = spi_desktop_dispose;
116   
117   parent_class = g_type_class_ref (SPI_ACCESSIBLE_TYPE);
118
119   epv->_get_childCount = impl_desktop_get_child_count;
120   epv->getChildAtIndex = impl_desktop_get_child_at_index;
121 }
122
123 BONOBO_TYPE_FUNC_FULL (SpiDesktop,
124                        Accessibility_Desktop,
125                        PARENT_TYPE,
126                        spi_desktop);
127
128 SpiDesktop *
129 spi_desktop_new (void)
130 {
131   SpiDesktop *retval = g_object_new (SPI_DESKTOP_TYPE, NULL);
132
133   return retval;
134 }
135
136 static void
137 abnormal_application_termination (gpointer object, Application *app)
138 {
139   g_return_if_fail (SPI_IS_DESKTOP (app->desktop));
140
141   spi_desktop_remove_application (app->desktop, app->ref);
142 }
143
144 void
145 spi_desktop_add_application (SpiDesktop *desktop,
146                              const Accessibility_Application application)
147 {
148   CORBA_Environment ev;
149   Application       *app;
150   Accessibility_Application ref;
151
152   g_return_if_fail (SPI_IS_DESKTOP (desktop));
153
154   spi_desktop_remove_application (desktop, application);
155
156   CORBA_exception_init (&ev);
157
158   ref = bonobo_object_dup_ref (application, &ev);
159
160   if (!BONOBO_EX (&ev))
161     {
162       app = g_new (Application, 1);
163       app->desktop = desktop;
164       app->ref = ref;
165
166       desktop->applications = g_list_append (desktop->applications, app);
167
168       ORBit_small_listen_for_broken (app->ref, G_CALLBACK (abnormal_application_termination), app);
169     }
170
171   CORBA_exception_free (&ev);
172 }
173
174 void
175 spi_desktop_remove_application (SpiDesktop *desktop,
176                                 const Accessibility_Application app_ref)
177 {
178   GList *l;
179   CORBA_Environment ev;
180
181   g_return_if_fail (SPI_IS_DESKTOP (desktop));
182
183   CORBA_exception_init (&ev);
184
185   for (l = desktop->applications; l; l = l->next)
186     {
187       Application *app = (Application *) l->data;
188
189       if (CORBA_Object_is_equivalent (app->ref, app_ref, &ev))
190         {
191           break;
192         }
193     }
194
195   CORBA_exception_free (&ev);
196
197   if (l)
198     {
199       Application *app = (Application *) l->data;
200
201       desktop->applications = g_list_delete_link (desktop->applications, l);
202
203       ORBit_small_unlisten_for_broken (app->ref, G_CALLBACK (abnormal_application_termination));
204       bonobo_object_release_unref (app->ref, NULL);
205       g_free (app);
206     }
207 }