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