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

Generated by: LCOV version 1.10