[Libreoffice-commits] core.git: Branch 'feature/ia2.4' - include/sal include/vcl vcl/source vcl/win winaccessibility/inc winaccessibility/Library_uacccom.mk winaccessibility/source

Michael Meeks michael.meeks at collabora.com
Mon Nov 18 15:13:24 PST 2013


Rebased ref, commits from common ancestor:
commit 5dbe8f35176bed789515b19636618968d1ac8228
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Nov 18 15:41:26 2013 +0000

    uia: merge VCL pieces of IAccessible2 work.
    
    Original code from:
        Author: Steve Yin <steve_y at apache.org>
        Date:   Sat Nov 16 23:58:19 2013 +0100
    
            Integrate branch of IAccessible2
    
    With these improvements:
    
    Make IAccessible2 an experimental feature, with fallback to Java a11y.
    Move initial setup of windows into the bridge and clean, remove conditionals
    Check for presence of AT in the bridge as well to clean. Merge VCL events
    extensions and their handling. Clean and split WB_GETOBJECT handling out to
    it's own method. Add component prefix namespacing.
    Cleanup msaa service info, and implement XComponent to share mxAccessBridge.
    Add suitable debugging output, remove VCL dependency from UAccCOM causing
    registration issues.
    
    Change-Id: Ib19e38ddca71182018df438df27dcdb555d91402

diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index ca635c4..a6ffef9 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -346,6 +346,10 @@ certain functionality.
 @li @c vcl.virdev
 @li @c vcl.window
 
+ at section winaccessiblity
+
+ at li @c iacc2 - IAccessible2 bridge debug
+
 @section Writer
 
 @li @c sw
