xref: /trunk/main/vcl/unx/gtk/a11y/atkfactory.cxx (revision 9f62ea84)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26 
27 #include <unx/gtk/gtkframe.hxx>
28 #include <vcl/window.hxx>
29 #include "atkwrapper.hxx"
30 #include "atkfactory.hxx"
31 #include "atkregistry.hxx"
32 
33 using namespace ::com::sun::star;
34 
35 extern "C" {
36 
37 /*
38  *  Instances of this dummy object class are returned whenever we have to
39  *  create an AtkObject, but can't touch the OOo object anymore since it
40  *  is already disposed.
41  */
42 
43 static AtkStateSet *
noop_wrapper_ref_state_set(AtkObject *)44 noop_wrapper_ref_state_set( AtkObject * )
45 {
46     AtkStateSet *state_set = atk_state_set_new();
47     atk_state_set_add_state( state_set, ATK_STATE_DEFUNCT );
48     return state_set;
49 }
50 
51 static void
atk_noop_object_wrapper_class_init(AtkNoOpObjectClass * klass)52 atk_noop_object_wrapper_class_init(AtkNoOpObjectClass *klass)
53 {
54     AtkObjectClass *atk_class = ATK_OBJECT_CLASS( klass );
55     atk_class->ref_state_set = noop_wrapper_ref_state_set;
56 }
57 
58 static GType
atk_noop_object_wrapper_get_type(void)59 atk_noop_object_wrapper_get_type(void)
60 {
61     static GType type = 0;
62 
63     if (!type)
64     {
65         static const GTypeInfo typeInfo =
66         {
67             sizeof (AtkNoOpObjectClass),
68             (GBaseInitFunc) NULL,
69             (GBaseFinalizeFunc) NULL,
70             (GClassInitFunc) atk_noop_object_wrapper_class_init,
71             (GClassFinalizeFunc) NULL,
72             NULL,
73             sizeof (AtkObjectWrapper),
74             0,
75             (GInstanceInitFunc) NULL,
76             NULL
77         } ;
78 
79         type = g_type_register_static (ATK_TYPE_OBJECT, "OOoAtkNoOpObj", &typeInfo, (GTypeFlags)0) ;
80   }
81   return type;
82 }
83 
84 AtkObject*
atk_noop_object_wrapper_new()85 atk_noop_object_wrapper_new()
86 {
87   AtkObject *accessible;
88 
89   accessible = (AtkObject *) g_object_new (atk_noop_object_wrapper_get_type(), NULL);
90   g_return_val_if_fail (accessible != NULL, NULL);
91 
92   accessible->role = ATK_ROLE_INVALID;
93   accessible->layer = ATK_LAYER_INVALID;
94 
95   return accessible;
96 }
97 
98 /*
99  * The wrapper factory
100  */
101 
102 static GType
wrapper_factory_get_accessible_type(void)103 wrapper_factory_get_accessible_type(void)
104 {
105   return atk_object_wrapper_get_type();
106 }
107 
108 static AtkObject*
wrapper_factory_create_accessible(GObject * obj)109 wrapper_factory_create_accessible( GObject *obj )
110 {
111     GtkWidget* parent_widget = gtk_widget_get_parent( GTK_WIDGET( obj ) );
112 
113     // gail_container_real_remove_gtk tries to re-instanciate an accessible
114     // for a widget that is about to vanish ..
115     if( ! parent_widget )
116         return atk_noop_object_wrapper_new();
117 
118     GtkSalFrame* pFrame = GtkSalFrame::getFromWindow( GTK_WINDOW( parent_widget ) );
119     g_return_val_if_fail( pFrame != NULL, NULL );
120 
121     Window* pFrameWindow = pFrame->GetWindow();
122     if( pFrameWindow )
123     {
124         Window* pWindow = pFrameWindow;
125 
126         // skip accessible objects already exposed by the frame objects
127         if( WINDOW_BORDERWINDOW == pWindow->GetType() )
128             pWindow = pFrameWindow->GetAccessibleChildWindow(0);
129 
130         if( pWindow )
131         {
132              uno::Reference< accessibility::XAccessible > xAccessible = pWindow->GetAccessible(true);
133             if( xAccessible.is() )
134             {
135                 AtkObject *accessible = ooo_wrapper_registry_get( xAccessible );
136 
137                 if( accessible )
138                     g_object_ref( G_OBJECT(accessible) );
139                 else
140                     accessible = atk_object_wrapper_new( xAccessible, gtk_widget_get_accessible(parent_widget) );
141 
142                 return accessible;
143             }
144         }
145     }
146 
147     return NULL;
148 }
149 
150 static void
wrapper_factory_class_init(AtkObjectFactoryClass * klass)151 wrapper_factory_class_init( AtkObjectFactoryClass *klass )
152 {
153   klass->create_accessible   = wrapper_factory_create_accessible;
154   klass->get_accessible_type = wrapper_factory_get_accessible_type;
155 }
156 
157 GType
wrapper_factory_get_type(void)158 wrapper_factory_get_type (void)
159 {
160   static GType t = 0;
161 
162   if (!t) {
163     static const GTypeInfo tinfo =
164     {
165       sizeof (AtkObjectFactoryClass),
166       NULL, NULL, (GClassInitFunc) wrapper_factory_class_init,
167       NULL, NULL, sizeof (AtkObjectFactory), 0, NULL, NULL
168     };
169 
170     t = g_type_register_static (
171         ATK_TYPE_OBJECT_FACTORY, "OOoAtkObjectWrapperFactory",
172         &tinfo, (GTypeFlags) 0);
173   }
174 
175   return t;
176 }
177 
178 } // extern C
179 
180