xref: /AOO41X/main/accessibility/bridge/org/openoffice/accessibility/AccessBridge.java (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir package org.openoffice.accessibility;
28*cdf0e10cSrcweir 
29*cdf0e10cSrcweir import com.sun.star.accessibility.AccessibleRole;
30*cdf0e10cSrcweir import com.sun.star.accessibility.XAccessible;
31*cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleContext;
32*cdf0e10cSrcweir import com.sun.star.awt.XExtendedToolkit;
33*cdf0e10cSrcweir import com.sun.star.awt.XTopWindow;
34*cdf0e10cSrcweir import com.sun.star.awt.XTopWindowListener;
35*cdf0e10cSrcweir import com.sun.star.awt.XWindow;
36*cdf0e10cSrcweir import com.sun.star.comp.loader.FactoryHelper;
37*cdf0e10cSrcweir import com.sun.star.lang.XComponent;
38*cdf0e10cSrcweir import com.sun.star.lang.XInitialization;
39*cdf0e10cSrcweir import com.sun.star.lang.XMultiServiceFactory;
40*cdf0e10cSrcweir import com.sun.star.lang.XSingleServiceFactory;
41*cdf0e10cSrcweir import com.sun.star.registry.*;
42*cdf0e10cSrcweir import com.sun.star.uno.*;
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir import org.openoffice.java.accessibility.*;
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir import java.lang.reflect.InvocationTargetException;
47*cdf0e10cSrcweir import java.lang.reflect.Method;
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir import javax.accessibility.Accessible;
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir public class AccessBridge {
53*cdf0e10cSrcweir     //
54*cdf0e10cSrcweir     protected static java.util.Hashtable topWindowMap = new java.util.Hashtable();
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir     private static java.awt.Window getTopWindowImpl(XAccessible xAccessible) {
57*cdf0e10cSrcweir         // Because it can not be garantied that
58*cdf0e10cSrcweir         // WindowsAccessBridgeAdapter.registerTopWindow() is called
59*cdf0e10cSrcweir         // before windowOpened(), we have to make this operation
60*cdf0e10cSrcweir         // atomic.
61*cdf0e10cSrcweir         synchronized (topWindowMap) {
62*cdf0e10cSrcweir             String oid = UnoRuntime.generateOid(xAccessible);
63*cdf0e10cSrcweir             java.awt.Window w = (java.awt.Window) topWindowMap.get(oid);
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir             if (w == null) {
66*cdf0e10cSrcweir                 w = AccessibleObjectFactory.getTopWindow(xAccessible);
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir                 if (w != null) {
69*cdf0e10cSrcweir                     topWindowMap.put(oid, w);
70*cdf0e10cSrcweir                 }
71*cdf0e10cSrcweir             }
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir             return w;
74*cdf0e10cSrcweir         }
75*cdf0e10cSrcweir     }
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir     protected static java.awt.Window getTopWindow(XAccessible xAccessible) {
78*cdf0e10cSrcweir         if (xAccessible != null) {
79*cdf0e10cSrcweir             XAccessibleContext xAccessibleContext = xAccessible.getAccessibleContext();
80*cdf0e10cSrcweir             if (xAccessibleContext != null) {
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir                 // Toolkit reports the VCL peer windows as toplevels. These have an
83*cdf0e10cSrcweir                 // accessible parent which represents the native frame window
84*cdf0e10cSrcweir                 switch(xAccessibleContext.getAccessibleRole()) {
85*cdf0e10cSrcweir                     case AccessibleRole.ROOT_PANE:
86*cdf0e10cSrcweir                     case AccessibleRole.POPUP_MENU:
87*cdf0e10cSrcweir                         return getTopWindow(xAccessibleContext.getAccessibleParent());
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir                     case AccessibleRole.WINDOW:
90*cdf0e10cSrcweir                     case AccessibleRole.FRAME:
91*cdf0e10cSrcweir                     case AccessibleRole.DIALOG:
92*cdf0e10cSrcweir                     case AccessibleRole.ALERT:
93*cdf0e10cSrcweir                         return getTopWindowImpl(xAccessible);
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir                     default:
96*cdf0e10cSrcweir                         break;
97*cdf0e10cSrcweir                 }
98*cdf0e10cSrcweir             }
99*cdf0e10cSrcweir         }
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir         return null;
102*cdf0e10cSrcweir     }
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir     protected static java.awt.Window removeTopWindow(XAccessible xAccessible) {
105*cdf0e10cSrcweir         if (xAccessible != null) {
106*cdf0e10cSrcweir             XAccessibleContext xAccessibleContext = xAccessible.getAccessibleContext();
107*cdf0e10cSrcweir             if (xAccessibleContext != null) {
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir                 // Toolkit reports the VCL peer windows as toplevels. These have an
110*cdf0e10cSrcweir                 // accessible parent which represents the native frame window
111*cdf0e10cSrcweir                 switch(xAccessibleContext.getAccessibleRole()) {
112*cdf0e10cSrcweir                     case AccessibleRole.ROOT_PANE:
113*cdf0e10cSrcweir                     case AccessibleRole.POPUP_MENU:
114*cdf0e10cSrcweir                         return removeTopWindow(xAccessibleContext.getAccessibleParent());
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir                     case AccessibleRole.WINDOW:
117*cdf0e10cSrcweir                     case AccessibleRole.FRAME:
118*cdf0e10cSrcweir                     case AccessibleRole.DIALOG:
119*cdf0e10cSrcweir                         return (java.awt.Window) topWindowMap.remove(UnoRuntime.generateOid(xAccessible));
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir                     default:
122*cdf0e10cSrcweir                         break;
123*cdf0e10cSrcweir                 }
124*cdf0e10cSrcweir             }
125*cdf0e10cSrcweir         }
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir         return null;
128*cdf0e10cSrcweir     }
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir     public static XSingleServiceFactory __getServiceFactory(String implName,
131*cdf0e10cSrcweir         XMultiServiceFactory multiFactory, XRegistryKey regKey) {
132*cdf0e10cSrcweir         XSingleServiceFactory xSingleServiceFactory = null;
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir         if (implName.equals(AccessBridge.class.getName())) {
135*cdf0e10cSrcweir             // Initialize toolkit to register at Java <-> Windows access bridge
136*cdf0e10cSrcweir             java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir             xSingleServiceFactory = FactoryHelper.getServiceFactory(_AccessBridge.class,
139*cdf0e10cSrcweir                     _AccessBridge._serviceName, multiFactory, regKey);
140*cdf0e10cSrcweir         }
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir         return xSingleServiceFactory;
143*cdf0e10cSrcweir     }
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir     static public class _AccessBridge implements XTopWindowListener,
146*cdf0e10cSrcweir         XInitialization, XComponent {
147*cdf0e10cSrcweir         static final String _serviceName = "com.sun.star.accessibility.AccessBridge";
148*cdf0e10cSrcweir         XComponentContext xComponentContext;
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir         public _AccessBridge(XComponentContext xComponentContext) {
151*cdf0e10cSrcweir             this.xComponentContext = xComponentContext;
152*cdf0e10cSrcweir         }
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir         /*
155*cdf0e10cSrcweir         * XInitialization
156*cdf0e10cSrcweir         */
157*cdf0e10cSrcweir         public void initialize(java.lang.Object[] arguments) {
158*cdf0e10cSrcweir             try {
159*cdf0e10cSrcweir                 // FIXME: Currently there is no way to determine if key event forwarding is needed or not,
160*cdf0e10cSrcweir                 // so we have to do it always ..
161*cdf0e10cSrcweir                 XExtendedToolkit unoToolkit = (XExtendedToolkit) AnyConverter.toObject(new Type(
162*cdf0e10cSrcweir                             XExtendedToolkit.class), arguments[0]);
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir                 if (unoToolkit != null) {
165*cdf0e10cSrcweir                     // FIXME this should be done in VCL
166*cdf0e10cSrcweir                     unoToolkit.addTopWindowListener(this);
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir                     String os = (String) System.getProperty("os.name");
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir                     // Try to initialize the WindowsAccessBridgeAdapter
171*cdf0e10cSrcweir                     if (os.startsWith("Windows")) {
172*cdf0e10cSrcweir                         WindowsAccessBridgeAdapter.attach(xComponentContext);
173*cdf0e10cSrcweir                     } else {
174*cdf0e10cSrcweir                         unoToolkit.addKeyHandler(new KeyHandler());
175*cdf0e10cSrcweir                     }
176*cdf0e10cSrcweir                 } else if (Build.DEBUG) {
177*cdf0e10cSrcweir                     System.err.println(
178*cdf0e10cSrcweir                         "argument 0 is not of type XExtendedToolkit.");
179*cdf0e10cSrcweir                 }
180*cdf0e10cSrcweir             } catch (com.sun.star.lang.IllegalArgumentException e) {
181*cdf0e10cSrcweir                 // FIXME: output
182*cdf0e10cSrcweir             }
183*cdf0e10cSrcweir         }
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir         /*
186*cdf0e10cSrcweir         * XTopWindowListener
187*cdf0e10cSrcweir         */
188*cdf0e10cSrcweir         public void windowOpened(com.sun.star.lang.EventObject event) {
189*cdf0e10cSrcweir             XAccessible xAccessible = (XAccessible) UnoRuntime.queryInterface(XAccessible.class,
190*cdf0e10cSrcweir                     event.Source);
191*cdf0e10cSrcweir             java.awt.Window w = getTopWindow(xAccessible);
192*cdf0e10cSrcweir         }
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir         public void windowActivated(com.sun.star.lang.EventObject event) {
195*cdf0e10cSrcweir         }
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir         public void windowDeactivated(com.sun.star.lang.EventObject event) {
198*cdf0e10cSrcweir         }
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir         public void windowMinimized(com.sun.star.lang.EventObject event) {
201*cdf0e10cSrcweir         }
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir         public void windowNormalized(com.sun.star.lang.EventObject event) {
204*cdf0e10cSrcweir         }
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir         public void windowClosing(com.sun.star.lang.EventObject event) {
207*cdf0e10cSrcweir         }
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir         public void windowClosed(com.sun.star.lang.EventObject event) {
210*cdf0e10cSrcweir             XAccessible xAccessible = (XAccessible) UnoRuntime.queryInterface(XAccessible.class,
211*cdf0e10cSrcweir                     event.Source);
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir             java.awt.Window w = removeTopWindow(xAccessible);
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir             if (w != null) {
216*cdf0e10cSrcweir                 w.dispose();
217*cdf0e10cSrcweir             }
218*cdf0e10cSrcweir         }
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir         public void disposing(com.sun.star.lang.EventObject event) {
221*cdf0e10cSrcweir         }
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir         /*
224*cdf0e10cSrcweir         * XComponent
225*cdf0e10cSrcweir         */
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir         public void addEventListener(com.sun.star.lang.XEventListener listener) {
228*cdf0e10cSrcweir         }
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir         public void removeEventListener(com.sun.star.lang.XEventListener listener) {
231*cdf0e10cSrcweir         }
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir         public void dispose() {
234*cdf0e10cSrcweir             try {
235*cdf0e10cSrcweir                 java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(
236*cdf0e10cSrcweir                     new Runnable() {
237*cdf0e10cSrcweir                         public void run() {
238*cdf0e10cSrcweir                         }
239*cdf0e10cSrcweir                     } );
240*cdf0e10cSrcweir             } catch (java.lang.InterruptedException e) {
241*cdf0e10cSrcweir             } catch (java.lang.reflect.InvocationTargetException e) {
242*cdf0e10cSrcweir             }
243*cdf0e10cSrcweir         }
244*cdf0e10cSrcweir     }
245*cdf0e10cSrcweir }
246