diff --git a/include/vcl/vclevent.hxx b/include/vcl/vclevent.hxx
index 1ce025f..92ffca9 100644
--- a/include/vcl/vclevent.hxx
+++ b/include/vcl/vclevent.hxx
@@ -151,6 +151,7 @@ namespace com { namespace sun { namespace star {
 #define VCLEVENT_ITEM_EXPANDED              1174
 #define VCLEVENT_ITEM_COLLAPSED             1175
 #define VCLEVENT_DROPDOWN_PRE_OPEN          1176
+#define VCLEVENT_LISTBOX_FOCUSITEMCHANGED   1180
 
 // VclMenuEvent
 #define VCLEVENT_MENU_ACTIVATE              1200
@@ -169,23 +170,35 @@ namespace com { namespace sun { namespace star {
 #define VCLEVENT_MENU_ITEMCHECKED           1213
 #define VCLEVENT_MENU_ITEMUNCHECKED         1214
 #define VCLEVENT_MENU_ACCESSIBLENAMECHANGED 1215
+#define VCLEVENT_TOOLBOX_ITEMWINDOWCHANGED  1216
+#define VCLEVENT_TOOLBOX_ITEMUPDATED  1217
 
 #define VCLEVENT_MENU_SHOW                  1250
 #define VCLEVENT_MENU_HIDE                  1251
 
 #define VCLEVENT_TOOLBOX_ITEMWINDOWCHANGED  1216
+#define VCLEVENT_LISTBOX_TREEEXPAND             1218
+#define VCLEVENT_LISTBOX_TREECOLLAPSE           1219
+#define VCLEVENT_LISTBOX_TREEFOCUS              1220
+#define VCLEVENT_LISTBOX_TREESELECT             1221
+#define VCLEVENT_EDIT_CARETCHANGED  1222
+#define VCLEVENT_COMBOBOX_UPDATEVALUE  1223
+
+#define VCLEVENT_LISTBOX_FOCUS             1224
+#define VCLEVENT_LISTBOX_CLEAR             1225
 
 // DockingWindow
-#define VCLEVENT_WINDOW_STARTDOCKING            1217    // pData = DockingData
-#define VCLEVENT_WINDOW_DOCKING                 1218
-#define VCLEVENT_WINDOW_ENDDOCKING              1219    // pData = EndDockingData
-#define VCLEVENT_WINDOW_PREPARETOGGLEFLOATING   1220    // pData = sal_Bool
-#define VCLEVENT_WINDOW_TOGGLEFLOATING          1221
-#define VCLEVENT_WINDOW_ENDPOPUPMODE            1222    // pData = EndPopupModeData
-
-#define VCLEVENT_TOOLBOX_BUTTONSTATECHANGED     1223    // pData = itempos
-#define VCLEVENT_TABLECELL_NAMECHANGED          1224    // pData = struct(Entry, Column, oldText)
-#define VCLEVENT_TABLEROW_SELECT                1225
+#define VCLEVENT_WINDOW_STARTDOCKING            1227    // pData = DockingData
+#define VCLEVENT_WINDOW_DOCKING                 1228
+#define VCLEVENT_WINDOW_ENDDOCKING              1229    // pData = EndDockingData
+#define VCLEVENT_WINDOW_PREPARETOGGLEFLOATING   1230    // pData = sal_Bool
+#define VCLEVENT_WINDOW_TOGGLEFLOATING          1231
+#define VCLEVENT_WINDOW_ENDPOPUPMODE            1232    // pData = EndPopupModeData
+
+#define VCLEVENT_TOOLBOX_BUTTONSTATECHANGED     1233    // pData = itempos
+#define VCLEVENT_TABLECELL_NAMECHANGED          1234    // pData = struct(Entry, Column, oldText)
+#define VCLEVENT_TABLEROW_SELECT                1235
+#define VCLEVENT_LISTBOX_STATEUPDATE            1236
 
 class VCL_DLLPUBLIC VclSimpleEvent
 {
diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
index b42eeea..cb24f02 100644
--- a/vcl/source/app/svdata.cxx
+++ b/vcl/source/app/svdata.cxx
@@ -52,6 +52,8 @@
 #include "com/sun/star/java/MissingJavaRuntimeException.hpp"
 #include "com/sun/star/java/JavaDisabledException.hpp"
 
+#include "officecfg/Office/Common.hxx"
+
 #include <stdio.h>
 
 using namespace com::sun::star::uno;
@@ -321,6 +323,20 @@ bool ImplInitAccessBridge(bool bAllowCancel, bool &rCancelled)
         {
             css::uno::Reference< XComponentContext > xContext(comphelper::getProcessComponentContext());
 
+            bool bTryIAcc2 = ( officecfg::Office::Common::Misc::ExperimentalMode::get( xContext ) &&
+                               !getenv ("SAL_DISABLE_IACCESSIBLE2") );
+
+            if ( bTryIAcc2 ) // Windows only really
+            {
+                // FIXME: convert to service ... pSVData->mxAccessBridge = css::accessibility::MSAAService::create( xContext );
+                pSVData->mxAccessBridge = Reference< XComponent >( xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.accessibility.MSAAService", xContext ), UNO_QUERY );
+
+                SAL_INFO( "vcl", "IAccessible2 bridge is: " << (int)(pSVData->mxAccessBridge.is()) );
+                return pSVData->mxAccessBridge.is();
+            }
+            else
+                SAL_INFO( "vcl", "IAccessible2 disabled, falling back to java" );
+
             css::uno::Reference< XExtendedToolkit > xToolkit =
                 css::uno::Reference< XExtendedToolkit >(Application::GetVCLToolkit(), UNO_QUERY);
 
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 24edbd1..90a15d9 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -8817,10 +8817,10 @@ sal_uInt16 Window::getDefaultAccessibleRole() const
         case WINDOW_CANCELBUTTON:
         case WINDOW_HELPBUTTON:
         case WINDOW_IMAGEBUTTON:
-        case WINDOW_MENUBUTTON:
         case WINDOW_MOREBUTTON:
         case WINDOW_SPINBUTTON:
         case WINDOW_BUTTON: nRole = accessibility::AccessibleRole::PUSH_BUTTON; break;
+        case WINDOW_MENUBUTTON: nRole = accessibility::AccessibleRole::BUTTON_MENU; break;
 
         case WINDOW_PATHDIALOG: nRole = accessibility::AccessibleRole::DIRECTORY_PANE; break;
         case WINDOW_FILEDIALOG: nRole = accessibility::AccessibleRole::FILE_CHOOSER; break;
@@ -8834,10 +8834,6 @@ sal_uInt16 Window::getDefaultAccessibleRole() const
         case WINDOW_MULTILINEEDIT: nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
 
         case WINDOW_PATTERNFIELD:
-        case WINDOW_NUMERICFIELD:
-        case WINDOW_METRICFIELD:
-        case WINDOW_CURRENCYFIELD:
-        case WINDOW_LONGCURRENCYFIELD:
         case WINDOW_CALCINPUTLINE:
         case WINDOW_EDIT: nRole = ( GetStyle() & WB_PASSWORD ) ? (accessibility::AccessibleRole::PASSWORD_TEXT) : (accessibility::AccessibleRole::TEXT); break;
 
@@ -8854,7 +8850,13 @@ sal_uInt16 Window::getDefaultAccessibleRole() const
         case WINDOW_TREELISTBOX: nRole = accessibility::AccessibleRole::TREE; break;
 
         case WINDOW_FIXEDTEXT: nRole = accessibility::AccessibleRole::LABEL; break;
-        case WINDOW_FIXEDLINE: nRole = accessibility::AccessibleRole::SEPARATOR; break;
+        case WINDOW_FIXEDLINE:
+            if( !GetText().isEmpty() )
+                nRole = accessibility::AccessibleRole::LABEL;
+            else
+                nRole = accessibility::AccessibleRole::SEPARATOR;
+            break;
+
         case WINDOW_FIXEDBITMAP:
         case WINDOW_FIXEDIMAGE: nRole = accessibility::AccessibleRole::ICON; break;
         case WINDOW_GROUPBOX: nRole = accessibility::AccessibleRole::GROUP_BOX; break;
@@ -8869,6 +8871,10 @@ sal_uInt16 Window::getDefaultAccessibleRole() const
         case WINDOW_DATEFIELD:
         case WINDOW_TIMEFIELD: nRole = accessibility::AccessibleRole::DATE_EDITOR; break;
 
+        case WINDOW_NUMERICFIELD:
+        case WINDOW_METRICFIELD:
+        case WINDOW_CURRENCYFIELD:
+        case WINDOW_LONGCURRENCYFIELD:
         case WINDOW_SPINFIELD: nRole = accessibility::AccessibleRole::SPIN_BOX; break;
 
         case WINDOW_TOOLBOX: nRole = accessibility::AccessibleRole::TOOL_BAR; break;
@@ -8932,8 +8938,12 @@ void Window::SetAccessibleName( const OUString& rName )
    if ( !mpWindowImpl->mpAccessibleInfos )
         mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
 
+    OUString oldName = GetAccessibleName();
+
     delete mpWindowImpl->mpAccessibleInfos->pAccessibleName;
     mpWindowImpl->mpAccessibleInfos->pAccessibleName = new OUString( rName );
+
+    ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldName );
 }
 
 OUString Window::GetAccessibleName() const
@@ -8974,6 +8984,8 @@ OUString Window::getDefaultAccessibleName() const
             Window *pLabel = GetAccessibleRelationLabeledBy();
             if ( pLabel && pLabel != this )
                 aAccessibleName = pLabel->GetText();
+            if (aAccessibleName.isEmpty())
+                aAccessibleName = GetQuickHelpText();
         }
         break;
 
@@ -8988,6 +9000,16 @@ OUString Window::getDefaultAccessibleName() const
             }
         break;
 
+        case WINDOW_TOOLBOX:
+            aAccessibleName = GetText();
+            if( aAccessibleName.isEmpty() )
+                aAccessibleName = "Tool Bar";
+            break;
+
+        case WINDOW_MOREBUTTON:
+            aAccessibleName = mpWindowImpl->maText;
+            break;
+
         default:
             aAccessibleName = GetText();
             break;
diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx
index 87e5c1a..8ee2cae 100644
--- a/vcl/win/source/window/salframe.cxx
+++ b/vcl/win/source/window/salframe.cxx
@@ -77,6 +77,12 @@ using ::std::max;
 
 #include <com/sun/star/uno/Exception.hpp>
 
+#include <oleacc.h>
+#include <com/sun/star/accessibility/XMSAAService.hpp>
+#ifndef WM_GETOBJECT // TESTME does this ever happen ?
+#  define WM_GETOBJECT  0x003D
+#endif
+
 #include <time.h>
 
 #if defined ( __MINGW32__ )
@@ -5178,7 +5184,7 @@ static sal_Bool ImplHandleIMEStartComposition( HWND hWnd )
 // -----------------------------------------------------------------------
 
 static sal_Bool ImplHandleIMECompositionInput( WinSalFrame* pFrame,
-                                           HIMC hIMC, LPARAM lParam )
+                                               HIMC hIMC, LPARAM lParam )
 {
     sal_Bool bDef = TRUE;
 
@@ -5478,6 +5484,46 @@ static void ImplHandleIMENotify( HWND hWnd, WPARAM wParam )
 
 // -----------------------------------------------------------------------
 
+static bool ImplHandleGetObject( HWND hWnd, LPARAM lParam, WPARAM wParam, long &nRet )
+{
+    // IA2 should be enabled automatically
+    AllSettings aSettings = Application::GetSettings();
+    MiscSettings aMisc = aSettings.GetMiscSettings();
+    aMisc.SetEnableATToolSupport( sal_True );
+    aSettings.SetMiscSettings( aMisc );
+    Application::SetSettings( aSettings );
+
+    if (!Application::GetSettings().GetMiscSettings().GetEnableATToolSupport())
+        return false; // locked down somehow ?
+
+    ImplSVData* pSVData = ImplGetSVData();
+
+    // Make sure to launch Accessibiliity only the following criterias are satisfied
+    // to avoid RFT interrupts regular accessibility processing
+    if ( !pSVData->mxAccessBridge.is() )
+    {
+        bool bCancelled = false;
+        InitAccessBridge( false, bCancelled );
+        if( bCancelled )
+            return false;
+    }
+
+    uno::Reference< accessibility::XMSAAService > xMSAA( pSVData->mxAccessBridge, uno::UNO_QUERY );
+    if ( xMSAA.is() )
+    {
+        // mhOnSetTitleWnd not set to reasonable value anywhere...
+        if ( lParam == OBJID_CLIENT )
+        {
+            nRet = xMSAA->getAccObjectPtr( (long)hWnd, lParam, wParam );
+            if( nRet != 0 )
+                return true;
+        }
+    }
+    return false;
+}
+
+// -----------------------------------------------------------------------
+
 static LRESULT ImplHandleIMEReconvertString( HWND hWnd, LPARAM lParam )
 {
     WinSalFrame* pFrame = GetWindowPtr( hWnd );
@@ -6005,6 +6051,16 @@ LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lP
         case WM_IME_NOTIFY:
             ImplHandleIMENotify( hWnd, wParam );
             break;
+
+        case WM_GETOBJECT:
+            long nRet;
+            if ( ImplHandleGetObject( hWnd, lParam, wParam, nRet ) )
+            {
+                rDef = false;
+                return (HRESULT) nRet;
+            }
+            break;
+
         case WM_APPCOMMAND:
             if( ImplHandleAppCommand( hWnd, lParam ) )
             {
diff --git a/winaccessibility/Library_uacccom.mk b/winaccessibility/Library_uacccom.mk
index b3b91ce..f481b40 100755
--- a/winaccessibility/Library_uacccom.mk
+++ b/winaccessibility/Library_uacccom.mk
@@ -41,7 +41,6 @@ $(eval $(call gb_Library_add_exception_objects,UAccCOM,\
 	winaccessibility/source/UAccCOM/AccText \
 	winaccessibility/source/UAccCOM/AccTextBase \
 	winaccessibility/source/UAccCOM/AccValue \
-	winaccessibility/source/UAccCOM/CheckEnableAccessible \
 	winaccessibility/source/UAccCOM/EnumVariant \
 	winaccessibility/source/UAccCOM/MAccessible \
 	winaccessibility/source/UAccCOM/StdAfx \
@@ -58,7 +57,6 @@ $(eval $(call gb_Library_add_ldflags,UAccCOM,\
 
 $(eval $(call gb_Library_use_libraries,UAccCOM,\
 	cppu \
-    vcl \
 	sal \
 ))
 
diff --git a/winaccessibility/inc/AccObject.hxx b/winaccessibility/inc/AccObject.hxx
index 1692064..ae63900 100644
--- a/winaccessibility/inc/AccObject.hxx
+++ b/winaccessibility/inc/AccObject.hxx
@@ -58,7 +58,7 @@ private:
     ::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessibleAction > m_xAccActionRef;
     ::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessibleContext > m_xAccContextRef;
 
-    sal_Bool ImplInitilizeCreateObj();//create COM object
+    sal_Bool ImplInitializeCreateObj();//create COM object
 
     void UpdateActionDesc();
     void UpdateRole();
diff --git a/winaccessibility/inc/g_msacc.hxx b/winaccessibility/inc/g_msacc.hxx
index df6e4bd..d700249 100644
--- a/winaccessibility/inc/g_msacc.hxx
+++ b/winaccessibility/inc/g_msacc.hxx
@@ -20,6 +20,10 @@
 #ifndef __G_MSACC_HXX
 #define __G_MSACC_HXX
 
+extern void FreeTopWindowListener();
+extern void handleWindowOpened_impl( long pAcc );
+extern long GetMSComPtr( long hWnd, long lParam, long wParam );
+
 extern AccTopWindowListener* g_pTop;
 
 #endif
diff --git a/winaccessibility/source/UAccCOM/CheckEnableAccessible.cxx b/winaccessibility/source/UAccCOM/CheckEnableAccessible.cxx
deleted file mode 100755
index 128d2cb..0000000
--- a/winaccessibility/source/UAccCOM/CheckEnableAccessible.cxx
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#define _USE_NAMESPACE
-
-#ifndef _SV_SVAPP_HXX
-#include <vcl/svapp.hxx>
-#endif
-
-#include "CheckEnableAccessible.h"
-
-
-bool IsEnableAccessibleInterface()
-{
-    return Application::IsEnableAccessInterface();
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/CheckEnableAccessible.h b/winaccessibility/source/UAccCOM/CheckEnableAccessible.h
index 7170e9f..90099ac 100644
--- a/winaccessibility/source/UAccCOM/CheckEnableAccessible.h
+++ b/winaccessibility/source/UAccCOM/CheckEnableAccessible.h
@@ -20,7 +20,7 @@
 #ifndef _CHECKENABLEACCESSIBLE_HXX
 #define _CHECKENABLEACCESSIBLE_HXX
 
-bool IsEnableAccessibleInterface();
+inline bool IsEnableAccessibleInterface() { return true; }
 
 #define CHECK_ENABLE_INF if(!IsEnableAccessibleInterface()){ return S_FALSE; }
 #define CHECK_ENABLE_INF_ZERO if(!IsEnableAccessibleInterface()){ return 0; }
diff --git a/winaccessibility/source/UAccCOM/stdafx.h b/winaccessibility/source/UAccCOM/stdafx.h
index b933b12..6b2ccdd 100644
--- a/winaccessibility/source/UAccCOM/stdafx.h
+++ b/winaccessibility/source/UAccCOM/stdafx.h
@@ -28,10 +28,6 @@
 #pragma once
 #endif // _MSC_VER > 1000
 
-//#define STRICT
-//#ifndef _WIN32_WINNT
-//#define _WIN32_WINNT 0x0400
-//#endif
 //#define _ATL_APARTMENT_THREADED
 
 #include <atlbase.h>
@@ -56,6 +52,7 @@ extern CComModule _Module;
 #include <windows.h>
 #undef OPAQUE
 #include "CheckEnableAccessible.h"
+
 //{{AFX_INSERT_LOCATION}}
 // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
 
diff --git a/winaccessibility/source/service/AccFrameEventListener.cxx b/winaccessibility/source/service/AccFrameEventListener.cxx
index a57fc3c..81b81ff 100755
--- a/winaccessibility/source/service/AccFrameEventListener.cxx
+++ b/winaccessibility/source/service/AccFrameEventListener.cxx
@@ -32,20 +32,7 @@ using namespace com::sun::star::accessibility;
 
 #include <vcl/window.hxx>
 #include <toolkit/awt/Vclxwindow.hxx>
-
-//#ifndef _SV_SYSDATA_HXX
-#if 0
-#if defined( WIN ) || defined( WNT ) || defined( OS2 )
-typedef sal_Int32 HWND;
-typedef sal_Int32 HMENU;
-typedef sal_Int32 HDC;
-typedef void *PVOID;
-typedef PVOID HANDLE;
-typedef HANDLE HFONT;
-#endif
-#endif
 #include <vcl/sysdata.hxx>
-//#endif
 
 AccFrameEventListener::AccFrameEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
         :AccEventListener(pAcc, Agent)
diff --git a/winaccessibility/source/service/AccObject.cxx b/winaccessibility/source/service/AccObject.cxx
index 300ebce..ad6b181 100644
--- a/winaccessibility/source/service/AccObject.cxx
+++ b/winaccessibility/source/service/AccObject.cxx
@@ -53,7 +53,8 @@ using namespace com::sun::star::accessibility::AccessibleStateType;
    * @param listener listener that registers in UNO system.
    * @return.
    */
-AccObject::AccObject(XAccessible* pAcc,AccObjectManagerAgent* pAgent ,AccEventListener* listener) :
+AccObject::AccObject(XAccessible* pAcc, AccObjectManagerAgent* pAgent,
+                     AccEventListener* listener) :
         m_pIMAcc    (NULL),
         m_resID     (NULL),
         m_pParantID (NULL),
@@ -62,7 +63,7 @@ AccObject::AccObject(XAccessible* pAcc,AccObjectManagerAgent* pAgent ,AccEventLi
         m_bShouldDestroy(sal_False),
         m_xAccRef( pAcc )
 {
-    sal_Bool bRet = ImplInitilizeCreateObj();
+    sal_Bool bRet = ImplInitializeCreateObj();
 
     m_xAccContextRef = m_xAccRef->getAccessibleContext();
     m_xAccActionRef = Reference< XAccessibleAction > (m_xAccContextRef,UNO_QUERY);
@@ -150,12 +151,14 @@ void AccObject::UpdateValidWindow()
    * @param
    * @return If the method is correctly processed.
    */
-sal_Bool AccObject::ImplInitilizeCreateObj()
+sal_Bool AccObject::ImplInitializeCreateObj()
 {
     ActivateActContext();
-    HRESULT hr = CoCreateInstance( CLSID_MAccessible, NULL, CLSCTX_ALL ,
+    HRESULT hr = CoCreateInstance( CLSID_MAccessible, NULL, CLSCTX_ALL,
                                    IID_IMAccessible,
                                    (void **)&m_pIMAcc);
+    if( !m_pIMAcc )
+        SAL_WARN( "iacc2", "Failed to create IAccessible2 instance" );
     DeactivateActContext();
 
     if ( S_OK != hr )
@@ -312,7 +315,6 @@ void  AccObject::SetValue( Any pAny )
         m_pIMAcc->Put_XAccValue( val.getStr() );
         break;
     case TREE_ITEM:
-    //IAccessibility2 Implementation 2009-----
     //case CHECK_BOX:   //Commented by Li Xing to disable the value for general checkbox
     case COMBO_BOX:
     case TABLE_CELL:
@@ -324,7 +326,6 @@ void  AccObject::SetValue( Any pAny )
     case CHECK_BOX:
         if( ( m_pParentObj !=NULL ) && (TREE == m_pParentObj->m_accRole || TREE_ITEM == m_pParentObj->m_accRole ))
             m_pIMAcc->Put_XAccValue( GetMAccessibleValueFromAny(pAny).getStr() );
-    //-----IAccessibility2 Implementation 2009
         break;
     default:
         break;
diff --git a/winaccessibility/source/service/AccTopWindowListener.cxx b/winaccessibility/source/service/AccTopWindowListener.cxx
index 28d2b79..5c55cbd 100755
--- a/winaccessibility/source/service/AccTopWindowListener.cxx
+++ b/winaccessibility/source/service/AccTopWindowListener.cxx
@@ -23,17 +23,6 @@
 #include <vcl/window.hxx>
 #include <toolkit/awt/Vclxwindow.hxx>
 
-//#ifndef _SV_SYSDATA_HXX
-#if 0
-#if defined( WIN ) || defined( WNT ) || defined( OS2 )
-typedef sal_Int32 HWND;
-typedef sal_Int32 HMENU;
-typedef sal_Int32 HDC;
-typedef void *PVOID;
-typedef PVOID HANDLE;
-typedef HANDLE HFONT;
-#endif
-#endif
 #include <vcl/sysdata.hxx>
 
 #include "AccTopWindowListener.hxx"
@@ -53,11 +42,9 @@ using namespace com::sun::star::bridge;
 using namespace com::sun::star::awt;
 using namespace rtl;
 using namespace cppu;
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
 
 AccTopWindowListener* g_pTop = NULL;
+
 //when proccess exit, call FreeTopWindowListener() in svmain
 void FreeTopWindowListener()
 {
@@ -73,7 +60,7 @@ void FreeTopWindowListener()
  */
 void handleWindowOpened_impl(long pAcc)
 {
-    if( g_pTop && pAcc != NULL )
+    if( g_pTop && pAcc != 0 )
         g_pTop->handleWindowOpened( (com::sun::star::accessibility::XAccessible*)((void*)pAcc) );
 }
 
@@ -99,14 +86,13 @@ void AccTopWindowListener::handleWindowOpened( com::sun::star::accessibility::XA
     }
     Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
     if(!xContext.is())
-    {
         return;
-    }
+
     com::sun::star::accessibility::XAccessibleContext* pAccessibleContext = xContext.get();
     //Only AccessibleContext exist, add all listeners
     if(pAccessibleContext != NULL && systemdata != NULL)
     {
-      accManagerAgent.SaveTopWindowHandle((long)(HWND)systemdata->hWnd,  pAccessible);
+        accManagerAgent.SaveTopWindowHandle((long)(HWND)systemdata->hWnd, pAccessible);
 
         AddAllListeners(pAccessible,NULL,(HWND)systemdata->hWnd);
 
@@ -115,7 +101,6 @@ void AccTopWindowListener::handleWindowOpened( com::sun::star::accessibility::XA
 
         short role = pAccessibleContext->getAccessibleRole();
 
-
         if (role == com::sun::star::accessibility::AccessibleRole::POPUP_MENU ||
                 role == com::sun::star::accessibility::AccessibleRole::MENU )
         {
@@ -147,20 +132,17 @@ AccTopWindowListener::~AccTopWindowListener()
  */
 void AccTopWindowListener::windowOpened( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException)
 {
+    SAL_INFO( "iacc2", "windowOpened triggered" );
+
     if ( !e.Source.is())
-    {
         return;
-    }
 
     Reference< com::sun::star::accessibility::XAccessible > xAccessible ( e.Source, UNO_QUERY );
     com::sun::star::accessibility::XAccessible* pAccessible = xAccessible.get();
-    if ( pAccessible == NULL)
-    {
+    if ( !pAccessible )
         return;
-    }
-
-    handleWindowOpened(pAccessible);
 
+    handleWindowOpened( pAccessible );
 }
 
 /**
@@ -213,16 +195,14 @@ void AccTopWindowListener::AddAllListeners(com::sun::star::accessibility::XAcces
             = mpAccessible->getAccessibleContext();
             com::sun::star::accessibility::XAccessibleContext* mpContext = mxAccessibleContext.get();
             if(mpContext != NULL)
-            {
-                //fprintf(output, "go on add child's children event listener\n");
-                AddAllListeners(mpAccessible,pAccessible,pWND);
-            }
+                AddAllListeners( mpAccessible, pAccessible, pWND);
         }
     }
 }
 
 void AccTopWindowListener::windowClosing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
 {
+    SAL_INFO( "iacc2", "windowClosing triggered" );
 }
 
 /**
@@ -232,17 +212,15 @@ void AccTopWindowListener::windowClosing( const ::com::sun::star::lang::EventObj
  */
 void AccTopWindowListener::windowClosed( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException)
 {
+    SAL_INFO( "iacc2", "windowClosed triggered" );
+
     if ( !e.Source.is())
-    {
         return;
-    }
+
     Reference< com::sun::star::accessibility::XAccessible > xAccessible ( e.Source, UNO_QUERY );
     com::sun::star::accessibility::XAccessible* pAccessible = xAccessible.get();
     if ( pAccessible == NULL)
-    {
         return;
-    }
-
 
     VCLXWindow* pvclwindow = (VCLXWindow*)pAccessible;
     Window* window = pvclwindow->GetWindow();
diff --git a/winaccessibility/source/service/msaaservice_impl.cxx b/winaccessibility/source/service/msaaservice_impl.cxx
index ce720c3..82a67b3 100755
--- a/winaccessibility/source/service/msaaservice_impl.cxx
+++ b/winaccessibility/source/service/msaaservice_impl.cxx
@@ -17,7 +17,7 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/implbase4.hxx>
 #include <cppuhelper/factory.hxx>
 #include <cppuhelper/implementationentry.hxx>
 
@@ -25,9 +25,13 @@
 #include <com/sun/star/lang/XInitialization.hpp>
 #include <com/sun/star/lang/IllegalArgumentException.hpp>
 #include <com/sun/star/accessibility/XMSAAService.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
 
 #include <com/sun/star/awt/XExtendedToolkit.hpp>
 #include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+
+#include <windows.h>
 
 using namespace ::rtl; // for OUString
 using namespace ::com::sun::star; // for odk interfaces
@@ -36,96 +40,53 @@ using namespace ::com::sun::star::accessibility;
 
 using namespace ::com::sun::star::awt;
 
-typedef sal_Int32 HWND;
-
 #include "AccTopWindowListener.hxx"
 #include "g_msacc.hxx"
 
-extern void FreeTopWindowListener();
-extern long GetMSComPtr(long hWnd, long lParam, long wParam);
-extern void handleWindowOpened_impl( long pAcc);
-
-
 namespace my_sc_impl
 {
 
-  //extern Sequence< OUString > SAL_CALL  getSupportedServiceNames_MSAAServiceImpl();
-  //static OUString SAL_CALL getImplementationName_MSAAServiceImpl();
-  //static Reference< XInterface > SAL_CALL create_MSAAServiceImpl(
-  //      Reference< XComponentContext > const & xContext )
-  //  SAL_THROW( () );
-/**
-   * Method that returns the service name.
-   * @param
-   * @return Name sequence.
-   */
 static Sequence< OUString > getSupportedServiceNames_MSAAServiceImpl()
 {
-    static Sequence < OUString > *pNames = 0;
-    if( ! pNames )
-    {
-        //      MutexGuard guard( Mutex::getGlobalMutex() );
-        if( !pNames )
-        {
-            static Sequence< OUString > seqNames(1);
-            seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.MSAAService"));
-            pNames = &seqNames;
-        }
-    }
-    return *pNames;
+    Sequence< OUString > seqNames(1);
+    seqNames.getArray()[0] = "com.sun.star.accessibility.MSAAService";
+    return seqNames;
 }
 
-/**
-   * Method that returns the service name.
-   * @param
-   * @return Name sequence.
-   */
 static OUString getImplementationName_MSAAServiceImpl()
 {
-    static OUString *pImplName = 0;
-    if( ! pImplName )
-    {
-        //      MutexGuard guard( Mutex::getGlobalMutex() );
-        if( ! pImplName )
-        {
-            static OUString implName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.my_sc_implementation.MSAAService") );
-            pImplName = &implName;
-        }
-    }
-    return *pImplName;
+    return OUString( "com.sun.star.accessibility.my_sc_implementation.MSAAService" );
 }
 
-class MSAAServiceImpl : public ::cppu::WeakImplHelper3<
-            XMSAAService, lang::XServiceInfo, lang::XInitialization >
+class MSAAServiceImpl : public ::cppu::WeakImplHelper4<
+            XMSAAService, lang::XServiceInfo,
+            lang::XInitialization, lang::XComponent >
 {
     OUString m_arg;
 public:
-    // focus on three given interfaces,
-    // no need to implement XInterface, XTypeProvider, XWeak
+    // focus on four interfaces,
+    // no need to implement XInterface, XTypeProvider, XWeak etc.
     MSAAServiceImpl ();
     virtual ~MSAAServiceImpl( void );
+
     // XInitialization will be called upon createInstanceWithArguments[AndContext]()
-    virtual void SAL_CALL initialize( Sequence< Any > const & args )
-    throw (Exception);
+    virtual void SAL_CALL initialize( Sequence< Any > const & args ) throw (Exception);
+
+    // XComponent - as used by VCL to lifecycle manage this bridge.
+    virtual void SAL_CALL dispose();
+    virtual void SAL_CALL addEventListener( const ::css::uno::Reference< ::css::lang::XEventListener >& )    { /* dummy */ }
+    virtual void SAL_CALL removeEventListener( const ::css::uno::Reference< ::css::lang::XEventListener >& ) { /* dummy */ }
+
     // XMSAAService
-    virtual sal_Int32 SAL_CALL getAccObjectPtr (long hWnd, long lParam, long wParam)
-    throw (RuntimeException);
-    virtual void SAL_CALL handleWindowOpened(sal_Int32)
-    throw (RuntimeException);
+    virtual sal_Int32 SAL_CALL getAccObjectPtr (long hWnd, long lParam, long wParam);
+    virtual void SAL_CALL handleWindowOpened(sal_Int32);
+
     // XServiceInfo
-    virtual OUString SAL_CALL getImplementationName()
-    throw (RuntimeException);
-    virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
-    throw (RuntimeException);
-    virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
-    throw (RuntimeException);
+    virtual OUString SAL_CALL getImplementationName();
+    virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName );
+    virtual Sequence< OUString > SAL_CALL getSupportedServiceNames();
 };
 
-/**
-   * Implemention of XInitialization.
-   * @param
-   * @return.
-   */
 void MSAAServiceImpl::initialize( Sequence< Any > const & args ) throw (Exception)
 {
     if (1 != args.getLength())
@@ -151,29 +112,24 @@ void MSAAServiceImpl::initialize( Sequence< Any > const & args ) throw (Exceptio
    */
 sal_Int32 MSAAServiceImpl::getAccObjectPtr ( long hWnd, long lParam, long wParam) throw (RuntimeException)
 {
-    return GetMSComPtr(hWnd, lParam, wParam);
+    return GetMSComPtr( hWnd, lParam, wParam );
 }
 
 /**
-   * Implemention of handleWindowOpened,the method will be invoked when a top window
-   * opened and AT starts up.
+   * Implemention of handleWindowOpened, the method will be invoked when a
+   * top window is opened and AT starts up.
    * @param
    * @return
    */
-void MSAAServiceImpl::handleWindowOpened( sal_Int32 pAcc)
+void MSAAServiceImpl::handleWindowOpened( sal_Int32 nAcc)
 {
-    handleWindowOpened_impl(pAcc);
+    SAL_INFO( "iacc2", "Window opened " << nAcc );
+    handleWindowOpened_impl( nAcc );
 }
 
-/**
-   * Implemention of XServiceInfo.
-   * @param
-   * @return Implementataion name.
-   */
 OUString MSAAServiceImpl::getImplementationName() throw (RuntimeException)
 {
-    // unique implementation name
-    return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.my_sc_impl.MSAAService") );
+    return OUString( "com.sun.star.accessibility.my_sc_impl.MSAAService" );
 }
 
 /**
@@ -184,7 +140,7 @@ OUString MSAAServiceImpl::getImplementationName() throw (RuntimeException)
 sal_Bool MSAAServiceImpl::supportsService( OUString const & serviceName ) throw (RuntimeException)
 {
     // this object only supports one service, so the test is simple
-    return serviceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.accessibility.MSAAService") );
+    return serviceName == "com.sun.star.accessibility.MSAAService";
 }
 
 /**
@@ -197,47 +153,159 @@ Sequence< OUString > MSAAServiceImpl::getSupportedServiceNames() throw (RuntimeE
     return getSupportedServiceNames_MSAAServiceImpl();
 }
 
+static void AccessBridgeHandleExistingWindow(const Reference< XMSAAService > &xAccMgr,
+                                             Window *pWindow, bool bShow)
+{
+    if ( pWindow )
+    {
+        css::uno::Reference< css::accessibility::XAccessible > xAccessible;
+
+        SAL_INFO( "iacc2", "Decide whether to register existing window with IAccessible2" );
+
+        // Test for combo box - drop down floating windows first
+        Window * pParentWindow = pWindow->GetParent();
+
+        if ( pParentWindow )
+        {
+            try
+            {
+                // The parent window of a combo box floating window should have the role COMBO_BOX
+                css::uno::Reference< css::accessibility::XAccessible > xParentAccessible(pParentWindow->GetAccessible());
+                if ( xParentAccessible.is() )
+                {
+                    css::uno::Reference< css::accessibility::XAccessibleContext > xParentAC( xParentAccessible->getAccessibleContext() );
+                    if ( xParentAC.is() && (css::accessibility::AccessibleRole::COMBO_BOX == xParentAC->getAccessibleRole()) )
+                    {
+                        // O.k. - this is a combo box floating window corresponding to the child of role LIST of the parent.
+                        // Let's not rely on a specific child order, just search for the child with the role LIST
+                        sal_Int32 nCount = xParentAC->getAccessibleChildCount();
+                        for ( sal_Int32 n = 0; (n < nCount) && !xAccessible.is(); n++)
+                        {
+                            css::uno::Reference< css::accessibility::XAccessible > xChild = xParentAC->getAccessibleChild(n);
+                            if ( xChild.is() )
+                            {
+                                css::uno::Reference< css::accessibility::XAccessibleContext > xChildAC = xChild->getAccessibleContext();
+                                if ( xChildAC.is() && (css::accessibility::AccessibleRole::LIST == xChildAC->getAccessibleRole()) )
+                                {
+                                    xAccessible = xChild;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            catch (::com::sun::star::uno::RuntimeException e)
+            {
+                // Ignore show events that throw DisposedExceptions in getAccessibleContext(),
+                // but keep revoking these windows in hide(s).
+                if (bShow)
+                    return;
+            }
+        }
+
+        // We have to rely on the fact that Window::GetAccessible()->getAccessibleContext() returns a valid XAccessibleContext
+        // also for other menus than menubar or toplevel popup window. Otherwise we had to traverse the hierarchy to find the
+        // context object to this menu floater. This makes the call to Window->IsMenuFloatingWindow() obsolete.
+        if ( ! xAccessible.is() )
+            xAccessible = pWindow->GetAccessible();
+
+        assert( xAccMgr.is() );
+        if ( xAccessible.is() )
+        {
+            xAccMgr->handleWindowOpened( (long)xAccessible.get() );
+            SAL_INFO( "iacc2", "Decide whether to register existing window with IAccessible2" );
+        }
+    }
+}
+
+/*
+ * Setup and notify the OS of Accessible peers for all existing windows.
+ */
+static void AccessBridgeUpdateOldTopWindows( const Reference< XMSAAService > &xAccMgr )
+{
+    sal_uInt16 nTopWindowCount = (sal_uInt16)Application::GetTopWindowCount();
+
+    for ( sal_uInt16 i = 0; i < nTopWindowCount; i++ )
+    {
+        Window* pTopWindow = Application::GetTopWindow( i );
+        css::uno::Reference< css::accessibility::XAccessible > xAccessible = pTopWindow->GetAccessible();
+        if ( xAccessible.is() )
+        {
+            css::uno::Reference< css::accessibility::XAccessibleContext > xAC( xAccessible->getAccessibleContext() );
+            if ( xAC.is())
+            {
+                short role = xAC->getAccessibleRole();
+                if ( !xAC->getAccessibleName().isEmpty() )
+                    AccessBridgeHandleExistingWindow( xAccMgr, pTopWindow, true );
+            }
+        }
+    }
+}
+
+static bool HasAtHook()
+{
+    sal_Int32 bIsRuning=0;
+    // BOOL WINAPI SystemParametersInfo(
+    //    __in     UINT uiAction,
+    //    __in     UINT uiParam,
+    //    __inout  PVOID pvParam,
+    //    __in     UINT fWinIni
+    //  );
+    // pvParam must be BOOL (defined in MFC as int)
+    // End
+    return SystemParametersInfo( SPI_GETSCREENREADER, 0,
+                                 &bIsRuning, 0) && bIsRuning;
+}
+
 /**
-   * Static method that can create an entity of our MSAA Service
-   * @param xContext No use here.
-   * @return The object interface.
-   */
+ * Static method that can create an entity of our MSAA Service
+ * @param xContext No use here.
+ * @return The object interface.
+ */
 Reference< XInterface > SAL_CALL create_MSAAServiceImpl( Reference< XComponentContext > const & /*xContext*/ ) SAL_THROW( () )
 {
-    MSAAServiceImpl* xxx = new MSAAServiceImpl();
-    //return static_cast< lang::XTypeProvider * >(  xxx );
-    Reference< XMSAAService > p( xxx );
-    return p;
+    bool bRunWithoutAt = getenv("SAL_FORCE_IACCESSIBLE2");
+
+    if ( !HasAtHook() )
+    {
+        if ( !bRunWithoutAt )
+        {
+            SAL_INFO("iacc2", "Apparently no running AT -> not enabling IAccessible2 integration");
+            return Reference< XMSAAService >();
+        }
+    }
+
+    Reference< XMSAAService > xAccMgr( new MSAAServiceImpl() );
+
+    AccessBridgeUpdateOldTopWindows( xAccMgr );
+
+    SAL_INFO("iacc2", "Created new IAccessible2 service impl.");
+
+    return xAccMgr;
 }
 
-/**
-   * Constructor.
-   * @param
-   * @return
-   */
 MSAAServiceImpl::MSAAServiceImpl()
 {
     Reference< XExtendedToolkit > xToolkit =
         Reference< XExtendedToolkit >(Application::GetVCLToolkit(), UNO_QUERY);
 
-    if(xToolkit.is())
+    if( xToolkit.is() )
     {
-        AccTopWindowListener *accListener;
-        accListener = new AccTopWindowListener();
-        g_pTop = accListener;
-        Reference< XTopWindowListener> x(accListener);
-        xToolkit->addTopWindowListener(x);
+        g_pTop = new AccTopWindowListener();
+        Reference< XTopWindowListener> xRef( g_pTop );
+        xToolkit->addTopWindowListener( xRef );
+        SAL_INFO( "iacc2", "successfully connected to the toolkit event hose" );
     }
+    else
+        SAL_WARN( "iacc2", "No VCL toolkit interface to listen to for events");
 }
 
-/**
-   * Static method that can create an entity of our MSAA Service
-   * @param Destructor
-   * @return
-   */
 MSAAServiceImpl::~MSAAServiceImpl()
 {
+}
 
+void MSAAServiceImpl::dispose()
+{
     // As all folders and streams contain references to their parents,
     // we must remove these references so that they will be deleted when
     // the hash_map of the root folder is cleared, releasing all subfolders
@@ -245,8 +313,6 @@ MSAAServiceImpl::~MSAAServiceImpl()
     // released when this destructor completes, the folder tree should be
     // deleted fully (and automagically).
     FreeTopWindowListener();
-
-
 }
 
 }
@@ -258,7 +324,8 @@ static struct ::cppu::ImplementationEntry s_component_entries [] =
     {
         {
             create_MSAAServiceImpl, getImplementationName_MSAAServiceImpl,
-            getSupportedServiceNames_MSAAServiceImpl, ::cppu::createSingleComponentFactory,
+            getSupportedServiceNames_MSAAServiceImpl,
+            ::cppu::createSingleComponentFactory,
             0, 0
         },
         { 0, 0, 0, 0, 0, 0 }
@@ -267,12 +334,12 @@ static struct ::cppu::ImplementationEntry s_component_entries [] =
 
 extern "C"
 {
-    SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
+    SAL_DLLPUBLIC_EXPORT void SAL_CALL iacc2_component_getImplementationEnvironment(
         sal_Char const ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
     {
         *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
     }
-    SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
+    SAL_DLLPUBLIC_EXPORT void * SAL_CALL iacc2_component_getFactory(
         sal_Char const * implName, lang::XMultiServiceFactory * xMgr,
         registry::XRegistryKey * xRegistry )
     {
diff --git a/winaccessibility/source/service/winaccessibility.component b/winaccessibility/source/service/winaccessibility.component
index 3a73858..71ea6de 100644
--- a/winaccessibility/source/service/winaccessibility.component
+++ b/winaccessibility/source/service/winaccessibility.component
@@ -16,7 +16,7 @@
  *   except in compliance with the License. You may obtain a copy of
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  -->
-<component loader="com.sun.star.loader.SharedLibrary"
+<component loader="com.sun.star.loader.SharedLibrary" prefix="iacc2"
     xmlns="http://openoffice.org/2010/uno-components">
   <implementation name="com.sun.star.accessibility.my_sc_implementation.MSAAService">
     <service name="com.sun.star.accessibility.MSAAService"/>


More information about the Libreoffice-commits mailing list