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