source: trunk/third/at-spi/registryd/desktop.c @ 18422

Revision 18422, 6.3 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18421, which included commits to RCS files with non-trunk default branches.
Line 
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 "desktop.h"
29
30/* SpiDesktop signals */
31enum {
32  APPLICATION_ADDED,
33  APPLICATION_REMOVED, 
34LAST_SIGNAL
35};
36static guint spi_desktop_signals[LAST_SIGNAL];
37
38
39/* Our parent Gtk object type */
40#define PARENT_TYPE SPI_ACCESSIBLE_TYPE
41
42typedef struct {
43        SpiDesktop *desktop;
44        Accessibility_Application ref;
45} Application;
46
47/* A pointer to our parent object class */
48static SpiAccessibleClass *parent_class;
49
50static void
51spi_desktop_init (SpiDesktop *desktop)
52{
53  spi_base_construct (SPI_BASE (desktop), g_object_new (ATK_TYPE_OBJECT, NULL));
54
55  desktop->applications = NULL;
56  bonobo_object_set_immortal (BONOBO_OBJECT (desktop), TRUE);
57
58  atk_object_set_name (ATK_OBJECT (SPI_BASE (desktop)->gobj), "main");
59}
60
61static void
62spi_desktop_dispose (GObject *object)
63{
64  SpiDesktop *desktop = (SpiDesktop *) object;
65
66  while (desktop->applications)
67    {
68      Application *app = desktop->applications->data;
69      g_assert (app->ref != CORBA_OBJECT_NIL);
70      spi_desktop_remove_application (desktop, app->ref);
71    }
72
73  G_OBJECT_CLASS (parent_class)->dispose (object);
74}
75
76static CORBA_long
77impl_desktop_get_child_count (PortableServer_Servant servant,
78                              CORBA_Environment     *ev)
79{
80  SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
81
82  if (desktop->applications)
83    {
84      return g_list_length (desktop->applications);
85    }
86  else
87    {
88      return 0;
89    }
90}
91
92static Accessibility_Accessible
93impl_desktop_get_child_at_index (PortableServer_Servant servant,
94                                 const CORBA_long       index,
95                                 CORBA_Environment     *ev)
96{
97  SpiDesktop  *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
98  CORBA_Object retval;
99  Application *app;
100
101  app = g_list_nth_data (desktop->applications, index);
102
103  if (app)
104    {
105      retval = bonobo_object_dup_ref (app->ref, ev);
106      if (BONOBO_EX (ev))
107        {
108          retval = CORBA_OBJECT_NIL;
109        }
110    }
111  else
112    {
113      retval = CORBA_OBJECT_NIL;
114    }
115
116  return (Accessibility_Accessible) retval;
117}
118
119static void
120spi_desktop_class_init (SpiDesktopClass *klass)
121{
122  GObjectClass * object_class = (GObjectClass *) klass;
123  SpiAccessibleClass * spi_accessible_class = (SpiAccessibleClass *) klass;
124  POA_Accessibility_Accessible__epv *epv = &spi_accessible_class->epv;
125
126  object_class->dispose = spi_desktop_dispose;
127 
128  parent_class = g_type_class_ref (SPI_ACCESSIBLE_TYPE);
129
130  spi_desktop_signals[APPLICATION_ADDED] =
131    g_signal_new ("application_added",
132                  G_TYPE_FROM_CLASS (klass),
133                  G_SIGNAL_RUN_LAST,
134                  G_STRUCT_OFFSET (SpiDesktopClass, application_added),
135                  NULL, NULL,
136                  g_cclosure_marshal_VOID__UINT,
137                  G_TYPE_NONE,
138                  1, G_TYPE_UINT);
139  spi_desktop_signals[APPLICATION_REMOVED] =
140    g_signal_new ("application_removed",
141                  G_TYPE_FROM_CLASS (klass),
142                  G_SIGNAL_RUN_LAST,
143                  G_STRUCT_OFFSET (SpiDesktopClass, application_removed),
144                  NULL, NULL,
145                  g_cclosure_marshal_VOID__UINT,
146                  G_TYPE_NONE,
147                  1, G_TYPE_UINT);
148  epv->_get_childCount = impl_desktop_get_child_count;
149  epv->getChildAtIndex = impl_desktop_get_child_at_index;
150}
151
152BONOBO_TYPE_FUNC_FULL (SpiDesktop,
153                       Accessibility_Desktop,
154                       PARENT_TYPE,
155                       spi_desktop);
156
157SpiDesktop *
158spi_desktop_new (void)
159{
160  SpiDesktop *retval = g_object_new (SPI_DESKTOP_TYPE, NULL);
161
162  return retval;
163}
164
165static void
166abnormal_application_termination (gpointer object, Application *app)
167{
168  g_return_if_fail (SPI_IS_DESKTOP (app->desktop));
169
170  spi_desktop_remove_application (app->desktop, app->ref);
171}
172
173void
174spi_desktop_add_application (SpiDesktop *desktop,
175                             const Accessibility_Application application)
176{
177  CORBA_Environment ev;
178  Application       *app;
179  Accessibility_Application ref;
180
181  g_return_if_fail (SPI_IS_DESKTOP (desktop));
182
183  spi_desktop_remove_application (desktop, application);
184
185  CORBA_exception_init (&ev);
186
187  ref = bonobo_object_dup_ref (application, &ev);
188
189  if (!BONOBO_EX (&ev))
190    {
191      app = g_new (Application, 1);
192      app->desktop = desktop;
193      app->ref = ref;
194
195      desktop->applications = g_list_append (desktop->applications, app);
196
197      ORBit_small_listen_for_broken (
198              app->ref, G_CALLBACK (abnormal_application_termination), app);
199
200      g_signal_emit (G_OBJECT (desktop),
201                     spi_desktop_signals[APPLICATION_ADDED], 0,
202                     g_list_index (desktop->applications, app));
203    }
204
205  CORBA_exception_free (&ev);
206}
207
208void
209spi_desktop_remove_application (SpiDesktop *desktop,
210                                const Accessibility_Application app_ref)
211{
212  guint idx;
213  GList *l;
214  CORBA_Environment ev;
215
216  g_return_if_fail (app_ref != CORBA_OBJECT_NIL);
217  g_return_if_fail (SPI_IS_DESKTOP (desktop));
218
219  CORBA_exception_init (&ev);
220
221  idx = 0;
222  for (l = desktop->applications; l; l = l->next)
223    {
224      Application *app = (Application *) l->data;
225
226      if (CORBA_Object_is_equivalent (app->ref, app_ref, &ev))
227        {
228          break;
229        }
230      idx++;
231    }
232
233  CORBA_exception_free (&ev);
234
235  if (l)
236    {
237      Application *app = (Application *) l->data;
238
239      desktop->applications = g_list_delete_link (desktop->applications, l);
240
241      ORBit_small_unlisten_for_broken (app->ref, G_CALLBACK (abnormal_application_termination));
242      bonobo_object_release_unref (app->ref, NULL);
243      g_free (app);
244     
245      g_signal_emit (G_OBJECT (desktop), spi_desktop_signals[APPLICATION_REMOVED], 0, idx);
246    }
247}
Note: See TracBrowser for help on using the repository browser.