diff options
Diffstat (limited to 'accessibility/bridge/org/openoffice/accessibility')
7 files changed, 1345 insertions, 0 deletions
diff --git a/accessibility/bridge/org/openoffice/accessibility/AccessBridge.java b/accessibility/bridge/org/openoffice/accessibility/AccessBridge.java new file mode 100755 index 000000000000..ec479fb3949d --- /dev/null +++ b/accessibility/bridge/org/openoffice/accessibility/AccessBridge.java @@ -0,0 +1,245 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package org.openoffice.accessibility; + +import com.sun.star.accessibility.AccessibleRole; +import com.sun.star.accessibility.XAccessible; +import com.sun.star.accessibility.XAccessibleContext; +import com.sun.star.awt.XExtendedToolkit; +import com.sun.star.awt.XTopWindow; +import com.sun.star.awt.XTopWindowListener; +import com.sun.star.awt.XWindow; +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.lang.XComponent; +import com.sun.star.lang.XInitialization; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.registry.*; +import com.sun.star.uno.*; + +import org.openoffice.java.accessibility.*; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import javax.accessibility.Accessible; + + +public class AccessBridge { + // + protected static java.util.Hashtable topWindowMap = new java.util.Hashtable(); + + private static java.awt.Window getTopWindowImpl(XAccessible xAccessible) { + // Because it can not be garantied that + // WindowsAccessBridgeAdapter.registerTopWindow() is called + // before windowOpened(), we have to make this operation + // atomic. + synchronized (topWindowMap) { + String oid = UnoRuntime.generateOid(xAccessible); + java.awt.Window w = (java.awt.Window) topWindowMap.get(oid); + + if (w == null) { + w = AccessibleObjectFactory.getTopWindow(xAccessible); + + if (w != null) { + topWindowMap.put(oid, w); + } + } + + return w; + } + } + + protected static java.awt.Window getTopWindow(XAccessible xAccessible) { + if (xAccessible != null) { + XAccessibleContext xAccessibleContext = xAccessible.getAccessibleContext(); + if (xAccessibleContext != null) { + + // Toolkit reports the VCL peer windows as toplevels. These have an + // accessible parent which represents the native frame window + switch(xAccessibleContext.getAccessibleRole()) { + case AccessibleRole.ROOT_PANE: + case AccessibleRole.POPUP_MENU: + return getTopWindow(xAccessibleContext.getAccessibleParent()); + + case AccessibleRole.WINDOW: + case AccessibleRole.FRAME: + case AccessibleRole.DIALOG: + case AccessibleRole.ALERT: + return getTopWindowImpl(xAccessible); + + default: + break; + } + } + } + + return null; + } + + protected static java.awt.Window removeTopWindow(XAccessible xAccessible) { + if (xAccessible != null) { + XAccessibleContext xAccessibleContext = xAccessible.getAccessibleContext(); + if (xAccessibleContext != null) { + + // Toolkit reports the VCL peer windows as toplevels. These have an + // accessible parent which represents the native frame window + switch(xAccessibleContext.getAccessibleRole()) { + case AccessibleRole.ROOT_PANE: + case AccessibleRole.POPUP_MENU: + return removeTopWindow(xAccessibleContext.getAccessibleParent()); + + case AccessibleRole.WINDOW: + case AccessibleRole.FRAME: + case AccessibleRole.DIALOG: + return (java.awt.Window) topWindowMap.remove(UnoRuntime.generateOid(xAccessible)); + + default: + break; + } + } + } + + return null; + } + + public static XSingleServiceFactory __getServiceFactory(String implName, + XMultiServiceFactory multiFactory, XRegistryKey regKey) { + XSingleServiceFactory xSingleServiceFactory = null; + + if (implName.equals(AccessBridge.class.getName())) { + // Initialize toolkit to register at Java <-> Windows access bridge + java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit(); + + xSingleServiceFactory = FactoryHelper.getServiceFactory(_AccessBridge.class, + _AccessBridge._serviceName, multiFactory, regKey); + } + + return xSingleServiceFactory; + } + + static public class _AccessBridge implements XTopWindowListener, + XInitialization, XComponent { + static final String _serviceName = "com.sun.star.accessibility.AccessBridge"; + XComponentContext xComponentContext; + + public _AccessBridge(XComponentContext xComponentContext) { + this.xComponentContext = xComponentContext; + } + + /* + * XInitialization + */ + public void initialize(java.lang.Object[] arguments) { + try { + // FIXME: Currently there is no way to determine if key event forwarding is needed or not, + // so we have to do it always .. + XExtendedToolkit unoToolkit = (XExtendedToolkit) AnyConverter.toObject(new Type( + XExtendedToolkit.class), arguments[0]); + + if (unoToolkit != null) { + // FIXME this should be done in VCL + unoToolkit.addTopWindowListener(this); + + String os = (String) System.getProperty("os.name"); + + // Try to initialize the WindowsAccessBridgeAdapter + if (os.startsWith("Windows")) { + WindowsAccessBridgeAdapter.attach(xComponentContext); + } else { + unoToolkit.addKeyHandler(new KeyHandler()); + } + } else if (Build.DEBUG) { + System.err.println( + "argument 0 is not of type XExtendedToolkit."); + } + } catch (com.sun.star.lang.IllegalArgumentException e) { + // FIXME: output + } + } + + /* + * XTopWindowListener + */ + public void windowOpened(com.sun.star.lang.EventObject event) { + XAccessible xAccessible = (XAccessible) UnoRuntime.queryInterface(XAccessible.class, + event.Source); + java.awt.Window w = getTopWindow(xAccessible); + } + + public void windowActivated(com.sun.star.lang.EventObject event) { + } + + public void windowDeactivated(com.sun.star.lang.EventObject event) { + } + + public void windowMinimized(com.sun.star.lang.EventObject event) { + } + + public void windowNormalized(com.sun.star.lang.EventObject event) { + } + + public void windowClosing(com.sun.star.lang.EventObject event) { + } + + public void windowClosed(com.sun.star.lang.EventObject event) { + XAccessible xAccessible = (XAccessible) UnoRuntime.queryInterface(XAccessible.class, + event.Source); + + java.awt.Window w = removeTopWindow(xAccessible); + + if (w != null) { + w.dispose(); + } + } + + public void disposing(com.sun.star.lang.EventObject event) { + } + + /* + * XComponent + */ + + public void addEventListener(com.sun.star.lang.XEventListener listener) { + } + + public void removeEventListener(com.sun.star.lang.XEventListener listener) { + } + + public void dispose() { + try { + java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait( + new Runnable() { + public void run() { + } + } ); + } catch (java.lang.InterruptedException e) { + } catch (java.lang.reflect.InvocationTargetException e) { + } + } + } +} diff --git a/accessibility/bridge/org/openoffice/accessibility/KeyHandler.java b/accessibility/bridge/org/openoffice/accessibility/KeyHandler.java new file mode 100755 index 000000000000..1e9f2f6520ae --- /dev/null +++ b/accessibility/bridge/org/openoffice/accessibility/KeyHandler.java @@ -0,0 +1,138 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.accessibility; + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.awt.XKeyHandler; +import org.openoffice.java.accessibility.AccessibleKeyBinding; +import org.openoffice.java.accessibility.Build; + +import java.awt.*; +import java.awt.event.KeyEvent; +import javax.accessibility.*; + +public class KeyHandler extends Component implements XKeyHandler, java.awt.KeyEventDispatcher { + EventQueue eventQueue; + + public class VCLKeyEvent extends KeyEvent implements Runnable { + boolean consumed = true; + + public VCLKeyEvent(Component c, int id, int modifiers, int keyCode, char keyChar) { + super(c, id, System.currentTimeMillis(), modifiers, keyCode, keyChar); + } + + public void run() { + // This is a no-op .. + } + + public void setConsumed(boolean b) { + consumed = b; + } + + public boolean isConsumed() { + return consumed; + } + } + + public KeyHandler() { + eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); + java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this); + } + + /** This method is called by the current KeyboardFocusManager requesting that this KeyEventDispatcher + * dispatch the specified event on its behalf + */ + public boolean dispatchKeyEvent(java.awt.event.KeyEvent e) { + if (e instanceof VCLKeyEvent) { + VCLKeyEvent event = (VCLKeyEvent) e; + event.setConsumed(false); + return true; + } + return false; + } + + /** Handler for KeyPressed events */ + public boolean keyPressed(com.sun.star.awt.KeyEvent event) { +// try { + VCLKeyEvent vke = new VCLKeyEvent(this, KeyEvent.KEY_PRESSED, + AccessibleKeyBinding.convertModifiers(event.Modifiers), + AccessibleKeyBinding.convertKeyCode(event.KeyCode), + event.KeyChar != 0 ? event.KeyChar : KeyEvent.CHAR_UNDEFINED); + + eventQueue.postEvent(vke); + + // VCL events for TABs have empty KeyChar + if (event.KeyCode == com.sun.star.awt.Key.TAB ) { + event.KeyChar = '\t'; + } + + // Synthesize KEY_TYPED event to emulate Java behavior + if (event.KeyChar != 0) { + eventQueue.postEvent(new VCLKeyEvent(this, + KeyEvent.KEY_TYPED, + AccessibleKeyBinding.convertModifiers(event.Modifiers), + KeyEvent.VK_UNDEFINED, + event.KeyChar)); + } + + // Wait until the key event is processed + return false; +// eventQueue.invokeAndWait(vke); +// return vke.isConsumed(); +// } catch(java.lang.InterruptedException e) { +// return false; +// } catch(java.lang.reflect.InvocationTargetException e) { +// return false; +// } + } + + /** Handler for KeyReleased events */ + public boolean keyReleased(com.sun.star.awt.KeyEvent event) { +// try { + VCLKeyEvent vke = new VCLKeyEvent(this, KeyEvent.KEY_RELEASED, + AccessibleKeyBinding.convertModifiers(event.Modifiers), + AccessibleKeyBinding.convertKeyCode(event.KeyCode), + event.KeyChar != 0 ? event.KeyChar : KeyEvent.CHAR_UNDEFINED); + eventQueue.postEvent(vke); + + // Wait until the key event is processed + return false; +// eventQueue.invokeAndWait(vke); +// return vke.isConsumed(); +// } catch(java.lang.InterruptedException e) { +// return false; +// } catch(java.lang.reflect.InvocationTargetException e) { +// return false; +// } + } + + public void disposing(com.sun.star.lang.EventObject event) { + java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this); + } +}; diff --git a/accessibility/bridge/org/openoffice/accessibility/PopupWindow.java b/accessibility/bridge/org/openoffice/accessibility/PopupWindow.java new file mode 100644 index 000000000000..a63b0589b4fa --- /dev/null +++ b/accessibility/bridge/org/openoffice/accessibility/PopupWindow.java @@ -0,0 +1,210 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package org.openoffice.accessibility; + +import org.openoffice.java.accessibility.*; + + +/** + * + */ +public class PopupWindow extends java.awt.Window { + javax.accessibility.AccessibleContext accessibleContext = null; + ContainerProxy layeredPane = new ContainerProxy(javax.accessibility.AccessibleRole.LAYERED_PANE); + ContainerProxy rootPane = new ContainerProxy(javax.accessibility.AccessibleRole.ROOT_PANE); + ContainerProxy popupLayer = new ContainerProxy(javax.accessibility.AccessibleRole.PANEL); + boolean opened = false; + boolean visible = false; + + /** Creates a new instance of PopupWindow */ + public PopupWindow(java.awt.Window owner) { + super(owner); + super.add(rootPane); + rootPane.add(layeredPane); + + javax.accessibility.AccessibleContext ac = rootPane.getAccessibleContext(); + + if (ac != null) { + ac.setAccessibleParent(this); + } + } + + static PopupWindow create( + com.sun.star.accessibility.XAccessible xAccessible) { + java.awt.Window parent = java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager() + .getActiveWindow(); + + if (parent != null) { + PopupWindow w = new PopupWindow(parent); + w.setVisible(true); + AccessibleObjectFactory.invokeAndWait(); + AccessibleObjectFactory.addChild(w, xAccessible); + + return w; + } + + return null; + } + + public boolean isShowing() { + if (isVisible()) { + java.awt.Container parent = getParent(); + + return (parent == null) || parent.isShowing(); + } + + return false; + } + + public void addNotify() { + } + + public void removeNotify() { + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean b) { + if (visible != b) { + visible = b; + + if (b) { + // If it is the first show, fire WINDOW_OPENED event + if (!opened) { + AccessibleObjectFactory.postWindowOpened(this); + opened = true; + } + } + } + } + + public java.awt.Component add(java.awt.Component c) { + popupLayer.add(c); + layeredPane.add(popupLayer); + + if (c instanceof javax.accessibility.Accessible) { + javax.accessibility.AccessibleContext ac = layeredPane.getAccessibleContext(); + + if (ac != null) { + ac.firePropertyChange(ac.ACCESSIBLE_CHILD_PROPERTY, null, + popupLayer.getAccessibleContext()); + } + } + + return c; + } + + public void remove(java.awt.Component c) { + layeredPane.remove(popupLayer); + + if (c instanceof javax.accessibility.Accessible) { + javax.accessibility.AccessibleContext ac = layeredPane.getAccessibleContext(); + + if (ac != null) { + ac.firePropertyChange(ac.ACCESSIBLE_CHILD_PROPERTY, + popupLayer.getAccessibleContext(), null); + } + } + + popupLayer.remove(c); + } + + public void dispose() { + setVisible(false); + AccessibleObjectFactory.postWindowClosed(this); + } + + public javax.accessibility.AccessibleContext getAccessibleContext() { + if (accessibleContext == null) { + accessibleContext = new AccessiblePopupWindow(); + } + + return accessibleContext; + } + + protected class AccessiblePopupWindow + extends java.awt.Window.AccessibleAWTWindow { + AccessiblePopupWindow() { + } + } + + protected class ContainerProxy extends java.awt.Container + implements javax.accessibility.Accessible { + javax.accessibility.AccessibleContext accessibleContext = null; + javax.accessibility.AccessibleRole role; + + protected ContainerProxy(javax.accessibility.AccessibleRole role) { + this.role = role; + } + + public java.awt.Component add(java.awt.Component c) { + if (c instanceof javax.accessibility.Accessible) { + javax.accessibility.Accessible a = (javax.accessibility.Accessible) c; + javax.accessibility.AccessibleContext ac = a.getAccessibleContext(); + + if (ac != null) { + ac.setAccessibleParent(this); + } + } + + return super.add(c); + } + + public void remove(java.awt.Component c) { + if (c instanceof javax.accessibility.Accessible) { + javax.accessibility.Accessible a = (javax.accessibility.Accessible) c; + javax.accessibility.AccessibleContext ac = a.getAccessibleContext(); + + if (ac != null) { + ac.setAccessibleParent(null); + } + } + + super.remove(c); + } + + public javax.accessibility.AccessibleContext getAccessibleContext() { + if (accessibleContext == null) { + accessibleContext = new AccessibleContainerProxy(); + } + + return accessibleContext; + } + + private class AccessibleContainerProxy + extends java.awt.Container.AccessibleAWTContainer { + AccessibleContainerProxy() { + } + + public javax.accessibility.AccessibleRole getAccessibleRole() { + return ContainerProxy.this.role; + } + } + } +} diff --git a/accessibility/bridge/org/openoffice/accessibility/WindowsAccessBridgeAdapter.java b/accessibility/bridge/org/openoffice/accessibility/WindowsAccessBridgeAdapter.java new file mode 100644 index 000000000000..28e58940867d --- /dev/null +++ b/accessibility/bridge/org/openoffice/accessibility/WindowsAccessBridgeAdapter.java @@ -0,0 +1,654 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package org.openoffice.accessibility; + +import com.sun.star.accessibility.AccessibleRole; +import com.sun.star.accessibility.XAccessible; +import com.sun.star.accessibility.XAccessibleContext; +import com.sun.star.java.XJavaVM; +import com.sun.star.uno.*; + +import org.openoffice.java.accessibility.*; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import javax.accessibility.*; + + +public class WindowsAccessBridgeAdapter { + private static Method registerVirtualFrame; + private static Method revokeVirtualFrame; + private static java.util.Hashtable frameMap; + + protected static native byte[] getProcessID(); + + protected static native boolean createMapping(long jvmaccess); + + // On Windows all native frames must be registered to the access bridge. + // Therefor the bridge exports two methods that we try to find here. + protected static void attach(XComponentContext xComponentContext) { + try { + Class bridge = Class.forName( + "com.sun.java.accessibility.AccessBridge"); + Class[] parameterTypes = { + javax.accessibility.Accessible.class, Integer.class + }; + + if (bridge != null) { + registerVirtualFrame = bridge.getMethod("registerVirtualFrame", + parameterTypes); + revokeVirtualFrame = bridge.getMethod("revokeVirtualFrame", + parameterTypes); + + // load the native dll + System.loadLibrary("java_uno_accessbridge"); + + Object any = xComponentContext.getValueByName( + "/singletons/com.sun.star.java.theJavaVirtualMachine"); + + if (AnyConverter.isObject(any)) { + XJavaVM xJavaVM = (XJavaVM) UnoRuntime.queryInterface(XJavaVM.class, + AnyConverter.toObject(new Type(XJavaVM.class), any)); + + if (xJavaVM != null) { + any = xJavaVM.getJavaVM(getProcessID()); + + if (AnyConverter.isLong(any)) { + createMapping(AnyConverter.toLong(any)); + frameMap = new java.util.Hashtable(); + } + } + } + } + } catch (NoSuchMethodException e) { + System.err.println("ERROR: incompatible AccessBridge found: " + + e.getMessage()); + + // Forward this exception to UNO to indicate that the service will + // not work correctly. + throw new com.sun.star.uno.RuntimeException( + "incompatible AccessBridge class: " + e.getMessage()); + } catch (java.lang.SecurityException e) { + System.err.println("ERROR: no access to AccessBridge: " + + e.getMessage()); + + // Forward this exception to UNO to indicate that the service will not work correctly. + throw new com.sun.star.uno.RuntimeException( + "Security exception caught: " + e.getMessage()); + } catch (ClassNotFoundException e) { + // Forward this exception to UNO to indicate that the service will not work correctly. + throw new com.sun.star.uno.RuntimeException( + "ClassNotFound exception caught: " + e.getMessage()); + } catch (IllegalArgumentException e) { + System.err.println("IllegalArgumentException caught: " + + e.getMessage()); + + // Forward this exception to UNO to indicate that the service will not work correctly. + throw new com.sun.star.uno.RuntimeException( + "IllegalArgumentException caught: " + e.getMessage()); + } catch (com.sun.star.lang.IllegalArgumentException e) { + System.err.println("UNO IllegalArgumentException caught: " + + e.getMessage()); + + // Forward this exception to UNO to indicate that the service will not work correctly. + throw new com.sun.star.uno.RuntimeException( + "UNO IllegalArgumentException caught: " + e.getMessage()); + } + } + + protected static boolean isAttached() { + return frameMap != null; + } + + protected static Accessible getAccessibleWrapper(XAccessible xAccessible) { + Accessible a = null; + + try { + XAccessibleContext xAccessibleContext = xAccessible.getAccessibleContext(); + + if (xAccessibleContext != null) { + switch (xAccessibleContext.getAccessibleRole()) { + case AccessibleRole.LIST: + a = (Accessible) AccessibleObjectFactory.getAccessibleComponent(xAccessible); + if (a != null) { + a = new ListProxy(a.getAccessibleContext()); + } + break; + + case AccessibleRole.MENU: + + Accessible tmp = (Accessible) AccessibleObjectFactory.getAccessibleComponent(xAccessible); + if (tmp != null) { + AccessibleContext ac = tmp.getAccessibleContext(); + + if (ac != null) { + a = new PopupMenuProxy(ac); + } + } + + break; + + case AccessibleRole.TOOL_TIP: + a = PopupWindow.create(xAccessible); + break; + + default: + a = (Accessible) AccessBridge.getTopWindow(xAccessible); + break; + } + } + } catch (com.sun.star.uno.RuntimeException e) { + } + + return a; + } + + /** Registers a native frame at the Java AccessBridge for Windows */ + public static void registerTopWindow(int handle, XAccessible xAccessible) { + Integer hwnd = new Integer(handle); + + if (!frameMap.contains(hwnd)) { + if (Build.DEBUG) { + System.err.println("Native frame " + hwnd + " of role " + + AccessibleRoleAdapter.getAccessibleRole(xAccessible) + + " has been opened"); + } + + Accessible a = getAccessibleWrapper(xAccessible); + + if (a != null) { + Object[] args = { a, hwnd }; + + frameMap.put(hwnd, a); + + if (Build.DEBUG) { + System.err.println("registering native frame " + hwnd); + } + + try { + registerVirtualFrame.invoke(null, args); + } catch (IllegalAccessException e) { + System.err.println("IllegalAccessException caught: " + + e.getMessage()); + } catch (IllegalArgumentException e) { + System.err.println("IllegalArgumentException caught: " + + e.getMessage()); + } catch (InvocationTargetException e) { + System.err.println("InvokationTargetException caught: " + + e.getMessage()); + } + } + } + } + + /** Revokes a native frame at the Java AccessBridge for Windows */ + public static void revokeTopWindow(int handle, XAccessible xAccessible) { + Integer hwnd = new Integer(handle); + + Accessible a = (Accessible) frameMap.remove(hwnd); + + if (a != null) { + Object[] args = { a, hwnd }; + + if (Build.DEBUG) { + System.err.println("revoking native frame " + hwnd); + } + + try { + revokeVirtualFrame.invoke(null, args); + } catch (IllegalAccessException e) { + System.err.println("IllegalAccessException caught: " + + e.getMessage()); + } catch (IllegalArgumentException e) { + System.err.println("IllegalArgumentException caught: " + + e.getMessage()); + } catch (InvocationTargetException e) { + System.err.println("InvokationTargetException caught: " + + e.getMessage()); + } + } + + if (a instanceof PopupWindow) { + PopupWindow toolTipWindow = (PopupWindow) a; + toolTipWindow.removeAll(); + toolTipWindow.dispose(); + } + } + + protected static class PopupMenuProxy extends AccessibleContext + implements Accessible, AccessibleComponent { + AccessibleContext menu; + AccessibleComponent menuComponent; + int x = 0; int y = 0; int width = 0; int height = 0; + + PopupMenuProxy(AccessibleContext ac) { + menu = ac; + menuComponent = menu.getAccessibleComponent(); + + /** calculate the bounding rectangle by iterating over the + * the children. + */ + int x2 = 0; int y2 = 0; + int count = ac.getAccessibleChildrenCount(); + for (int i = 0; i < count; i++) { + Accessible a = menu.getAccessibleChild(i); + + if (a != null) { + AccessibleContext childAC = a.getAccessibleContext(); + + if (childAC != null) { + AccessibleComponent comp = ac.getAccessibleComponent(); + + if (comp != null) { + java.awt.Point p = comp.getLocationOnScreen(); + java.awt.Dimension d = comp.getSize(); + + if (p != null && d != null) { + if (p.x < x) { + x = p.x; + } + if (p.y < y) { + y = p.y; + } + if (p.x + d.width > x2) { + x2 = p.x + d.width; + } + if (p.y + d.height > y2) { + y2 = p.y + d.height; + } + } + } + } + } + } + + width = x2 - x; + height = y2 - y; + } + + /** Returns the AccessibleContext associated with this object */ + public javax.accessibility.AccessibleContext getAccessibleContext() { + return this; + } + + /** Returns the AccessibleContext associated with this object */ + public javax.accessibility.AccessibleComponent getAccessibleComponent() { + return this; + } + + /** Returns the AccessibleText associated with this object */ + public javax.accessibility.AccessibleText getAccessibleText() { + return menu.getAccessibleText(); + } + + /** Returns the AccessibleContext associated with this object */ + public javax.accessibility.AccessibleStateSet getAccessibleStateSet() { + return menu.getAccessibleStateSet(); + } + + public java.util.Locale getLocale() { + return menu.getLocale(); + } + + public int getAccessibleIndexInParent() { + return -1; + } + + public int getAccessibleChildrenCount() { + return menu.getAccessibleChildrenCount(); + } + + public javax.accessibility.Accessible getAccessibleChild(int i) { + return menu.getAccessibleChild(i); + } + + public javax.accessibility.AccessibleRole getAccessibleRole() { + return javax.accessibility.AccessibleRole.POPUP_MENU; + } + + /* + * AccessibleComponent + */ + public void addFocusListener(java.awt.event.FocusListener fl) { + menuComponent.addFocusListener(fl); + } + + public void removeFocusListener(java.awt.event.FocusListener fl) { + menuComponent.removeFocusListener(fl); + } + + /** Returns the background color of the object */ + public java.awt.Color getBackground() { + return menuComponent.getBackground(); + } + + public void setBackground(java.awt.Color c) { + // Not supported by UNO accessibility API + } + + /** Returns the foreground color of the object */ + public java.awt.Color getForeground() { + return menuComponent.getForeground(); + } + + public void setForeground(java.awt.Color c) { + menuComponent.setForeground(c); + } + + public java.awt.Cursor getCursor() { + return menuComponent.getCursor(); + } + + public void setCursor(java.awt.Cursor cursor) { + menuComponent.setCursor(cursor); + } + + public java.awt.Font getFont() { + return menuComponent.getFont(); + } + + public void setFont(java.awt.Font f) { + menuComponent.setFont(f); + } + + public java.awt.FontMetrics getFontMetrics(java.awt.Font f) { + return menuComponent.getFontMetrics(f); + } + + public boolean isEnabled() { + return menuComponent.isEnabled(); + } + + public void setEnabled(boolean b) { + menuComponent.setEnabled(b); + } + + public boolean isVisible() { + return menuComponent.isVisible(); + } + + public void setVisible(boolean b) { + menuComponent.setVisible(b); + } + + public boolean isShowing() { + return menuComponent.isShowing(); + } + + public boolean contains(java.awt.Point p) { + java.awt.Dimension d = getSize(); + + if (Build.DEBUG) { + System.err.println("PopupMenuProxy.containsPoint(" + p.x + "," + + p.y + ") returns " + + (((d.width >= 0) && (p.x < d.width) && (d.height >= 0) && + (p.y < d.height)) ? "true" : "false")); + } + + if ((d.width >= 0) && (p.x < d.width) && (d.height >= 0) && + (p.y < d.height)) { + return true; + } + + return false; + } + + /** Returns the location of the object on the screen. */ + public java.awt.Point getLocationOnScreen() { + return new java.awt.Point(x,y); + } + + /** Gets the location of this component in the form of a point specifying the component's top-left corner */ + public java.awt.Point getLocation() { + // This object represents a toplevel, so this is the same as getLocationOnScreen() + return getLocationOnScreen(); + } + + /** Moves this component to a new location */ + public void setLocation(java.awt.Point p) { + // Not supported by UNO accessibility API + } + + /** Gets the bounds of this component in the form of a Rectangle object */ + public java.awt.Rectangle getBounds() { + return new java.awt.Rectangle(x, y, width, height); + } + + /** Moves and resizes this component to conform to the new bounding rectangle r */ + public void setBounds(java.awt.Rectangle r) { + // Not supported by UNO accessibility API + } + + /** Returns the size of this component in the form of a Dimension object */ + public java.awt.Dimension getSize() { + return new java.awt.Dimension(width, height); + } + + /** Resizes this component so that it has width d.width and height d.height */ + public void setSize(java.awt.Dimension d) { + // Not supported by UNO accessibility API + } + + /** Returns the Accessible child, if one exists, contained at the local + * coordinate Point + */ + public javax.accessibility.Accessible getAccessibleAt(java.awt.Point p) { + java.awt.Point p2 = menuComponent.getLocationOnScreen(); + return menuComponent.getAccessibleAt( + new java.awt.Point(p.x + x - p2.x, p.y + y - p2.y)); + } + + public boolean isFocusTraversable() { + return menuComponent.isFocusTraversable(); + } + + public void requestFocus() { + menuComponent.requestFocus(); + } + } + + protected static class ListProxy extends AccessibleContext + implements Accessible, AccessibleComponent { + AccessibleContext list; + AccessibleComponent listComponent; + + ListProxy(AccessibleContext ac) { + list = ac; + listComponent = list.getAccessibleComponent(); + } + + /** Returns the AccessibleContext associated with this object */ + public javax.accessibility.AccessibleContext getAccessibleContext() { + return this; + } + + /** Returns the AccessibleContext associated with this object */ + public javax.accessibility.AccessibleComponent getAccessibleComponent() { + return this; + } + + /** Returns the AccessibleSelection associated with this object */ + public javax.accessibility.AccessibleSelection getAccessibleSelection() { + return list.getAccessibleSelection(); + } + + /** Returns the AccessibleContext associated with this object */ + public javax.accessibility.AccessibleStateSet getAccessibleStateSet() { + return list.getAccessibleStateSet(); + } + + public java.util.Locale getLocale() { + return list.getLocale(); + } + + public int getAccessibleIndexInParent() { + return -1; + } + + public int getAccessibleChildrenCount() { + return list.getAccessibleChildrenCount(); + } + + public javax.accessibility.Accessible getAccessibleChild(int i) { + return list.getAccessibleChild(i); + } + + public javax.accessibility.AccessibleRole getAccessibleRole() { + return javax.accessibility.AccessibleRole.LIST; + } + + /* + * AccessibleComponent + */ + public void addFocusListener(java.awt.event.FocusListener fl) { + listComponent.addFocusListener(fl); + } + + public void removeFocusListener(java.awt.event.FocusListener fl) { + listComponent.removeFocusListener(fl); + } + + /** Returns the background color of the object */ + public java.awt.Color getBackground() { + return listComponent.getBackground(); + } + + public void setBackground(java.awt.Color c) { + // Not supported by UNO accessibility API + } + + /** Returns the foreground color of the object */ + public java.awt.Color getForeground() { + return listComponent.getForeground(); + } + + public void setForeground(java.awt.Color c) { + listComponent.setForeground(c); + } + + public java.awt.Cursor getCursor() { + return listComponent.getCursor(); + } + + public void setCursor(java.awt.Cursor cursor) { + listComponent.setCursor(cursor); + } + + public java.awt.Font getFont() { + return listComponent.getFont(); + } + + public void setFont(java.awt.Font f) { + listComponent.setFont(f); + } + + public java.awt.FontMetrics getFontMetrics(java.awt.Font f) { + return listComponent.getFontMetrics(f); + } + + public boolean isEnabled() { + return listComponent.isEnabled(); + } + + public void setEnabled(boolean b) { + listComponent.setEnabled(b); + } + + public boolean isVisible() { + return listComponent.isVisible(); + } + + public void setVisible(boolean b) { + listComponent.setVisible(b); + } + + public boolean isShowing() { + return listComponent.isShowing(); + } + + public boolean contains(java.awt.Point p) { + return listComponent.contains(p); + } + + /** Returns the location of the object on the screen. */ + public java.awt.Point getLocationOnScreen() { + return listComponent.getLocationOnScreen(); + } + + /** Gets the location of this component in the form of a point specifying + * the component's top-left corner + */ + public java.awt.Point getLocation() { + // This object represents a toplevel object, so getLocation() should + // return the same as getLocationOnScreen(). + return getLocationOnScreen(); + } + + /** Moves this component to a new location */ + public void setLocation(java.awt.Point p) { + // Not supported by UNO accessibility API + } + + /** Gets the bounds of this component in the form of a Rectangle object */ + public java.awt.Rectangle getBounds() { + java.awt.Point p = getLocationOnScreen(); + java.awt.Dimension d = getSize(); + return new java.awt.Rectangle(p.x, p.y, d.width, d.height); + } + + /** Moves and resizes this component to conform to the new bounding rectangle r */ + public void setBounds(java.awt.Rectangle r) { + // Not supported by UNO accessibility API + } + + /** Returns the size of this component in the form of a Dimension object */ + public java.awt.Dimension getSize() { + return listComponent.getSize(); + } + + /** Resizes this component so that it has width d.width and height d.height */ + public void setSize(java.awt.Dimension d) { + // Not supported by UNO accessibility API + } + + /** Returns the Accessible child, if one exists, contained at the local + * coordinate Point + */ + public javax.accessibility.Accessible getAccessibleAt(java.awt.Point p) { + return listComponent.getAccessibleAt(p); + } + + public boolean isFocusTraversable() { + return listComponent.isFocusTraversable(); + } + + public void requestFocus() { + listComponent.requestFocus(); + } + } +} diff --git a/accessibility/bridge/org/openoffice/accessibility/java_uno_accessbridge.component b/accessibility/bridge/org/openoffice/accessibility/java_uno_accessbridge.component new file mode 100644 index 000000000000..5fc897f2d5aa --- /dev/null +++ b/accessibility/bridge/org/openoffice/accessibility/java_uno_accessbridge.component @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.Java2" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="org.openoffice.accessibility.AccessBridge"> + <service name="com.sun.star.accessibility.AccessBridge"/> + </implementation> +</component> diff --git a/accessibility/bridge/org/openoffice/accessibility/makefile.mk b/accessibility/bridge/org/openoffice/accessibility/makefile.mk new file mode 100755 index 000000000000..1fa29f5bfcb1 --- /dev/null +++ b/accessibility/bridge/org/openoffice/accessibility/makefile.mk @@ -0,0 +1,62 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJNAME = accessibility +PRJ = ..$/..$/..$/.. +TARGET = java_uno_accessbridge +PACKAGE = org$/openoffice$/accessibility + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +JARFILES = jurt.jar unoil.jar ridl.jar +JAVAFILES = \ + AccessBridge.java \ + KeyHandler.java \ + PopupWindow.java \ + WindowsAccessBridgeAdapter.java + +JAVACLASSFILES= $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class) + +JARTARGET = $(TARGET).jar +JARCOMPRESS = TRUE +JARCLASSDIRS = $(PACKAGE) org/openoffice/java/accessibility +CUSTOMMANIFESTFILE = manifest + +# --- Targets ------------------------------------------------------ + + +.INCLUDE : target.mk + +ALLTAR : $(MISC)/java_uno_accessbridge.component + +$(MISC)/java_uno_accessbridge.component .ERRREMOVE : \ + $(SOLARENV)/bin/createcomponent.xslt java_uno_accessbridge.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_BASIS_JAVA)$(JARTARGET)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt java_uno_accessbridge.component diff --git a/accessibility/bridge/org/openoffice/accessibility/manifest b/accessibility/bridge/org/openoffice/accessibility/manifest new file mode 100755 index 000000000000..4b5ffd54d34b --- /dev/null +++ b/accessibility/bridge/org/openoffice/accessibility/manifest @@ -0,0 +1,2 @@ +RegistrationClassName: org.openoffice.accessibility.AccessBridge +UNO-Type-Path: |