LCOV - code coverage report
Current view: top level - vcl/unx/gtk/a11y - atkwrapper.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 346 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 24 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11