xref: /aoo41x/main/vcl/unx/gtk/a11y/atkfactory.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <unx/gtk/gtkframe.hxx>
32 #include <vcl/window.hxx>
33 #include "atkwrapper.hxx"
34 #include "atkfactory.hxx"
35 #include "atkregistry.hxx"
36 
37 using namespace ::com::sun::star;
38 
39 extern "C" {
40 
41 /*
42  *  Instances of this dummy object class are returned whenever we have to
43  *  create an AtkObject, but can't touch the OOo object anymore since it
44  *  is already disposed.
45  */
46 
47 static AtkStateSet *
48 noop_wrapper_ref_state_set( AtkObject * )
49 {
50     AtkStateSet *state_set = atk_state_set_new();
51     atk_state_set_add_state( state_set, ATK_STATE_DEFUNCT );
52     return state_set;
53 }
54 
55 static void
56 atk_noop_object_wrapper_class_init(AtkNoOpObjectClass *klass)
57 {
58     AtkObjectClass *atk_class = ATK_OBJECT_CLASS( klass );
59     atk_class->ref_state_set = noop_wrapper_ref_state_set;
60 }
61 
62 static GType
63 atk_noop_object_wrapper_get_type(void)
64 {
65     static GType type = 0;
66 
67     if (!type)
68     {
69         static const GTypeInfo typeInfo =
70         {
71             sizeof (AtkNoOpObjectClass),
72             (GBaseInitFunc) NULL,
73             (GBaseFinalizeFunc) NULL,
74             (GClassInitFunc) atk_noop_object_wrapper_class_init,
75             (GClassFinalizeFunc) NULL,
76             NULL,
77             sizeof (AtkObjectWrapper),
78             0,
79             (GInstanceInitFunc) NULL,
80             NULL
81         } ;
82 
83         type = g_type_register_static (ATK_TYPE_OBJECT, "OOoAtkNoOpObj", &typeInfo, (GTypeFlags)0) ;
84   }
85   return type;
86 }
87 
88 AtkObject*
89 atk_noop_object_wrapper_new()
90 {
91   AtkObject *accessible;
92 
93   accessible = (AtkObject *) g_object_new (atk_noop_object_wrapper_get_type(), NULL);
94   g_return_val_if_fail (accessible != NULL, NULL);
95 
96   accessible->role = ATK_ROLE_INVALID;
97   accessible->layer = ATK_LAYER_INVALID;
98 
99   return accessible;
100 }
101 
102 /*
103  * The wrapper factory
104  */
105 
106 static GType
107 wrapper_factory_get_accessible_type(void)
108 {
109   return atk_object_wrapper_get_type();
110 }
111 
112 static AtkObject*
113 wrapper_factory_create_accessible( GObject *obj )
114 {
115     GtkWidget* parent_widget = gtk_widget_get_parent( GTK_WIDGET( obj ) );
116 
117     // gail_container_real_remove_gtk tries to re-instanciate an accessible
118     // for a widget that is about to vanish ..
119     if( ! parent_widget )
120         return atk_noop_object_wrapper_new();
121 
122     GtkSalFrame* pFrame = GtkSalFrame::getFromWindow( GTK_WINDOW( parent_widget ) );
123     g_return_val_if_fail( pFrame != NULL, NULL );
124 
125     Window* pFrameWindow = pFrame->GetWindow();
126     if( pFrameWindow )
127     {
128         Window* pWindow = pFrameWindow;
129 
130         // skip accessible objects already exposed by the frame objects
131         if( WINDOW_BORDERWINDOW == pWindow->GetType() )
132             pWindow = pFrameWindow->GetAccessibleChildWindow(0);
133 
134         if( pWindow )
135         {
136              uno::Reference< accessibility::XAccessible > xAccessible = pWindow->GetAccessible(true);
137             if( xAccessible.is() )
138             {
139                 AtkObject *accessible = ooo_wrapper_registry_get( xAccessible );
140 
141                 if( accessible )
142                     g_object_ref( G_OBJECT(accessible) );
143                 else
144                     accessible = atk_object_wrapper_new( xAccessible, gtk_widget_get_accessible(parent_widget) );
145 
146                 return accessible;
147             }
148         }
149     }
150 
151     return NULL;
152 }
153 
154 static void
155 wrapper_factory_class_init( AtkObjectFactoryClass *klass )
156 {
157   klass->create_accessible   = wrapper_factory_create_accessible;
158   klass->get_accessible_type = wrapper_factory_get_accessible_type;
159 }
160 
161 GType
162 wrapper_factory_get_type (void)
163 {
164   static GType t = 0;
165 
166   if (!t) {
167     static const GTypeInfo tinfo =
168     {
169       sizeof (AtkObjectFactoryClass),
170       NULL, NULL, (GClassInitFunc) wrapper_factory_class_init,
171       NULL, NULL, sizeof (AtkObjectFactory), 0, NULL, NULL
172     };
173 
174     t = g_type_register_static (
175         ATK_TYPE_OBJECT_FACTORY, "OOoAtkObjectWrapperFactory",
176         &tinfo, (GTypeFlags) 0);
177   }
178 
179   return t;
180 }
181 
182 } // extern C
183 
184