xref: /AOO41X/main/vcl/unx/gtk/a11y/atkwrapper.cxx (revision 24c56ab9f1bd1305754aa2f564704f38ff57627e)
19f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
39f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
49f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
59f62ea84SAndrew Rist  * distributed with this work for additional information
69f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
79f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
89f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
99f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
119f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
139f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
149f62ea84SAndrew Rist  * software distributed under the License is distributed on an
159f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
179f62ea84SAndrew Rist  * specific language governing permissions and limitations
189f62ea84SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
209f62ea84SAndrew Rist  *************************************************************/
219f62ea84SAndrew Rist 
229f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <com/sun/star/uno/Any.hxx>
28cdf0e10cSrcweir #include <com/sun/star/uno/Type.hxx>
29cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx>
30cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
31cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRelation.hpp>
32cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
33cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp>
34cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessible.hpp>
35cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleText.hpp>
36cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleTextMarkup.hpp>
37cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
38cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleValue.hpp>
39cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleAction.hpp>
40cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleContext.hpp>
41cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
42cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
43cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp>
44cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
45cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
46cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleTable.hpp>
47cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
48cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleImage.hpp>
49cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleHyperlink.hpp>
50cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleHypertext.hpp>
51cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleSelection.hpp>
52cdf0e10cSrcweir #include <com/sun/star/awt/XExtendedToolkit.hpp>
53cdf0e10cSrcweir #include <com/sun/star/awt/XTopWindow.hpp>
54cdf0e10cSrcweir #include <com/sun/star/awt/XTopWindowListener.hpp>
55cdf0e10cSrcweir #include <com/sun/star/awt/XWindow.hpp>
56cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp>
57cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
58cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
59cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
60cdf0e10cSrcweir #include <com/sun/star/lang/XSingleServiceFactory.hpp>
61cdf0e10cSrcweir #include <com/sun/star/beans/Property.hpp>
62cdf0e10cSrcweir 
63cdf0e10cSrcweir #include <rtl/ref.hxx>
64cdf0e10cSrcweir #include <cppuhelper/factory.hxx>
65cdf0e10cSrcweir #include <cppuhelper/queryinterface.hxx>
66cdf0e10cSrcweir 
67cdf0e10cSrcweir #include "atkwrapper.hxx"
68cdf0e10cSrcweir #include "atkregistry.hxx"
69cdf0e10cSrcweir #include "atklistener.hxx"
70cdf0e10cSrcweir 
71cdf0e10cSrcweir #ifdef ENABLE_TRACING
72cdf0e10cSrcweir #include <stdio.h>
73cdf0e10cSrcweir #endif
74cdf0e10cSrcweir 
75cdf0e10cSrcweir #include <string.h>
76cdf0e10cSrcweir 
77cdf0e10cSrcweir using namespace ::com::sun::star;
78cdf0e10cSrcweir 
79cdf0e10cSrcweir static GObjectClass *parent_class = NULL;
80cdf0e10cSrcweir 
mapRelationType(sal_Int16 nRelation)81cdf0e10cSrcweir static AtkRelationType mapRelationType( sal_Int16 nRelation )
82cdf0e10cSrcweir {
83cdf0e10cSrcweir     AtkRelationType type = ATK_RELATION_NULL;
84cdf0e10cSrcweir 
85cdf0e10cSrcweir     switch( nRelation )
86cdf0e10cSrcweir     {
87cdf0e10cSrcweir         case accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM:
88cdf0e10cSrcweir             type = ATK_RELATION_FLOWS_FROM;
89cdf0e10cSrcweir             break;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir         case accessibility::AccessibleRelationType::CONTENT_FLOWS_TO:
92cdf0e10cSrcweir             type = ATK_RELATION_FLOWS_TO;
93cdf0e10cSrcweir             break;
94cdf0e10cSrcweir 
95cdf0e10cSrcweir         case accessibility::AccessibleRelationType::CONTROLLED_BY:
96cdf0e10cSrcweir             type = ATK_RELATION_CONTROLLED_BY;
97cdf0e10cSrcweir             break;
98cdf0e10cSrcweir 
99cdf0e10cSrcweir         case accessibility::AccessibleRelationType::CONTROLLER_FOR:
100cdf0e10cSrcweir             type = ATK_RELATION_CONTROLLER_FOR;
101cdf0e10cSrcweir             break;
102cdf0e10cSrcweir 
103cdf0e10cSrcweir         case accessibility::AccessibleRelationType::LABEL_FOR:
104cdf0e10cSrcweir             type = ATK_RELATION_LABEL_FOR;
105cdf0e10cSrcweir             break;
106cdf0e10cSrcweir 
107cdf0e10cSrcweir         case accessibility::AccessibleRelationType::LABELED_BY:
108cdf0e10cSrcweir             type = ATK_RELATION_LABELLED_BY;
109cdf0e10cSrcweir             break;
110cdf0e10cSrcweir 
111cdf0e10cSrcweir         case accessibility::AccessibleRelationType::MEMBER_OF:
112cdf0e10cSrcweir             type = ATK_RELATION_MEMBER_OF;
113cdf0e10cSrcweir             break;
114cdf0e10cSrcweir 
115cdf0e10cSrcweir         case accessibility::AccessibleRelationType::SUB_WINDOW_OF:
116cdf0e10cSrcweir             type = ATK_RELATION_SUBWINDOW_OF;
117cdf0e10cSrcweir             break;
118cdf0e10cSrcweir 
119cdf0e10cSrcweir         case accessibility::AccessibleRelationType::NODE_CHILD_OF:
120cdf0e10cSrcweir             type = ATK_RELATION_NODE_CHILD_OF;
121cdf0e10cSrcweir             break;
122cdf0e10cSrcweir 
123cdf0e10cSrcweir         default:
124cdf0e10cSrcweir             break;
125cdf0e10cSrcweir     }
126cdf0e10cSrcweir #if 0
127cdf0e10cSrcweir   ATK_RELATION_NODE_CHILD_OF,
128cdf0e10cSrcweir   ATK_RELATION_EMBEDS,
129cdf0e10cSrcweir   ATK_RELATION_EMBEDDED_BY,
130cdf0e10cSrcweir   ATK_RELATION_POPUP_FOR,
131cdf0e10cSrcweir #endif
132cdf0e10cSrcweir     return type;
133cdf0e10cSrcweir }
134cdf0e10cSrcweir 
135cdf0e10cSrcweir 
mapAtkState(sal_Int16 nState)136cdf0e10cSrcweir AtkStateType mapAtkState( sal_Int16 nState )
137cdf0e10cSrcweir {
138cdf0e10cSrcweir     AtkStateType type = ATK_STATE_INVALID;
139cdf0e10cSrcweir 
140cdf0e10cSrcweir     // A perfect / complete mapping ...
141cdf0e10cSrcweir     switch( nState )
142cdf0e10cSrcweir     {
143cdf0e10cSrcweir #define MAP_DIRECT( a ) \
144cdf0e10cSrcweir         case accessibility::AccessibleStateType::a: \
145cdf0e10cSrcweir             type = ATK_STATE_##a; break
146cdf0e10cSrcweir 
147cdf0e10cSrcweir         MAP_DIRECT( INVALID );
148cdf0e10cSrcweir         MAP_DIRECT( ACTIVE );
149cdf0e10cSrcweir         MAP_DIRECT( ARMED );
150cdf0e10cSrcweir         MAP_DIRECT( BUSY );
151cdf0e10cSrcweir         MAP_DIRECT( CHECKED );
152cdf0e10cSrcweir         MAP_DIRECT( EDITABLE );
153cdf0e10cSrcweir         MAP_DIRECT( ENABLED );
154cdf0e10cSrcweir         MAP_DIRECT( EXPANDABLE );
155cdf0e10cSrcweir         MAP_DIRECT( EXPANDED );
156cdf0e10cSrcweir         MAP_DIRECT( FOCUSABLE );
157cdf0e10cSrcweir         MAP_DIRECT( FOCUSED );
158cdf0e10cSrcweir         MAP_DIRECT( HORIZONTAL );
159cdf0e10cSrcweir         MAP_DIRECT( ICONIFIED );
160cdf0e10cSrcweir         MAP_DIRECT( INDETERMINATE );
161cdf0e10cSrcweir         MAP_DIRECT( MANAGES_DESCENDANTS );
162cdf0e10cSrcweir         MAP_DIRECT( MODAL );
163cdf0e10cSrcweir         MAP_DIRECT( MULTI_LINE );
164cdf0e10cSrcweir         MAP_DIRECT( OPAQUE );
165cdf0e10cSrcweir         MAP_DIRECT( PRESSED );
166cdf0e10cSrcweir         MAP_DIRECT( RESIZABLE );
167cdf0e10cSrcweir         MAP_DIRECT( SELECTABLE );
168cdf0e10cSrcweir         MAP_DIRECT( SELECTED );
169cdf0e10cSrcweir         MAP_DIRECT( SENSITIVE );
170cdf0e10cSrcweir         MAP_DIRECT( SHOWING );
171cdf0e10cSrcweir         MAP_DIRECT( SINGLE_LINE );
172cdf0e10cSrcweir         MAP_DIRECT( STALE );
173cdf0e10cSrcweir         MAP_DIRECT( TRANSIENT );
174cdf0e10cSrcweir         MAP_DIRECT( VERTICAL );
175cdf0e10cSrcweir         MAP_DIRECT( VISIBLE );
176cdf0e10cSrcweir         // a spelling error ...
177cdf0e10cSrcweir         case accessibility::AccessibleStateType::DEFUNC:
178cdf0e10cSrcweir             type = ATK_STATE_DEFUNCT; break;
179cdf0e10cSrcweir         case accessibility::AccessibleStateType::MULTI_SELECTABLE:
180cdf0e10cSrcweir             type = ATK_STATE_MULTISELECTABLE; break;
181cdf0e10cSrcweir     default:
182cdf0e10cSrcweir         break;
183cdf0e10cSrcweir     }
184cdf0e10cSrcweir 
185cdf0e10cSrcweir     return type;
186cdf0e10cSrcweir }
187cdf0e10cSrcweir 
registerRole(const gchar * name)188cdf0e10cSrcweir static inline AtkRole registerRole( const gchar * name )
189cdf0e10cSrcweir {
190cdf0e10cSrcweir     AtkRole ret = atk_role_for_name( name );
191cdf0e10cSrcweir     if( ATK_ROLE_INVALID == ret )
192cdf0e10cSrcweir         ret = atk_role_register( name );
193cdf0e10cSrcweir 
194cdf0e10cSrcweir     return ret;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
mapToAtkRole(sal_Int16 nRole)197cdf0e10cSrcweir static AtkRole mapToAtkRole( sal_Int16 nRole )
198cdf0e10cSrcweir {
199cdf0e10cSrcweir     AtkRole role = ATK_ROLE_UNKNOWN;
200cdf0e10cSrcweir 
201cdf0e10cSrcweir     static AtkRole roleMap[] = {
202cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,
203cdf0e10cSrcweir         ATK_ROLE_ALERT,
204cdf0e10cSrcweir         ATK_ROLE_COLUMN_HEADER,
205cdf0e10cSrcweir         ATK_ROLE_CANVAS,
206cdf0e10cSrcweir         ATK_ROLE_CHECK_BOX,
207cdf0e10cSrcweir         ATK_ROLE_CHECK_MENU_ITEM,
208cdf0e10cSrcweir         ATK_ROLE_COLOR_CHOOSER,
209cdf0e10cSrcweir         ATK_ROLE_COMBO_BOX,
210cdf0e10cSrcweir         ATK_ROLE_DATE_EDITOR,
211cdf0e10cSrcweir         ATK_ROLE_DESKTOP_ICON,
212cdf0e10cSrcweir         ATK_ROLE_DESKTOP_FRAME,   // ? pane
213cdf0e10cSrcweir         ATK_ROLE_DIRECTORY_PANE,
214cdf0e10cSrcweir         ATK_ROLE_DIALOG,
215cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,         // DOCUMENT - registered below
216cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,         // EMBEDDED_OBJECT - registered below
217cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,         // END_NOTE - registered below
218cdf0e10cSrcweir         ATK_ROLE_FILE_CHOOSER,
219cdf0e10cSrcweir         ATK_ROLE_FILLER,
220cdf0e10cSrcweir         ATK_ROLE_FONT_CHOOSER,
221cdf0e10cSrcweir         ATK_ROLE_FOOTER,
222cdf0e10cSrcweir         ATK_ROLE_TEXT,            // FOOTNOTE - registered below
223cdf0e10cSrcweir         ATK_ROLE_FRAME,
224cdf0e10cSrcweir         ATK_ROLE_GLASS_PANE,
225cdf0e10cSrcweir         ATK_ROLE_IMAGE,           // GRAPHIC
226cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,         // GROUP_BOX - registered below
227cdf0e10cSrcweir         ATK_ROLE_HEADER,
228cdf0e10cSrcweir         ATK_ROLE_PARAGRAPH,       // HEADING - registered below
229cdf0e10cSrcweir         ATK_ROLE_TEXT,            // HYPER_LINK - registered below
230cdf0e10cSrcweir         ATK_ROLE_ICON,
231cdf0e10cSrcweir         ATK_ROLE_INTERNAL_FRAME,
232cdf0e10cSrcweir         ATK_ROLE_LABEL,
233cdf0e10cSrcweir         ATK_ROLE_LAYERED_PANE,
234cdf0e10cSrcweir         ATK_ROLE_LIST,
235cdf0e10cSrcweir         ATK_ROLE_LIST_ITEM,
236cdf0e10cSrcweir         ATK_ROLE_MENU,
237cdf0e10cSrcweir         ATK_ROLE_MENU_BAR,
238cdf0e10cSrcweir         ATK_ROLE_MENU_ITEM,
239cdf0e10cSrcweir         ATK_ROLE_OPTION_PANE,
240cdf0e10cSrcweir         ATK_ROLE_PAGE_TAB,
241cdf0e10cSrcweir         ATK_ROLE_PAGE_TAB_LIST,
242cdf0e10cSrcweir         ATK_ROLE_PANEL,
243cdf0e10cSrcweir         ATK_ROLE_PARAGRAPH,
244cdf0e10cSrcweir         ATK_ROLE_PASSWORD_TEXT,
245cdf0e10cSrcweir         ATK_ROLE_POPUP_MENU,
246cdf0e10cSrcweir         ATK_ROLE_PUSH_BUTTON,
247cdf0e10cSrcweir         ATK_ROLE_PROGRESS_BAR,
248cdf0e10cSrcweir         ATK_ROLE_RADIO_BUTTON,
249cdf0e10cSrcweir         ATK_ROLE_RADIO_MENU_ITEM,
250cdf0e10cSrcweir         ATK_ROLE_ROW_HEADER,
251cdf0e10cSrcweir         ATK_ROLE_ROOT_PANE,
252cdf0e10cSrcweir         ATK_ROLE_SCROLL_BAR,
253cdf0e10cSrcweir         ATK_ROLE_SCROLL_PANE,
254cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,        // SHAPE - registered below
255cdf0e10cSrcweir         ATK_ROLE_SEPARATOR,
256cdf0e10cSrcweir         ATK_ROLE_SLIDER,
257cdf0e10cSrcweir         ATK_ROLE_SPIN_BUTTON,    // SPIN_BOX ?
258cdf0e10cSrcweir         ATK_ROLE_SPLIT_PANE,
259cdf0e10cSrcweir         ATK_ROLE_STATUSBAR,
260cdf0e10cSrcweir         ATK_ROLE_TABLE,
261cdf0e10cSrcweir         ATK_ROLE_TABLE_CELL,
262cdf0e10cSrcweir         ATK_ROLE_TEXT,
263cdf0e10cSrcweir         ATK_ROLE_INTERNAL_FRAME, // TEXT_FRAME - registered below
264cdf0e10cSrcweir         ATK_ROLE_TOGGLE_BUTTON,
265cdf0e10cSrcweir         ATK_ROLE_TOOL_BAR,
266cdf0e10cSrcweir         ATK_ROLE_TOOL_TIP,
267cdf0e10cSrcweir         ATK_ROLE_TREE,
268cdf0e10cSrcweir         ATK_ROLE_VIEWPORT,
269cdf0e10cSrcweir         ATK_ROLE_WINDOW,
270cdf0e10cSrcweir         ATK_ROLE_PUSH_BUTTON,   // BUTTON_DROPDOWN
271cdf0e10cSrcweir         ATK_ROLE_PUSH_BUTTON,   // BUTTON_MENU
272cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,       // CAPTION - registered below
273cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,       // CHART - registered below
274cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,       // EDIT_BAR - registered below
275cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,       // FORM - registered below
276cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,       // IMAGE_MAP - registered below
277cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,       // NOTE - registered below
278cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,       // PAGE - registered below
279cdf0e10cSrcweir         ATK_ROLE_RULER,
280cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,       // SECTION - registered below
281cdf0e10cSrcweir         ATK_ROLE_UNKNOWN,       // TREE_ITEM - registered below
282cdf0e10cSrcweir         ATK_ROLE_TREE_TABLE,
283cdf0e10cSrcweir         ATK_ROLE_SCROLL_PANE,   // COMMENT - mapped to atk_role_scroll_pane
284cdf0e10cSrcweir         ATK_ROLE_UNKNOWN        // COMMENT_END - mapped to atk_role_unknown
285cdf0e10cSrcweir     };
286cdf0e10cSrcweir 
287cdf0e10cSrcweir     static bool initialized = false;
288cdf0e10cSrcweir 
289cdf0e10cSrcweir     if( ! initialized )
290cdf0e10cSrcweir     {
291cdf0e10cSrcweir         // re-use strings from ATK library
292cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::EDIT_BAR] = registerRole("edit bar");
293cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::EMBEDDED_OBJECT] = registerRole("embedded component");
294cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::CHART] = registerRole("chart");
295cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::CAPTION] = registerRole("caption");
296cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::DOCUMENT] = registerRole("document frame");
297cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::HEADING] = registerRole("heading");
298cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::PAGE] = registerRole("page");
299cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::SECTION] = registerRole("section");
300cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::FORM] = registerRole("form");
301cdf0e10cSrcweir 
302cdf0e10cSrcweir         // these don't exist in ATK yet
303cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::END_NOTE] = registerRole("end note");
304cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::FOOTNOTE] = registerRole("foot note");
305cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::GROUP_BOX] = registerRole("group box");
306cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::HYPER_LINK] = registerRole("hyper link");
307cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::SHAPE] = registerRole("shape");
308cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::TEXT_FRAME] = registerRole("text frame");
309cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::IMAGE_MAP] = registerRole("image map");
310cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::NOTE] = registerRole("note");
311cdf0e10cSrcweir         roleMap[accessibility::AccessibleRole::TREE_ITEM] = registerRole("tree item");
312cdf0e10cSrcweir 
313cdf0e10cSrcweir         initialized = true;
314cdf0e10cSrcweir     }
315cdf0e10cSrcweir 
31693ed1f29SArmin Le Grand     static const sal_Int32 nMapSize = sizeof(roleMap)/sizeof(roleMap[0]);
317cdf0e10cSrcweir     if( 0 <= nRole &&  nMapSize > nRole )
318cdf0e10cSrcweir         role = roleMap[nRole];
319cdf0e10cSrcweir 
320cdf0e10cSrcweir     return role;
321cdf0e10cSrcweir }
322cdf0e10cSrcweir 
323cdf0e10cSrcweir 
324cdf0e10cSrcweir /*****************************************************************************/
325cdf0e10cSrcweir 
326cdf0e10cSrcweir extern "C" {
327cdf0e10cSrcweir 
328cdf0e10cSrcweir /*****************************************************************************/
329cdf0e10cSrcweir 
330cdf0e10cSrcweir static G_CONST_RETURN gchar*
wrapper_get_name(AtkObject * atk_obj)331cdf0e10cSrcweir wrapper_get_name( AtkObject *atk_obj )
332cdf0e10cSrcweir {
333cdf0e10cSrcweir     AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj);
334cdf0e10cSrcweir 
335cdf0e10cSrcweir     if( obj->mpContext )
336cdf0e10cSrcweir     {
337cdf0e10cSrcweir         try {
338cdf0e10cSrcweir             rtl::OString aName =
339cdf0e10cSrcweir                 rtl::OUStringToOString(
340cdf0e10cSrcweir                     obj->mpContext->getAccessibleName(),
341cdf0e10cSrcweir                     RTL_TEXTENCODING_UTF8);
342cdf0e10cSrcweir 
343cdf0e10cSrcweir             int nCmp = atk_obj->name ? rtl_str_compare( atk_obj->name, aName.getStr() ) : -1;
344cdf0e10cSrcweir             if( nCmp != 0 )
345cdf0e10cSrcweir             {
346cdf0e10cSrcweir                 if( atk_obj->name )
347cdf0e10cSrcweir                     g_free(atk_obj->name);
348cdf0e10cSrcweir                 atk_obj->name = g_strdup(aName.getStr());
349cdf0e10cSrcweir             }
350cdf0e10cSrcweir         }
351cdf0e10cSrcweir         catch(const uno::Exception& e) {
352cdf0e10cSrcweir             g_warning( "Exception in getAccessibleName()" );
353cdf0e10cSrcweir         }
354cdf0e10cSrcweir     }
355cdf0e10cSrcweir 
356cdf0e10cSrcweir     return ATK_OBJECT_CLASS (parent_class)->get_name(atk_obj);
357cdf0e10cSrcweir }
358cdf0e10cSrcweir 
359cdf0e10cSrcweir /*****************************************************************************/
360cdf0e10cSrcweir 
361cdf0e10cSrcweir static G_CONST_RETURN gchar*
wrapper_get_description(AtkObject * atk_obj)362cdf0e10cSrcweir wrapper_get_description( AtkObject *atk_obj )
363cdf0e10cSrcweir {
364cdf0e10cSrcweir     AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj);
365cdf0e10cSrcweir 
366cdf0e10cSrcweir     if( obj->mpContext )
367cdf0e10cSrcweir     {
368cdf0e10cSrcweir         try {
369cdf0e10cSrcweir             rtl::OString aDescription =
370cdf0e10cSrcweir                 rtl::OUStringToOString(
371cdf0e10cSrcweir                     obj->mpContext->getAccessibleDescription(),
372cdf0e10cSrcweir                     RTL_TEXTENCODING_UTF8);
373cdf0e10cSrcweir 
374cdf0e10cSrcweir             g_free(atk_obj->description);
375cdf0e10cSrcweir             atk_obj->description = g_strdup(aDescription.getStr());
376cdf0e10cSrcweir         }
377cdf0e10cSrcweir         catch(const uno::Exception& e) {
378cdf0e10cSrcweir             g_warning( "Exception in getAccessibleDescription()" );
379cdf0e10cSrcweir         }
380cdf0e10cSrcweir     }
381cdf0e10cSrcweir 
382cdf0e10cSrcweir     return ATK_OBJECT_CLASS (parent_class)->get_description(atk_obj);
383cdf0e10cSrcweir 
384cdf0e10cSrcweir }
385cdf0e10cSrcweir 
386cdf0e10cSrcweir /*****************************************************************************/
387cdf0e10cSrcweir 
388cdf0e10cSrcweir static gint
wrapper_get_n_children(AtkObject * atk_obj)389cdf0e10cSrcweir wrapper_get_n_children( AtkObject *atk_obj )
390cdf0e10cSrcweir {
391cdf0e10cSrcweir     AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj);
392cdf0e10cSrcweir     gint n = 0;
393cdf0e10cSrcweir 
394cdf0e10cSrcweir     if( obj->mpContext )
395cdf0e10cSrcweir     {
396cdf0e10cSrcweir         try {
397cdf0e10cSrcweir             n = obj->mpContext->getAccessibleChildCount();
398cdf0e10cSrcweir         }
399cdf0e10cSrcweir         catch(const uno::Exception& e) {
400cdf0e10cSrcweir             OSL_ENSURE(0, "Exception in getAccessibleChildCount()" );
401cdf0e10cSrcweir         }
402cdf0e10cSrcweir     }
403cdf0e10cSrcweir 
404cdf0e10cSrcweir     return n;
405cdf0e10cSrcweir }
406cdf0e10cSrcweir 
407cdf0e10cSrcweir /*****************************************************************************/
408cdf0e10cSrcweir 
409cdf0e10cSrcweir static AtkObject *
wrapper_ref_child(AtkObject * atk_obj,gint i)410cdf0e10cSrcweir wrapper_ref_child( AtkObject *atk_obj,
411cdf0e10cSrcweir                    gint       i )
412cdf0e10cSrcweir {
413cdf0e10cSrcweir     AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj);
414cdf0e10cSrcweir     AtkObject* child = NULL;
415cdf0e10cSrcweir 
416cdf0e10cSrcweir     // see comments above atk_object_wrapper_remove_child
417cdf0e10cSrcweir     if( -1 < i && obj->index_of_child_about_to_be_removed == i )
418cdf0e10cSrcweir     {
419cdf0e10cSrcweir         g_object_ref( obj->child_about_to_be_removed );
420cdf0e10cSrcweir         return obj->child_about_to_be_removed;
421cdf0e10cSrcweir     }
422cdf0e10cSrcweir 
423cdf0e10cSrcweir     if( obj->mpContext )
424cdf0e10cSrcweir     {
425cdf0e10cSrcweir         try {
426cdf0e10cSrcweir             uno::Reference< accessibility::XAccessible > xAccessible =
427cdf0e10cSrcweir                 obj->mpContext->getAccessibleChild( i );
428cdf0e10cSrcweir 
429cdf0e10cSrcweir             child = atk_object_wrapper_ref( xAccessible );
430cdf0e10cSrcweir         }
431cdf0e10cSrcweir         catch(const uno::Exception& e) {
432cdf0e10cSrcweir             OSL_ENSURE(0, "Exception in getAccessibleChild");
433cdf0e10cSrcweir         }
434cdf0e10cSrcweir     }
435cdf0e10cSrcweir 
436cdf0e10cSrcweir     return child;
437cdf0e10cSrcweir }
438cdf0e10cSrcweir 
439cdf0e10cSrcweir /*****************************************************************************/
440cdf0e10cSrcweir 
441cdf0e10cSrcweir static gint
wrapper_get_index_in_parent(AtkObject * atk_obj)442cdf0e10cSrcweir wrapper_get_index_in_parent( AtkObject *atk_obj )
443cdf0e10cSrcweir {
444cdf0e10cSrcweir     AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj);
445cdf0e10cSrcweir     gint i = -1;
446cdf0e10cSrcweir 
447cdf0e10cSrcweir     if( obj->mpContext )
448cdf0e10cSrcweir     {
449cdf0e10cSrcweir         try {
450cdf0e10cSrcweir             i = obj->mpContext->getAccessibleIndexInParent();
451cdf0e10cSrcweir 
452cdf0e10cSrcweir #ifdef ENABLE_TRACING
453cdf0e10cSrcweir             fprintf(stderr, "%p->getAccessibleIndexInParent() returned: %u\n",
454cdf0e10cSrcweir                 obj->mpAccessible, i);
455cdf0e10cSrcweir #endif
456cdf0e10cSrcweir         }
457cdf0e10cSrcweir         catch(const uno::Exception& e) {
458cdf0e10cSrcweir             g_warning( "Exception in getAccessibleIndexInParent()" );
459cdf0e10cSrcweir         }
460cdf0e10cSrcweir     }
461cdf0e10cSrcweir     return i;
462cdf0e10cSrcweir }
463cdf0e10cSrcweir 
464cdf0e10cSrcweir /*****************************************************************************/
465cdf0e10cSrcweir 
466cdf0e10cSrcweir static AtkRelationSet *
wrapper_ref_relation_set(AtkObject * atk_obj)467cdf0e10cSrcweir wrapper_ref_relation_set( AtkObject *atk_obj )
468cdf0e10cSrcweir {
469cdf0e10cSrcweir     AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj);
470cdf0e10cSrcweir     AtkRelationSet *pSet = atk_relation_set_new();
471cdf0e10cSrcweir 
472cdf0e10cSrcweir     if( obj->mpContext )
473cdf0e10cSrcweir     {
474cdf0e10cSrcweir         try {
475cdf0e10cSrcweir             uno::Reference< accessibility::XAccessibleRelationSet > xRelationSet(
476cdf0e10cSrcweir                     obj->mpContext->getAccessibleRelationSet()
477cdf0e10cSrcweir             );
478cdf0e10cSrcweir 
479cdf0e10cSrcweir             sal_Int32 nRelations = xRelationSet.is() ? xRelationSet->getRelationCount() : 0;
480cdf0e10cSrcweir             for( sal_Int32 n = 0; n < nRelations; n++ )
481cdf0e10cSrcweir             {
482cdf0e10cSrcweir                 accessibility::AccessibleRelation aRelation = xRelationSet->getRelation( n );
483cdf0e10cSrcweir                 sal_uInt32 nTargetCount = aRelation.TargetSet.getLength();
484cdf0e10cSrcweir                 AtkObject **pTargets = (AtkObject **) alloca( nTargetCount * sizeof(AtkObject *) );
485cdf0e10cSrcweir 
486cdf0e10cSrcweir                 for( sal_uInt32 i = 0; i < nTargetCount; i++ )
487cdf0e10cSrcweir                 {
488cdf0e10cSrcweir                     uno::Reference< accessibility::XAccessible > xAccessible(
489cdf0e10cSrcweir                             aRelation.TargetSet[i], uno::UNO_QUERY );
490cdf0e10cSrcweir                     pTargets[i] = atk_object_wrapper_ref( xAccessible );
491cdf0e10cSrcweir                 }
492cdf0e10cSrcweir 
493cdf0e10cSrcweir                 AtkRelation *pRel =
494cdf0e10cSrcweir                     atk_relation_new(
495cdf0e10cSrcweir                         pTargets, nTargetCount,
496cdf0e10cSrcweir                         mapRelationType( aRelation.RelationType )
497cdf0e10cSrcweir                     );
498cdf0e10cSrcweir                 atk_relation_set_add( pSet, pRel );
499cdf0e10cSrcweir                 g_object_unref( G_OBJECT( pRel ) );
500cdf0e10cSrcweir             }
501cdf0e10cSrcweir         }
502cdf0e10cSrcweir         catch(const uno::Exception &e) {
503cdf0e10cSrcweir             g_object_unref( G_OBJECT( pSet ) );
504cdf0e10cSrcweir             pSet = NULL;
505cdf0e10cSrcweir         }
506cdf0e10cSrcweir     }
507cdf0e10cSrcweir 
508cdf0e10cSrcweir     return pSet;
509cdf0e10cSrcweir }
510cdf0e10cSrcweir 
511cdf0e10cSrcweir /*****************************************************************************/
512cdf0e10cSrcweir 
513cdf0e10cSrcweir #if 0
514cdf0e10cSrcweir struct {
515cdf0e10cSrcweir     sal_Int16       value;
516cdf0e10cSrcweir     const sal_Char* name;
517cdf0e10cSrcweir } aStateTypeTable[] = {
518cdf0e10cSrcweir     { accessibility::AccessibleStateType::INVALID, "INVALID" },
519cdf0e10cSrcweir     { accessibility::AccessibleStateType::ACTIVE, "ACTIVE" },
520cdf0e10cSrcweir     { accessibility::AccessibleStateType::ARMED, "ARMED" },
521cdf0e10cSrcweir     { accessibility::AccessibleStateType::BUSY, "BUSY" },
522cdf0e10cSrcweir     { accessibility::AccessibleStateType::CHECKED, "CHECKED" },
523cdf0e10cSrcweir     { accessibility::AccessibleStateType::DEFUNC, "DEFUNC" },
524cdf0e10cSrcweir     { accessibility::AccessibleStateType::EDITABLE, "EDITABLE" },
525cdf0e10cSrcweir     { accessibility::AccessibleStateType::ENABLED, "ENABLED" },
526cdf0e10cSrcweir     { accessibility::AccessibleStateType::EXPANDABLE, "EXPANDABLE" },
527cdf0e10cSrcweir     { accessibility::AccessibleStateType::EXPANDED, "EXPANDED" },
528cdf0e10cSrcweir     { accessibility::AccessibleStateType::FOCUSABLE, "FOCUSABLE" },
529cdf0e10cSrcweir     { accessibility::AccessibleStateType::FOCUSED, "FOCUSED" },
530cdf0e10cSrcweir     { accessibility::AccessibleStateType::HORIZONTAL, "HORIZONTAL" },
531cdf0e10cSrcweir     { accessibility::AccessibleStateType::ICONIFIED, "ICONIFIED" },
532cdf0e10cSrcweir     { accessibility::AccessibleStateType::INDETERMINATE, "INDETERMINATE" },
533cdf0e10cSrcweir     { accessibility::AccessibleStateType::MANAGES_DESCENDANTS, "MANAGES_DESCENDANTS" },
534cdf0e10cSrcweir     { accessibility::AccessibleStateType::MODAL, "MODAL" },
535cdf0e10cSrcweir     { accessibility::AccessibleStateType::MULTI_LINE, "MULTI_LINE" },
536cdf0e10cSrcweir     { accessibility::AccessibleStateType::MULTI_SELECTABLE, "MULTI_SELECTABLE" },
537cdf0e10cSrcweir     { accessibility::AccessibleStateType::OPAQUE, "OPAQUE" },
538cdf0e10cSrcweir     { accessibility::AccessibleStateType::PRESSED, "PRESSED" },
539cdf0e10cSrcweir     { accessibility::AccessibleStateType::RESIZABLE, "RESIZABLE" },
540cdf0e10cSrcweir     { accessibility::AccessibleStateType::SELECTABLE, "SELECTABLE" },
541cdf0e10cSrcweir     { accessibility::AccessibleStateType::SELECTED, "SELECTED" },
542cdf0e10cSrcweir     { accessibility::AccessibleStateType::SENSITIVE, "SENSITIVE" },
543cdf0e10cSrcweir     { accessibility::AccessibleStateType::SHOWING, "SHOWING" },
544cdf0e10cSrcweir     { accessibility::AccessibleStateType::SINGLE_LINE, "SINGLE_LINE" },
545cdf0e10cSrcweir     { accessibility::AccessibleStateType::STALE, "STALE" },
546cdf0e10cSrcweir     { accessibility::AccessibleStateType::TRANSIENT, "TRANSIENT" },
547cdf0e10cSrcweir     { accessibility::AccessibleStateType::VERTICAL, "VERTICAL" },
548cdf0e10cSrcweir     { accessibility::AccessibleStateType::VISIBLE, "VISIBLE" }
549cdf0e10cSrcweir };
550cdf0e10cSrcweir 
551cdf0e10cSrcweir static void printStates(const uno::Sequence<sal_Int16>& rStates)
552cdf0e10cSrcweir {
553cdf0e10cSrcweir     sal_Int32 n = rStates.getLength();
554cdf0e10cSrcweir     size_t nTypes = sizeof(aStateTypeTable)/sizeof(aStateTypeTable[0]);
555cdf0e10cSrcweir     for (sal_Int32 i = 0; i < n; ++i)
556cdf0e10cSrcweir     {
557cdf0e10cSrcweir         for (size_t j = 0; j < nTypes; ++j)
558cdf0e10cSrcweir         {
559cdf0e10cSrcweir             if (aStateTypeTable[j].value == rStates[i])
560cdf0e10cSrcweir                 printf("%s ", aStateTypeTable[j].name);
561cdf0e10cSrcweir         }
562cdf0e10cSrcweir     }
563cdf0e10cSrcweir     printf("\n");
564cdf0e10cSrcweir }
565cdf0e10cSrcweir #endif
566cdf0e10cSrcweir 
567cdf0e10cSrcweir static AtkStateSet *
wrapper_ref_state_set(AtkObject * atk_obj)568cdf0e10cSrcweir wrapper_ref_state_set( AtkObject *atk_obj )
569cdf0e10cSrcweir {
570cdf0e10cSrcweir     AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj);
571cdf0e10cSrcweir     AtkStateSet *pSet = atk_state_set_new();
572cdf0e10cSrcweir 
573cdf0e10cSrcweir     if( obj->mpContext )
574cdf0e10cSrcweir     {
575cdf0e10cSrcweir         try {
576cdf0e10cSrcweir             uno::Reference< accessibility::XAccessibleStateSet > xStateSet(
577cdf0e10cSrcweir                 obj->mpContext->getAccessibleStateSet());
578cdf0e10cSrcweir 
579cdf0e10cSrcweir             if( xStateSet.is() )
580cdf0e10cSrcweir             {
581cdf0e10cSrcweir                 uno::Sequence< sal_Int16 > aStates = xStateSet->getStates();
582cdf0e10cSrcweir 
583cdf0e10cSrcweir                 for( sal_Int32 n = 0; n < aStates.getLength(); n++ )
584cdf0e10cSrcweir                     atk_state_set_add_state( pSet, mapAtkState( aStates[n] ) );
585cdf0e10cSrcweir 
586cdf0e10cSrcweir                 // We need to emulate FOCUS state for menus, menu-items etc.
587cdf0e10cSrcweir                 if( atk_obj == atk_get_focus_object() )
588cdf0e10cSrcweir                     atk_state_set_add_state( pSet, ATK_STATE_FOCUSED );
589cdf0e10cSrcweir /* FIXME - should we do this ?
590cdf0e10cSrcweir                 else
591cdf0e10cSrcweir                     atk_state_set_remove_state( pSet, ATK_STATE_FOCUSED );
592cdf0e10cSrcweir */
593cdf0e10cSrcweir             }
594cdf0e10cSrcweir         }
595cdf0e10cSrcweir 
596cdf0e10cSrcweir         catch(const uno::Exception &e) {
597cdf0e10cSrcweir             g_warning( "Exception in wrapper_ref_state_set" );
598cdf0e10cSrcweir             atk_state_set_add_state( pSet, ATK_STATE_DEFUNCT );
599cdf0e10cSrcweir         }
600cdf0e10cSrcweir     }
601cdf0e10cSrcweir     else
602cdf0e10cSrcweir         atk_state_set_add_state( pSet, ATK_STATE_DEFUNCT );
603cdf0e10cSrcweir 
604cdf0e10cSrcweir     return pSet;
605cdf0e10cSrcweir }
606cdf0e10cSrcweir 
607cdf0e10cSrcweir /*****************************************************************************/
608cdf0e10cSrcweir 
609cdf0e10cSrcweir 
610cdf0e10cSrcweir static void
atk_object_wrapper_finalize(GObject * obj)611cdf0e10cSrcweir atk_object_wrapper_finalize (GObject *obj)
612cdf0e10cSrcweir {
613cdf0e10cSrcweir     AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER (obj);
614cdf0e10cSrcweir 
615cdf0e10cSrcweir     if( pWrap->mpAccessible )
616cdf0e10cSrcweir     {
617cdf0e10cSrcweir         ooo_wrapper_registry_remove( pWrap->mpAccessible );
618cdf0e10cSrcweir         pWrap->mpAccessible->release();
619cdf0e10cSrcweir         pWrap->mpAccessible = NULL;
620cdf0e10cSrcweir     }
621cdf0e10cSrcweir 
622cdf0e10cSrcweir     atk_object_wrapper_dispose( pWrap );
623cdf0e10cSrcweir 
624cdf0e10cSrcweir     parent_class->finalize( obj );
625cdf0e10cSrcweir }
626cdf0e10cSrcweir 
627cdf0e10cSrcweir static void
atk_object_wrapper_class_init(AtkObjectWrapperClass * klass)628cdf0e10cSrcweir atk_object_wrapper_class_init (AtkObjectWrapperClass *klass)
629cdf0e10cSrcweir {
630cdf0e10cSrcweir   GObjectClass *gobject_class = G_OBJECT_CLASS( klass );
631cdf0e10cSrcweir   AtkObjectClass *atk_class = ATK_OBJECT_CLASS( klass );
632cdf0e10cSrcweir 
633cdf0e10cSrcweir   parent_class = (GObjectClass *) g_type_class_peek_parent (klass);
634cdf0e10cSrcweir 
635cdf0e10cSrcweir   // GObject methods
636cdf0e10cSrcweir   gobject_class->finalize = atk_object_wrapper_finalize;
637cdf0e10cSrcweir 
638cdf0e10cSrcweir   // AtkObject methods
639cdf0e10cSrcweir   atk_class->get_name = wrapper_get_name;
640cdf0e10cSrcweir   atk_class->get_description = wrapper_get_description;
641cdf0e10cSrcweir   atk_class->get_n_children = wrapper_get_n_children;
642cdf0e10cSrcweir   atk_class->ref_child = wrapper_ref_child;
643cdf0e10cSrcweir   atk_class->get_index_in_parent = wrapper_get_index_in_parent;
644cdf0e10cSrcweir   atk_class->ref_relation_set = wrapper_ref_relation_set;
645cdf0e10cSrcweir   atk_class->ref_state_set = wrapper_ref_state_set;
646cdf0e10cSrcweir }
647cdf0e10cSrcweir 
648cdf0e10cSrcweir static void
atk_object_wrapper_init(AtkObjectWrapper * wrapper,AtkObjectWrapperClass)649cdf0e10cSrcweir atk_object_wrapper_init (AtkObjectWrapper      *wrapper,
650cdf0e10cSrcweir                          AtkObjectWrapperClass)
651cdf0e10cSrcweir {
652cdf0e10cSrcweir    wrapper->mpAction = NULL;
653cdf0e10cSrcweir    wrapper->mpComponent = NULL;
654cdf0e10cSrcweir    wrapper->mpEditableText = NULL;
655cdf0e10cSrcweir    wrapper->mpHypertext = NULL;
656cdf0e10cSrcweir    wrapper->mpImage = NULL;
657cdf0e10cSrcweir    wrapper->mpSelection = NULL;
658cdf0e10cSrcweir    wrapper->mpTable = NULL;
659cdf0e10cSrcweir    wrapper->mpText = NULL;
660cdf0e10cSrcweir    wrapper->mpValue = NULL;
661cdf0e10cSrcweir }
662cdf0e10cSrcweir 
663cdf0e10cSrcweir } // extern "C"
664cdf0e10cSrcweir 
665cdf0e10cSrcweir GType
atk_object_wrapper_get_type(void)666cdf0e10cSrcweir atk_object_wrapper_get_type (void)
667cdf0e10cSrcweir {
668cdf0e10cSrcweir   static GType type = 0;
669cdf0e10cSrcweir 
670cdf0e10cSrcweir   if (!type)
671cdf0e10cSrcweir     {
672cdf0e10cSrcweir       static const GTypeInfo typeInfo =
673cdf0e10cSrcweir       {
674cdf0e10cSrcweir         sizeof (AtkObjectWrapperClass),
675cdf0e10cSrcweir         (GBaseInitFunc) NULL,
676cdf0e10cSrcweir         (GBaseFinalizeFunc) NULL,
677cdf0e10cSrcweir         (GClassInitFunc) atk_object_wrapper_class_init,
678cdf0e10cSrcweir         (GClassFinalizeFunc) NULL,
679cdf0e10cSrcweir         NULL,
680cdf0e10cSrcweir         sizeof (AtkObjectWrapper),
681cdf0e10cSrcweir         0,
682cdf0e10cSrcweir         (GInstanceInitFunc) atk_object_wrapper_init,
683cdf0e10cSrcweir         NULL
684cdf0e10cSrcweir       } ;
685cdf0e10cSrcweir       type = g_type_register_static (ATK_TYPE_OBJECT,
686cdf0e10cSrcweir                                      "OOoAtkObj",
687cdf0e10cSrcweir                                      &typeInfo, (GTypeFlags)0) ;
688cdf0e10cSrcweir     }
689cdf0e10cSrcweir   return type;
690cdf0e10cSrcweir }
691cdf0e10cSrcweir 
692cdf0e10cSrcweir static bool
isOfType(uno::XInterface * pInterface,const uno::Type & rType)693cdf0e10cSrcweir isOfType( uno::XInterface *pInterface, const uno::Type & rType )
694cdf0e10cSrcweir {
695cdf0e10cSrcweir     g_return_val_if_fail( pInterface != NULL, false );
696cdf0e10cSrcweir 
697cdf0e10cSrcweir     bool bIs = false;
698cdf0e10cSrcweir     try {
699cdf0e10cSrcweir         uno::Any aRet = pInterface->queryInterface( rType );
700cdf0e10cSrcweir 
701cdf0e10cSrcweir         bIs = ( ( typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass ) &&
702cdf0e10cSrcweir                 ( aRet.pReserved != NULL ) );
703cdf0e10cSrcweir     } catch( const uno::Exception &e) { }
704cdf0e10cSrcweir 
705cdf0e10cSrcweir     return bIs;
706cdf0e10cSrcweir }
707cdf0e10cSrcweir 
708cdf0e10cSrcweir extern "C" {
709cdf0e10cSrcweir typedef  GType (* GetGIfaceType ) (void);
710cdf0e10cSrcweir }
711cdf0e10cSrcweir const struct {
712cdf0e10cSrcweir         const char          *name;
713cdf0e10cSrcweir         GInterfaceInitFunc   aInit;
714cdf0e10cSrcweir         GetGIfaceType        aGetGIfaceType;
715cdf0e10cSrcweir         const uno::Type &  (*aGetUnoType) (void *);
716cdf0e10cSrcweir } aTypeTable[] = {
717cdf0e10cSrcweir // re-location heaven:
718cdf0e10cSrcweir     {
719cdf0e10cSrcweir         "Comp", (GInterfaceInitFunc) componentIfaceInit,
720cdf0e10cSrcweir         atk_component_get_type,
721cdf0e10cSrcweir         accessibility::XAccessibleComponent::static_type
722cdf0e10cSrcweir     },
723cdf0e10cSrcweir     {
724cdf0e10cSrcweir         "Act",  (GInterfaceInitFunc) actionIfaceInit,
725cdf0e10cSrcweir         atk_action_get_type,
726cdf0e10cSrcweir         accessibility::XAccessibleAction::static_type
727cdf0e10cSrcweir     },
728cdf0e10cSrcweir     {
729cdf0e10cSrcweir         "Txt",  (GInterfaceInitFunc) textIfaceInit,
730cdf0e10cSrcweir         atk_text_get_type,
731cdf0e10cSrcweir         accessibility::XAccessibleText::static_type
732cdf0e10cSrcweir     },
733cdf0e10cSrcweir     {
734cdf0e10cSrcweir         "Val",  (GInterfaceInitFunc) valueIfaceInit,
735cdf0e10cSrcweir         atk_value_get_type,
736cdf0e10cSrcweir         accessibility::XAccessibleValue::static_type
737cdf0e10cSrcweir     },
738cdf0e10cSrcweir     {
739cdf0e10cSrcweir         "Tab",  (GInterfaceInitFunc) tableIfaceInit,
740cdf0e10cSrcweir         atk_table_get_type,
741cdf0e10cSrcweir         accessibility::XAccessibleTable::static_type
742cdf0e10cSrcweir     },
743cdf0e10cSrcweir     {
744cdf0e10cSrcweir         "Edt",  (GInterfaceInitFunc) editableTextIfaceInit,
745cdf0e10cSrcweir         atk_editable_text_get_type,
746cdf0e10cSrcweir         accessibility::XAccessibleEditableText::static_type
747cdf0e10cSrcweir     },
748cdf0e10cSrcweir     {
749cdf0e10cSrcweir         "Img",  (GInterfaceInitFunc) imageIfaceInit,
750cdf0e10cSrcweir         atk_image_get_type,
751cdf0e10cSrcweir         accessibility::XAccessibleImage::static_type
752cdf0e10cSrcweir     },
753cdf0e10cSrcweir     {
754cdf0e10cSrcweir         "Hyp",  (GInterfaceInitFunc) hypertextIfaceInit,
755cdf0e10cSrcweir         atk_hypertext_get_type,
756cdf0e10cSrcweir         accessibility::XAccessibleHypertext::static_type
757cdf0e10cSrcweir     },
758cdf0e10cSrcweir     {
759cdf0e10cSrcweir         "Sel",  (GInterfaceInitFunc) selectionIfaceInit,
760cdf0e10cSrcweir         atk_selection_get_type,
761cdf0e10cSrcweir         accessibility::XAccessibleSelection::static_type
762cdf0e10cSrcweir     }
763cdf0e10cSrcweir     // AtkDocument is a nastily broken interface (so far)
764cdf0e10cSrcweir     //  we could impl. get_document_type perhaps though.
765cdf0e10cSrcweir };
766cdf0e10cSrcweir 
767cdf0e10cSrcweir const int aTypeTableSize = G_N_ELEMENTS( aTypeTable );
768cdf0e10cSrcweir 
769cdf0e10cSrcweir static GType
ensureTypeFor(uno::XInterface * pAccessible)770cdf0e10cSrcweir ensureTypeFor( uno::XInterface *pAccessible )
771cdf0e10cSrcweir {
772cdf0e10cSrcweir     int i;
773cdf0e10cSrcweir     int bTypes[ aTypeTableSize ] = { 0, };
774cdf0e10cSrcweir     rtl::OString aTypeName( "OOoAtkObj" );
775cdf0e10cSrcweir 
776cdf0e10cSrcweir     for( i = 0; i < aTypeTableSize; i++ )
777cdf0e10cSrcweir     {
778cdf0e10cSrcweir         if( isOfType( pAccessible, aTypeTable[i].aGetUnoType(0) ) )
779cdf0e10cSrcweir         {
780cdf0e10cSrcweir             aTypeName += aTypeTable[i].name;
781cdf0e10cSrcweir             bTypes[i] = TRUE;
782cdf0e10cSrcweir         }
783cdf0e10cSrcweir //      g_message( "Accessible %p has type '%s' (%d)",
784cdf0e10cSrcweir //                 pAccessible, aTypeTable[i].name, bTypes[i] );
785cdf0e10cSrcweir     }
786cdf0e10cSrcweir 
787*24c56ab9SHerbert Dürr     GType nType = g_type_from_name( aTypeName.getStr() );
788cdf0e10cSrcweir     if( nType == G_TYPE_INVALID )
789cdf0e10cSrcweir     {
790cdf0e10cSrcweir         GTypeInfo aTypeInfo = {
791cdf0e10cSrcweir             sizeof( AtkObjectWrapperClass ),
792cdf0e10cSrcweir             NULL, NULL, NULL, NULL, NULL,
793cdf0e10cSrcweir             sizeof( AtkObjectWrapper ),
794cdf0e10cSrcweir             0, NULL, NULL
795cdf0e10cSrcweir         } ;
796cdf0e10cSrcweir         nType = g_type_register_static( ATK_TYPE_OBJECT_WRAPPER,
797*24c56ab9SHerbert Dürr                                         aTypeName.getStr(), &aTypeInfo, (GTypeFlags)0 ) ;
798cdf0e10cSrcweir 
799cdf0e10cSrcweir         for( int j = 0; j < aTypeTableSize; j++ )
800cdf0e10cSrcweir             if( bTypes[j] )
801cdf0e10cSrcweir             {
802cdf0e10cSrcweir                 GInterfaceInfo aIfaceInfo = { NULL, NULL, NULL };
803cdf0e10cSrcweir                 aIfaceInfo.interface_init = aTypeTable[j].aInit;
804cdf0e10cSrcweir                 g_type_add_interface_static (nType, aTypeTable[j].aGetGIfaceType(),
805cdf0e10cSrcweir                                              &aIfaceInfo);
806cdf0e10cSrcweir             }
807cdf0e10cSrcweir     }
808cdf0e10cSrcweir     return nType;
809cdf0e10cSrcweir }
810cdf0e10cSrcweir 
811cdf0e10cSrcweir AtkObject *
atk_object_wrapper_ref(const uno::Reference<accessibility::XAccessible> & rxAccessible,bool create)812cdf0e10cSrcweir atk_object_wrapper_ref( const uno::Reference< accessibility::XAccessible > &rxAccessible, bool create )
813cdf0e10cSrcweir {
814cdf0e10cSrcweir     g_return_val_if_fail( rxAccessible.get() != NULL, NULL );
815cdf0e10cSrcweir 
816cdf0e10cSrcweir     AtkObject *obj = ooo_wrapper_registry_get(rxAccessible);
817cdf0e10cSrcweir     if( obj )
818cdf0e10cSrcweir     {
819cdf0e10cSrcweir         g_object_ref( obj );
820cdf0e10cSrcweir         return obj;
821cdf0e10cSrcweir     }
822cdf0e10cSrcweir 
823cdf0e10cSrcweir     if( create )
824cdf0e10cSrcweir         return atk_object_wrapper_new( rxAccessible );
825cdf0e10cSrcweir 
826cdf0e10cSrcweir     return NULL;
827cdf0e10cSrcweir }
828cdf0e10cSrcweir 
829cdf0e10cSrcweir 
830cdf0e10cSrcweir AtkObject *
atk_object_wrapper_new(const::com::sun::star::uno::Reference<::com::sun::star::accessibility::XAccessible> & rxAccessible,AtkObject * parent)831cdf0e10cSrcweir atk_object_wrapper_new( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& rxAccessible,
832cdf0e10cSrcweir                         AtkObject* parent )
833cdf0e10cSrcweir {
834cdf0e10cSrcweir     g_return_val_if_fail( rxAccessible.get() != NULL, NULL );
835cdf0e10cSrcweir 
836cdf0e10cSrcweir     AtkObjectWrapper *pWrap = NULL;
837cdf0e10cSrcweir 
838cdf0e10cSrcweir     try {
839cdf0e10cSrcweir         uno::Reference< accessibility::XAccessibleContext > xContext(rxAccessible->getAccessibleContext());
840cdf0e10cSrcweir 
841cdf0e10cSrcweir         g_return_val_if_fail( xContext.get() != NULL, NULL );
842cdf0e10cSrcweir 
843cdf0e10cSrcweir         GType nType = ensureTypeFor( xContext.get() );
844cdf0e10cSrcweir         gpointer obj = g_object_new( nType, NULL);
845cdf0e10cSrcweir 
846cdf0e10cSrcweir         pWrap = ATK_OBJECT_WRAPPER( obj );
847cdf0e10cSrcweir         pWrap->mpAccessible = rxAccessible.get();
848cdf0e10cSrcweir         rxAccessible->acquire();
849cdf0e10cSrcweir 
850cdf0e10cSrcweir         pWrap->index_of_child_about_to_be_removed = -1;
851cdf0e10cSrcweir         pWrap->child_about_to_be_removed = NULL;
852cdf0e10cSrcweir 
853cdf0e10cSrcweir         xContext->acquire();
854cdf0e10cSrcweir         pWrap->mpContext = xContext.get();
855cdf0e10cSrcweir 
856cdf0e10cSrcweir         AtkObject* atk_obj = ATK_OBJECT(pWrap);
857cdf0e10cSrcweir         atk_obj->role = mapToAtkRole( xContext->getAccessibleRole() );
858cdf0e10cSrcweir         atk_obj->accessible_parent = parent;
859cdf0e10cSrcweir 
860cdf0e10cSrcweir         ooo_wrapper_registry_add( rxAccessible, atk_obj );
861cdf0e10cSrcweir 
862cdf0e10cSrcweir         if( parent )
863cdf0e10cSrcweir             g_object_ref( atk_obj->accessible_parent );
864cdf0e10cSrcweir         else
865cdf0e10cSrcweir         {
866cdf0e10cSrcweir             /* gail_focus_tracker remembers the focused object at the first
867cdf0e10cSrcweir              * parent in the hierachy that is a Gtk+ widget, but at the time the
868cdf0e10cSrcweir              * event gets processed (at idle), it may be too late to create the
869cdf0e10cSrcweir              * hierachy, so doing it now ..
870cdf0e10cSrcweir              */
871cdf0e10cSrcweir             uno::Reference< accessibility::XAccessible > xParent( xContext->getAccessibleParent() );
872cdf0e10cSrcweir 
873cdf0e10cSrcweir             /* The top-level objects should never be of this class */
874cdf0e10cSrcweir             OSL_ASSERT( xParent.is() );
875cdf0e10cSrcweir 
876cdf0e10cSrcweir             if( xParent.is() )
877cdf0e10cSrcweir                 atk_obj->accessible_parent = atk_object_wrapper_ref( xParent );
878cdf0e10cSrcweir         }
879cdf0e10cSrcweir 
880cdf0e10cSrcweir         // Attach a listener to the UNO object if it's not TRANSIENT
881cdf0e10cSrcweir         uno::Reference< accessibility::XAccessibleStateSet > xStateSet( xContext->getAccessibleStateSet() );
882cdf0e10cSrcweir         if( xStateSet.is() && ! xStateSet->contains( accessibility::AccessibleStateType::TRANSIENT ) )
883cdf0e10cSrcweir         {
884cdf0e10cSrcweir             uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster(xContext, uno::UNO_QUERY);
885cdf0e10cSrcweir             if( xBroadcaster.is() )
886cdf0e10cSrcweir                 xBroadcaster->addEventListener( static_cast< accessibility::XAccessibleEventListener * > ( new AtkListener(pWrap) ) );
887cdf0e10cSrcweir 	    else
888cdf0e10cSrcweir                 OSL_ASSERT( false );
889cdf0e10cSrcweir         }
890cdf0e10cSrcweir 
891cdf0e10cSrcweir         return ATK_OBJECT( pWrap );
892cdf0e10cSrcweir     }
893cdf0e10cSrcweir     catch (const uno::Exception &e)
894cdf0e10cSrcweir     {
895cdf0e10cSrcweir         if( pWrap )
896cdf0e10cSrcweir             g_object_unref( pWrap );
897cdf0e10cSrcweir 
898cdf0e10cSrcweir         return NULL;
899cdf0e10cSrcweir     }
900cdf0e10cSrcweir }
901cdf0e10cSrcweir 
902cdf0e10cSrcweir 
903cdf0e10cSrcweir /*****************************************************************************/
904cdf0e10cSrcweir 
atk_object_wrapper_add_child(AtkObjectWrapper * wrapper,AtkObject * child,gint index)905cdf0e10cSrcweir void atk_object_wrapper_add_child(AtkObjectWrapper* wrapper, AtkObject *child, gint index)
906cdf0e10cSrcweir {
907cdf0e10cSrcweir     AtkObject *atk_obj = ATK_OBJECT( wrapper );
908cdf0e10cSrcweir 
909cdf0e10cSrcweir     atk_object_set_parent( child, atk_obj );
910cdf0e10cSrcweir     g_signal_emit_by_name( atk_obj, "children_changed::add", index, child, NULL );
911cdf0e10cSrcweir }
912cdf0e10cSrcweir 
913cdf0e10cSrcweir /*****************************************************************************/
914cdf0e10cSrcweir 
atk_object_wrapper_remove_child(AtkObjectWrapper * wrapper,AtkObject * child,gint index)915cdf0e10cSrcweir void atk_object_wrapper_remove_child(AtkObjectWrapper* wrapper, AtkObject *child, gint index)
916cdf0e10cSrcweir {
917cdf0e10cSrcweir     /*
918cdf0e10cSrcweir      * the atk-bridge GTK+ module get's back to the event source to ref the child just
919cdf0e10cSrcweir      * vanishing, so we keep this reference because the semantic on OOo side is different.
920cdf0e10cSrcweir      */
921cdf0e10cSrcweir     wrapper->child_about_to_be_removed = child;
922cdf0e10cSrcweir     wrapper->index_of_child_about_to_be_removed = index;
923cdf0e10cSrcweir 
924cdf0e10cSrcweir     g_signal_emit_by_name( ATK_OBJECT( wrapper ), "children_changed::remove", index, child, NULL );
925cdf0e10cSrcweir 
926cdf0e10cSrcweir     wrapper->index_of_child_about_to_be_removed = -1;
927cdf0e10cSrcweir     wrapper->child_about_to_be_removed = NULL;
928cdf0e10cSrcweir }
929cdf0e10cSrcweir 
930cdf0e10cSrcweir /*****************************************************************************/
931cdf0e10cSrcweir 
932cdf0e10cSrcweir #define RELEASE(i) if( i ) { i->release(); i = NULL; }
933cdf0e10cSrcweir 
atk_object_wrapper_dispose(AtkObjectWrapper * wrapper)934cdf0e10cSrcweir void atk_object_wrapper_dispose(AtkObjectWrapper* wrapper)
935cdf0e10cSrcweir {
936cdf0e10cSrcweir     RELEASE( wrapper->mpContext )
937cdf0e10cSrcweir     RELEASE( wrapper->mpAction )
938cdf0e10cSrcweir     RELEASE( wrapper->mpComponent )
939cdf0e10cSrcweir     RELEASE( wrapper->mpEditableText )
940cdf0e10cSrcweir     RELEASE( wrapper->mpHypertext )
941cdf0e10cSrcweir     RELEASE( wrapper->mpImage )
942cdf0e10cSrcweir     RELEASE( wrapper->mpSelection )
943cdf0e10cSrcweir     RELEASE( wrapper->mpMultiLineText )
944cdf0e10cSrcweir     RELEASE( wrapper->mpTable )
945cdf0e10cSrcweir     RELEASE( wrapper->mpText )
946cdf0e10cSrcweir     RELEASE( wrapper->mpTextMarkup )
947cdf0e10cSrcweir     RELEASE( wrapper->mpTextAttributes )
948cdf0e10cSrcweir     RELEASE( wrapper->mpValue )
949cdf0e10cSrcweir }
950