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