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