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

Generated by: LCOV version 1.10