--- old/make/Javadoc.gmk 2015-03-30 10:52:56.273627000 -0500 +++ new/make/Javadoc.gmk 2015-03-30 10:52:55.831126200 -0500 @@ -1,4 +1,4 @@ -# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -74,6 +74,7 @@ JNLP_FIRST_COPYRIGHT_YEAR = 1998 PLUGIN2_FIRST_COPYRIGHT_YEAR = 2007 JDKNET_FIRST_COPYRIGHT_YEAR = 2014 +JACCESSAPI_FIRST_COPYRIGHT_YEAR = 2002 # Oracle name FULL_COMPANY_NAME = Oracle and/or its affiliates @@ -1208,6 +1209,56 @@ ############################################################# # +# jaccessdocs - Java Accessibility Utilities +# + +ALL_OTHER_TARGETS += jaccessdocs + +JACCESSAPI_DOCDIR := $(JRE_API_DOCSDIR)/accessibility/jaccess/spec +JACCESSAPI2COREAPI := ../../../$(JDKJRE2COREAPI) +JACCESSAPI_DOCTITLE := JACCESS API +JACCESSAPI_WINDOWTITLE := JACCESS API +JACCESSAPI_HEADER := JACCESS API +JACCESSAPI_BOTTOM := $(call CommonBottom,$(JACCESSAPI_FIRST_COPYRIGHT_YEAR)) +# JACCESSAPI_PKGS is located in NON_CORE_PKGS.gmk + +JACCESSAPI_INDEX_HTML = $(JACCESSAPI_DOCDIR)/index.html +JACCESSAPI_OPTIONS_FILE = $(DOCSTMPDIR)/jaccess.options +JACCESSAPI_PACKAGES_FILE = $(DOCSTMPDIR)/jaccess.packages + +jaccessdocs: $(JACCESSAPI_INDEX_HTML) + +# Set relative location to core api document root +$(JACCESSAPI_INDEX_HTML): GET2DOCSDIR=$(JACCESSAPI2COREAPI)/.. + +# Run javadoc if the index file is out of date or missing +$(JACCESSAPI_INDEX_HTML): $(JACCESSAPI_OPTIONS_FILE) $(JACCESSAPI_PACKAGES_FILE) coredocs + $(prep-javadoc) + $(call JavadocSummary,$(JACCESSAPI_OPTIONS_FILE),$(JACCESSAPI_PACKAGES_FILE)) + $(JAVADOC_CMD) -d $(@D) \ + @$(JACCESSAPI_OPTIONS_FILE) @$(JACCESSAPI_PACKAGES_FILE) + +# Create file with javadoc options in it +$(JACCESSAPI_OPTIONS_FILE): + $(prep-target) + @($(call OptionOnly,$(COMMON_JAVADOCFLAGS)) ; \ + $(call OptionPair,-sourcepath,$(RELEASEDOCS_SOURCEPATH)) ; \ + $(call OptionPair,-encoding,ascii) ; \ + $(call OptionOnly,-nodeprecatedlist) ; \ + $(call OptionPair,-doctitle,$(JACCESSAPI_DOCTITLE)) ; \ + $(call OptionPair,-windowtitle,$(JACCESSAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \ + $(call OptionPair,-header,$(JACCESSAPI_HEADER)$(DRAFT_HEADER)) ; \ + $(call OptionPair,-bottom,$(JACCESSAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \ + $(call OptionTrip,-linkoffline,$(JACCESSAPI2COREAPI),$(COREAPI_DOCSDIR)/); \ + ) >> $@ + +# Create a file with the package names in it +$(JACCESSAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(JACCESSAPI_PKGS)) + $(prep-target) + $(call PackageFilter,$(JACCESSAPI_PKGS)) + +############################################################# +# # jdk.net docs # --- old/make/common/NON_CORE_PKGS.gmk 2015-03-30 10:52:59.676147200 -0500 +++ new/make/common/NON_CORE_PKGS.gmk 2015-03-30 10:52:59.226146600 -0500 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -100,6 +100,8 @@ jdk.net \ jdk.management.cmm +JACCESSAPI_PKGS = com.sun.java.accessibility.util + # non-core packages in rt.jar NON_CORE_PKGS = $(DOMAPI_PKGS) \ $(MGMT_PKGS) \ @@ -111,4 +113,5 @@ $(SMARTCARDIO_PKGS) \ $(SCTPAPI_PKGS) \ $(APPLE_EXT_PKGS) \ - $(JDK_PKGS) + $(JDK_PKGS) \ + $(JACCESSAPI_PKGS) --- old/jdk/make/CompileJavaClasses.gmk 2015-03-30 10:53:03.210159100 -0500 +++ new/jdk/make/CompileJavaClasses.gmk 2015-03-30 10:53:02.677158100 -0500 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -271,8 +271,12 @@ # Now we have COPY_PATTERNS, COPY_FILES and COPY_EXTRA ifndef OPENJDK - CLOSED_SRC_DIRS := $(JDK_TOPDIR)/src/closed/share/classes \ + ifeq ($(OPENJDK_TARGET_OS), windows) + CLOSED_SRC_DIRS := $(JDK_TOPDIR)/src/closed/share/classes + else + CLOSED_SRC_DIRS := $(JDK_TOPDIR)/src/closed/share/classes \ $(JDK_TOPDIR)/src/closed/$(OPENJDK_TARGET_OS_API_DIR)/classes + endif endif MACOSX_SRC_DIRS := --- old/jdk/make/CompileLaunchers.gmk 2015-03-30 10:53:07.042166200 -0500 +++ new/jdk/make/CompileLaunchers.gmk 2015-03-30 10:53:06.492165400 -0500 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -659,11 +659,10 @@ ########################################################################################## # jabswitch -ifndef OPENJDK - ifeq ($(OPENJDK_TARGET_OS), windows) +ifeq ($(OPENJDK_TARGET_OS), windows) $(eval $(call SetupNativeCompilation,BUILD_JABSWITCH, \ - SRC := $(JDK_TOPDIR)/src/closed/windows/native/sun/bridge, \ + SRC := $(JDK_TOPDIR)/src/windows/native/sun/bridge, \ INCLUDE_FILES := jabswitch.cpp, \ LANG := C++, \ CFLAGS := $(filter-out -Zc:wchar_t-, $(CFLAGS_JDKEXE)) -Zc:wchar_t \ @@ -675,16 +674,15 @@ OUTPUT_DIR := $(JDK_OUTPUTDIR)/bin, \ PROGRAM := jabswitch, \ DEBUG_SYMBOLS := true, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/closed/windows/native/sun/bridge/AccessBridgeStatusWindow.rc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/native/sun/bridge/AccessBridgeStatusWindow.rc, \ RC_FLAGS := $(RC_FLAGS) \ -D "JDK_FNAME=jabswitch.exe" \ -D "JDK_INTERNAL_NAME=jabswitch" \ -D "JDK_FTYPE=0x01L", \ - MANIFEST := $(JDK_TOPDIR)/src/closed/windows/native/sun/bridge/jabswitch.manifest)) + MANIFEST := $(JDK_TOPDIR)/src/windows/native/sun/bridge/jabswitch.manifest)) BUILD_LAUNCHERS += $(BUILD_JABSWITCH) - endif endif ########################################################################################## --- old/jdk/make/CopyFiles.gmk 2015-03-30 10:53:10.991181200 -0500 +++ new/jdk/make/CopyFiles.gmk 2015-03-30 10:53:10.430180300 -0500 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -55,8 +55,7 @@ ########################################################################################## -ifndef OPENJDK - ifeq ($(OPENJDK_TARGET_OS), windows) +ifeq ($(OPENJDK_TARGET_OS), windows) COPY_FILES += $(OPENJDK_TARGET_OS_INCLUDE)/bridge/AccessBridgeCallbacks.h \ $(OPENJDK_TARGET_OS_INCLUDE)/bridge/AccessBridgeCalls.h \ $(OPENJDK_TARGET_OS_INCLUDE)/bridge/AccessBridgePackages.h \ @@ -64,14 +63,12 @@ $(JDK_OUTPUTDIR)/lib/accessibility.properties $(OPENJDK_TARGET_OS_INCLUDE)/bridge/%: \ - $(JDK_TOPDIR)/src/closed/windows/native/sun/bridge/% + $(JDK_TOPDIR)/src/windows/native/sun/bridge/% $(install-file) $(JDK_OUTPUTDIR)/lib/accessibility.properties: \ - $(JDK_TOPDIR)/src/closed/windows/native/sun/bridge/accessibility.properties + $(JDK_TOPDIR)/src/windows/native/sun/bridge/accessibility.properties $(install-file) - - endif endif ########################################################################################## --- old/jdk/make/gensrc/GensrcMisc.gmk 2015-03-30 10:53:15.004211500 -0500 +++ new/jdk/make/gensrc/GensrcMisc.gmk 2015-03-30 10:53:14.347199000 -0500 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -178,7 +178,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows) AB_GENSRC_DIR := $(JDK_OUTPUTDIR)/gensrc_ab - AB_SRC_DIR := $(JDK_TOPDIR)/src/closed/windows/classes/com/sun/java/accessibility + AB_SRC_DIR := $(JDK_TOPDIR)/src/windows/classes/com/sun/java/accessibility ifeq ($(OPENJDK_TARGET_CPU_BITS), 32) $(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridgeLoader.java: \ --- old/jdk/make/lib/PlatformLibraries.gmk 2015-03-30 10:53:19.099248200 -0500 +++ new/jdk/make/lib/PlatformLibraries.gmk 2015-03-30 10:53:18.532247000 -0500 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -127,10 +127,9 @@ ########################################################################################## -ifndef OPENJDK - ifeq ($(OPENJDK_TARGET_OS), windows) +ifeq ($(OPENJDK_TARGET_OS), windows) - ACCESSBRIDGE_SRCDIR := $(JDK_TOPDIR)/src/closed/windows/native/sun/bridge + ACCESSBRIDGE_SRCDIR := $(JDK_TOPDIR)/src/windows/native/sun/bridge define SetupAccessBridge # Parameter 1 Suffix @@ -149,8 +148,7 @@ LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \ winspool.lib jawt.lib comdlg32.lib advapi32.lib shell32.lib \ ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \ - -subsystem:windows -machine:$2 \ - -def:$(ACCESSBRIDGE_SRCDIR)/JAWTAccessBridge.DEF, \ + -subsystem:windows -machine:$2, \ VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRCDIR)/AccessBridgeStatusWindow.rc, \ RC_FLAGS := $(RC_FLAGS) \ -D "JDK_FNAME=JAWTAccessBridge$1.dll" \ @@ -175,8 +173,7 @@ LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \ winspool.lib comdlg32.lib advapi32.lib shell32.lib \ ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \ - -subsystem:windows -machine:$2 \ - -def:$(ACCESSBRIDGE_SRCDIR)/JavaAccessBridge.DEF, \ + -subsystem:windows -machine:$2, \ VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRCDIR)/AccessBridgeStatusWindow.rc, \ RC_FLAGS := $(RC_FLAGS) \ -D "JDK_FNAME=JavaAccessBridge$1.dll" \ @@ -221,5 +218,5 @@ else $(eval $(call SetupAccessBridge,-64,X64,64)) endif - endif + endif --- /dev/null 2015-03-30 10:53:23.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/32bit/AccessBridgeLoader.java 2015-03-30 10:53:22.433263100 -0500 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility; + +@jdk.Exported(false) +abstract class AccessBridgeLoader { + + /** + * Load JavaAccessBridge.DLL (our native half) + */ + static { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + System.loadLibrary("JavaAccessBridge-32"); + return null; + } + }, null, new java.lang.RuntimePermission("loadLibrary.JavaAccessBridge-32") + ); + } + + boolean useJAWT_DLL = false; + + /** + * AccessBridgeLoader constructor + */ + AccessBridgeLoader() { + // load JAWTAccessBridge.DLL on JDK 1.4.1 or later + // determine which version of the JDK is running + String version = System.getProperty("java.version"); + if (version != null) + useJAWT_DLL = (version.compareTo("1.4.1") >= 0); + + if (useJAWT_DLL) { + // Note that we have to explicitly load JAWT.DLL + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + System.loadLibrary("JAWT"); + System.loadLibrary("JAWTAccessBridge-32"); + return null; + } + }, null, new RuntimePermission("loadLibrary.JAWT"), + new RuntimePermission("loadLibrary.JAWTAccessBridge-32") + ); + } + } +} --- /dev/null 2015-03-30 10:53:26.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/64bit/AccessBridgeLoader.java 2015-03-30 10:53:25.566273300 -0500 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility; + +@jdk.Exported(false) +abstract class AccessBridgeLoader { + + /** + * Load JavaAccessBridge.DLL (our native half) + */ + static { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + System.loadLibrary("JavaAccessBridge-64"); + return null; + } + }, null, new RuntimePermission("loadLibrary.JavaAccessBridge-64") + ); + } + + boolean useJAWT_DLL = false; + + /** + * AccessBridgLoader constructor + */ + AccessBridgeLoader() { + // load JAWTAccessBridge.DLL on JDK 1.4.1 or later + String version = System.getProperty("java.version"); + if (version != null) + useJAWT_DLL = (version.compareTo("1.4.1") >= 0); + + if (useJAWT_DLL) { + // Note that we have to explicitly load JAWT.DLL + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + System.loadLibrary("JAWT"); + System.loadLibrary("JAWTAccessBridge-64"); + return null; + } + }, null, new RuntimePermission("loadLibrary.JAWT"), + new RuntimePermission("loadLibrary.JAWTAccessBridge-64") + ); + } + } + +} --- /dev/null 2015-03-30 10:53:29.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/AccessBridge.java 2015-03-30 10:53:28.708284500 -0500 @@ -0,0 +1,7272 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.lang.*; +import java.lang.reflect.*; + +import java.beans.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.tree.*; +import javax.swing.table.*; +import javax.swing.plaf.TreeUI; + +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; +import sun.awt.AWTAccessor; +import sun.awt.AppContext; +import sun.awt.SunToolkit; + +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; + +/* + * Note: This class has to be public. It's loaded from the VM like this: + * Class.forName(atName).newInstance(); + */ +@jdk.Exported(false) +final public class AccessBridge extends AccessBridgeLoader { + + private final String AccessBridgeVersion = + "AccessBridge 2.0.4"; + + private static AccessBridge theAccessBridge; + private ObjectReferences references; + private EventHandler eventHandler; + private boolean runningOnJDK1_4 = false; + private boolean runningOnJDK1_5 = false; + + // Maps AccessibleRoles strings to AccessibleRoles. + private ConcurrentHashMap accessibleRoleMap = new ConcurrentHashMap<>(); + + /** + If the object's role is in the following array getVirtualAccessibleName + will use the extended search algorithm. + */ + private ArrayList extendedVirtualNameSearchRoles = new ArrayList<>(); + /** + If the role of the object's parent is in the following array + getVirtualAccessibleName will NOT use the extended search + algorithm even if the object's role is in the + extendedVirtualNameSearchRoles array. + */ + private ArrayList noExtendedVirtualNameSearchParentRoles = new ArrayList<>(); + + /** + * AccessBridge constructor + * + * Note: This constructor has to be public. It's called from the VM like this: + * Class.forName(atName).newInstance(); + */ + public AccessBridge() { + super(); + theAccessBridge = this; + references = new ObjectReferences(); + + // initialize shutdown hook + Runtime runTime = Runtime.getRuntime(); + shutdownHook hook = new shutdownHook(); + runTime.addShutdownHook(new Thread(hook)); + + // initialize AccessibleRole map + initAccessibleRoleMap(); + + // determine which version of the JDK is running + String version = getJavaVersionProperty(); + debugString("JDK version = "+version); + runningOnJDK1_4 = (version.compareTo("1.4") >= 0); + runningOnJDK1_5 = (version.compareTo("1.5") >= 0); + + // initialize the methods that map HWNDs and Java top-level + // windows + if (initHWNDcalls() == true) { + + // is this a JVM we can use? + // install JDK 1.2 and later Swing ToolKit listener + EventQueueMonitor.isGUIInitialized(); + + // start the Java event handler + eventHandler = new EventHandler(this); + + // register for menu selection events + if (runningOnJDK1_4) { + MenuSelectionManager.defaultManager().addChangeListener(eventHandler); + } + + // register as a NativeWindowHandler + addNativeWindowHandler(new DefaultNativeWindowHandler()); + + // start in a new thread + Thread abthread = new Thread(new dllRunner()); + abthread.setDaemon(true); + abthread.start(); + debugString("AccessBridge started"); + } + } + + /* + * adaptor to run the AccessBridge DLL + */ + private class dllRunner implements Runnable { + public void run() { + runDLL(); + } + } + + /* + * shutdown hook + */ + private class shutdownHook implements Runnable { + + public void run() { + debugString("***** shutdownHook: shutting down..."); + javaShutdown(); + } + } + + + /* + * Initialize the hashtable that maps Strings to AccessibleRoles. + */ + private void initAccessibleRoleMap() { + /* + * Initialize the AccessibleRoles map. This code uses methods in + * java.lang.reflect.* to build the map. + */ + try { + Class clAccessibleRole = Class.forName ("javax.accessibility.AccessibleRole"); + if (null != clAccessibleRole) { + AccessibleRole roleUnknown = AccessibleRole.UNKNOWN; + Field [] fields = clAccessibleRole.getFields (); + int i = 0; + for (i = 0; i < fields.length; i ++) { + Field f = fields [i]; + if (javax.accessibility.AccessibleRole.class == f.getType ()) { + AccessibleRole nextRole = (AccessibleRole) (f.get (roleUnknown)); + String nextRoleString = nextRole.toDisplayString (Locale.US); + accessibleRoleMap.put (nextRoleString, nextRole); + } + } + } + } catch (Exception e) {} + + /* + Build the extendedVirtualNameSearchRoles array list. I chose this method + because some of the Accessible Roles that need to be added to it are not + available in all versions of the J2SE that we want to support. + */ + extendedVirtualNameSearchRoles.add (AccessibleRole.COMBO_BOX); + try { + /* + Added in J2SE 1.4 + */ + extendedVirtualNameSearchRoles.add (AccessibleRole.DATE_EDITOR); + } catch (NoSuchFieldError e) {} + extendedVirtualNameSearchRoles.add (AccessibleRole.LIST); + extendedVirtualNameSearchRoles.add (AccessibleRole.PASSWORD_TEXT); + extendedVirtualNameSearchRoles.add (AccessibleRole.SLIDER); + try { + /* + Added in J2SE 1.3 + */ + extendedVirtualNameSearchRoles.add (AccessibleRole.SPIN_BOX); + } catch (NoSuchFieldError e) {} + extendedVirtualNameSearchRoles.add (AccessibleRole.TABLE); + extendedVirtualNameSearchRoles.add (AccessibleRole.TEXT); + extendedVirtualNameSearchRoles.add (AccessibleRole.UNKNOWN); + + noExtendedVirtualNameSearchParentRoles.add (AccessibleRole.TABLE); + noExtendedVirtualNameSearchParentRoles.add (AccessibleRole.TOOL_BAR); + } + + /** + * start the AccessBridge DLL running in its own thread + */ + private native void runDLL(); + + /** + * debugging output (goes to OutputDebugStr()) + */ + private native void sendDebugString(String debugStr); + + /** + * debugging output (goes to OutputDebugStr()) + */ + private void debugString(String debugStr) { + sendDebugString(debugStr); + } + + /* ===== utility methods ===== */ + + /** + * decrement the reference to the object (called by native code) + */ + private void decrementReference(Object o) { + references.decrement(o); + } + + /** + * get the java.version property from the JVM + */ + private String getJavaVersionProperty() { + String s = System.getProperty("java.version"); + if (s != null) { + references.increment(s); + return s; + } + return null; + } + + /** + * get the java.version property from the JVM + */ + private String getAccessBridgeVersion() { + String s = new String(AccessBridgeVersion); + references.increment(s); + return s; + } + + /* ===== HWND/Java window mapping methods ===== */ + + // Java toolkit methods for mapping HWNDs to Java components + private Method javaGetComponentFromNativeWindowHandleMethod; + private Method javaGetNativeWindowHandleFromComponentMethod; + + // native jawt methods for mapping HWNDs to Java components + private native int isJAWTInstalled(); + + private native int jawtGetNativeWindowHandleFromComponent(Component comp); + + private native Component jawtGetComponentFromNativeWindowHandle(int handle); + + Toolkit toolkit; + + /** + * map an HWND to an AWT Component + */ + private boolean initHWNDcalls() { + Class integerParemter[] = new Class[1]; + integerParemter[0] = Integer.TYPE; + Class componentParemter[] = new Class[1]; + try { + componentParemter[0] = Class.forName("java.awt.Component"); + } catch (ClassNotFoundException e) { + debugString("Exception: " + e.toString()); + } + Object[] args = new Object[1]; + Component c; + boolean returnVal = false; + + toolkit = Toolkit.getDefaultToolkit(); + + if (useJAWT_DLL) { + returnVal = true; + } else { + // verify javaGetComponentFromNativeWindowHandle() method + // is present if JAWT.DLL is not installed + try { + javaGetComponentFromNativeWindowHandleMethod = + toolkit.getClass().getMethod( + "getComponentFromNativeWindowHandle", integerParemter); + if (javaGetComponentFromNativeWindowHandleMethod != null) { + try { + args[0] = new Integer(1); + c = (Component) javaGetComponentFromNativeWindowHandleMethod.invoke(toolkit, args); + returnVal = true; + } catch (InvocationTargetException e) { + debugString("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + debugString("Exception: " + e.toString()); + } + } + } catch (NoSuchMethodException e) { + debugString("Exception: " + e.toString()); + } catch (SecurityException e) { + debugString("Exception: " + e.toString()); + } + + // verify getComponentFromNativeWindowHandle() method + // is present if JAWT.DLL is not installed + try { + javaGetNativeWindowHandleFromComponentMethod = + toolkit.getClass().getMethod( + "getNativeWindowHandleFromComponent", componentParemter); + if (javaGetNativeWindowHandleFromComponentMethod != null) { + try { + args[0] = new Button("OK"); // need some Component... + Integer i = (Integer) javaGetNativeWindowHandleFromComponentMethod.invoke(toolkit, args); + returnVal = true; + } catch (InvocationTargetException e) { + debugString("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + debugString("Exception: " + e.toString()); + } catch (Exception e) { + debugString("Exception: " + e.toString()); + } + } + } catch (NoSuchMethodException e) { + debugString("Exception: " + e.toString()); + } catch (SecurityException e) { + debugString("Exception: " + e.toString()); + } + } + return returnVal; + } + + // native window handler interface + private interface NativeWindowHandler { + public Accessible getAccessibleFromNativeWindowHandle(int nativeHandle); + } + + // hash table of native window handle to AccessibleContext mappings + static private ConcurrentHashMap windowHandleToContextMap = new ConcurrentHashMap<>(); + + // hash table of AccessibleContext to native window handle mappings + static private ConcurrentHashMap contextToWindowHandleMap = new ConcurrentHashMap<>(); + + /* + * adds a virtual window handler to our hash tables + */ + static private void registerVirtualFrame(final Accessible a, + Integer nativeWindowHandle ) { + if (a != null) { + AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return a.getAccessibleContext(); + } + }, a); + windowHandleToContextMap.put(nativeWindowHandle, ac); + contextToWindowHandleMap.put(ac, nativeWindowHandle); + } + } + + /* + * removes a virtual window handler to our hash tables + */ + static private void revokeVirtualFrame(final Accessible a, + Integer nativeWindowHandle ) { + AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return a.getAccessibleContext(); + } + }, a); + windowHandleToContextMap.remove(nativeWindowHandle); + contextToWindowHandleMap.remove(ac); + } + + // vector of native window handlers + private static Vector nativeWindowHandlers = new Vector<>(); + + /* + * adds a native window handler to our list + */ + private static void addNativeWindowHandler(NativeWindowHandler handler) { + if (handler == null) { + throw new IllegalArgumentException(); + } + nativeWindowHandlers.addElement(handler); + } + + /* + * removes a native window handler to our list + */ + private static boolean removeNativeWindowHandler(NativeWindowHandler handler) { + if (handler == null) { + throw new IllegalArgumentException(); + } + return nativeWindowHandlers.removeElement(handler); + } + + /** + * verifies that a native window handle is a Java window + */ + private boolean isJavaWindow(int nativeHandle) { + AccessibleContext ac = getContextFromNativeWindowHandle(nativeHandle); + if (ac != null) { + saveContextToWindowHandleMapping(ac, nativeHandle); + return true; + } + return false; + } + + /* + * saves the mapping between an AccessibleContext and a window handle + */ + private void saveContextToWindowHandleMapping(AccessibleContext ac, + int nativeHandle) { + debugString("saveContextToWindowHandleMapping..."); + if (ac == null) { + return; + } + if (! contextToWindowHandleMap.containsKey(ac)) { + debugString("saveContextToWindowHandleMapping: ac = "+ac+"; handle = "+nativeHandle); + contextToWindowHandleMap.put(ac, nativeHandle); + } + } + + /** + * maps a native window handle to an Accessible Context + */ + private AccessibleContext getContextFromNativeWindowHandle(int nativeHandle) { + // First, look for the Accessible in our hash table of + // virtual window handles. + AccessibleContext ac = windowHandleToContextMap.get(nativeHandle); + if(ac!=null) { + saveContextToWindowHandleMapping(ac, nativeHandle); + return ac; + } + + // Next, look for the native window handle in our vector + // of native window handles. + int numHandlers = nativeWindowHandlers.size(); + for (int i = 0; i < numHandlers; i++) { + NativeWindowHandler nextHandler = nativeWindowHandlers.elementAt(i); + final Accessible a = nextHandler.getAccessibleFromNativeWindowHandle(nativeHandle); + if (a != null) { + ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return a.getAccessibleContext(); + } + }, a); + saveContextToWindowHandleMapping(ac, nativeHandle); + return ac; + } + } + // Not found. + return null; + } + + /** + * maps an AccessibleContext to a native window handle + * returns 0 on error + */ + private int getNativeWindowHandleFromContext(AccessibleContext ac) { + debugString("getNativeWindowHandleFromContext: ac = "+ac); + try { + return contextToWindowHandleMap.get(ac); + } catch (Exception ex) { + return 0; + } + } + + private class DefaultNativeWindowHandler implements NativeWindowHandler { + /* + * returns the Accessible associated with a native window + */ + public Accessible getAccessibleFromNativeWindowHandle(int nativeHandle) { + final Component c = getComponentFromNativeWindowHandle(nativeHandle); + if (c instanceof Accessible) { + AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return c.getAccessibleContext(); + } + }, c); + saveContextToWindowHandleMapping(ac, nativeHandle); + return (Accessible)c; + } else { + return null; + } + } + + /** + * map an HWND to an AWT Component + */ + private Component getComponentFromNativeWindowHandle(int nativeHandle) { + if (useJAWT_DLL) { + debugString("*** calling jawtGetComponentFromNativeWindowHandle"); + return jawtGetComponentFromNativeWindowHandle(nativeHandle); + } else { + debugString("*** calling javaGetComponentFromNativeWindowHandle"); + Object[] args = new Object[1]; + if (javaGetComponentFromNativeWindowHandleMethod != null) { + try { + args[0] = nativeHandle; + Object o = javaGetComponentFromNativeWindowHandleMethod.invoke(toolkit, args); + if (o instanceof Accessible) { + final Accessible acc=(Accessible)o; + AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return acc.getAccessibleContext(); + } + }, (Component)o); + saveContextToWindowHandleMapping(ac,nativeHandle); + } + return (Component)o; + } catch (InvocationTargetException | IllegalAccessException e) { + debugString("Exception: " + e.toString()); + } + } + } + return null; + } + } + + /** + * map an AWT Component to an HWND + */ + private int getNativeWindowHandleFromComponent(final Component target) { + if (useJAWT_DLL) { + debugString("*** calling jawtGetNativeWindowHandleFromComponent"); + return jawtGetNativeWindowHandleFromComponent(target); + } else { + Object[] args = new Object[1]; + debugString("*** calling javaGetNativeWindowHandleFromComponent"); + if (javaGetNativeWindowHandleFromComponentMethod != null) { + try { + args[0] = target; + Integer i = (Integer) javaGetNativeWindowHandleFromComponentMethod.invoke(toolkit, args); + // cache the mapping + AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return target.getAccessibleContext(); + } + }, target); + contextToWindowHandleMap.put(ac, i); + return i.intValue(); + } catch (InvocationTargetException e) { + debugString("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + debugString("Exception: " + e.toString()); + } + } + } + return -1; + } + + /* ===== AccessibleContext methods =====*/ + + /* + * returns the inner-most AccessibleContext in parent at Point(x, y) + */ + private AccessibleContext getAccessibleContextAt(int x, int y, + AccessibleContext parent) { + if (parent == null) { + return null; + } + if (windowHandleToContextMap != null && + windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) { + // Path for applications that register their top-level + // windows with the AccessBridge (e.g., StarOffice 6.1) + return getAccessibleContextAt_1(x, y, parent); + } else { + // Path for applications that do not register + // their top-level windows with the AccessBridge + // (e.g., Swing/AWT applications) + return getAccessibleContextAt_2(x, y, parent); + } + } + + /* + * returns the root accessible context + */ + private AccessibleContext getRootAccessibleContext(final AccessibleContext ac) { + if (ac == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible parent = ac.getAccessibleParent(); + if (parent == null) { + return ac; + } + Accessible tmp = parent.getAccessibleContext().getAccessibleParent(); + while (tmp != null) { + parent = tmp; + tmp = parent.getAccessibleContext().getAccessibleParent(); + } + return parent.getAccessibleContext(); + } + }, ac); + } + + /* + * StarOffice version that does not use the EventQueueMonitor + */ + private AccessibleContext getAccessibleContextAt_1(final int x, final int y, + final AccessibleContext parent) { + debugString(" : getAccessibleContextAt_1 called"); + debugString(" -> x = " + x + " y = " + y + " parent = " + parent); + + if (parent == null) return null; + final AccessibleComponent acmp = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleComponent call() throws Exception { + return parent.getAccessibleComponent(); + } + }, parent); + if (acmp!=null) { + final Point loc = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Point call() throws Exception { + return acmp.getLocation(); + } + }, parent); + final Accessible a = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return acmp.getAccessibleAt(new Point(x - loc.x, y - loc.y)); + } + }, parent); + if (a != null) { + AccessibleContext foundAC = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return a.getAccessibleContext(); + } + }, parent); + if (foundAC != null) { + if (foundAC != parent) { + // recurse down into the child + return getAccessibleContextAt_1(x - loc.x, y - loc.y, + foundAC); + } else + return foundAC; + } + } + } + return parent; + } + + /* + * AWT/Swing version + */ + private AccessibleContext getAccessibleContextAt_2(final int x, final int y, + AccessibleContext parent) { + debugString("getAccessibleContextAt_2 called"); + debugString(" -> x = " + x + " y = " + y + " parent = " + parent); + + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = EventQueueMonitor.getAccessibleAt(new Point(x, y)); + if (a != null) { + AccessibleContext childAC = a.getAccessibleContext(); + if (childAC != null) { + debugString(" returning childAC = " + childAC); + return childAC; + } + } + return null; + } + }, parent); + } + + /** + * returns the Accessible that has focus + */ + private AccessibleContext getAccessibleContextWithFocus() { + Component c = AWTEventMonitor.getComponentWithFocus(); + if (c != null) { + final Accessible a = Translator.getAccessible(c); + if (a != null) { + AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return a.getAccessibleContext(); + } + }, c); + if (ac != null) { + return ac; + } + } + } + return null; + } + + /** + * returns the AccessibleName from an AccessibleContext + */ + private String getAccessibleNameFromContext(final AccessibleContext ac) { + debugString("***** ac = "+ac.getClass()); + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleName(); + } + }, ac); + if (s != null) { + references.increment(s); + debugString("Returning AccessibleName from Context: " + s); + return s; + } else { + return null; + } + } else { + debugString("getAccessibleNameFromContext; ac = null!"); + return null; + } + } + + /** + * Returns an AccessibleName for a component using an algorithm optimized + * for the JAWS screen reader. This method is only intended for JAWS. All + * other uses are entirely optional. + */ + private String getVirtualAccessibleNameFromContext(final AccessibleContext ac) { + if (null != ac) { + /* + Step 1: + ======= + Determine if we can obtain the Virtual Accessible Name from the + Accessible Name or Accessible Description of the object. + */ + String nameString = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleName(); + } + }, ac); + if ( ( null != nameString ) && ( 0 != nameString.length () ) ) { + debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleName."); + references.increment (nameString); + return nameString; + } + String descriptionString = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleDescription(); + } + }, ac); + if ( ( null != descriptionString ) && ( 0 != descriptionString.length () ) ) { + debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleDescription."); + references.increment (descriptionString); + return descriptionString; + } + + debugString ("The Virtual Accessible Name was not found using AccessibleContext::getAccessibleDescription. or getAccessibleName"); + /* + Step 2: + ======= + Decide whether the extended name search algorithm should be + used for this object. + */ + boolean bExtendedSearch = false; + AccessibleRole role = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return ac.getAccessibleRole(); + } + }, ac); + AccessibleContext parentContext = null; + AccessibleRole parentRole = AccessibleRole.UNKNOWN; + + if ( extendedVirtualNameSearchRoles.contains (role) ) { + parentContext = getAccessibleParentFromContext (ac); + if ( null != parentContext ) { + final AccessibleContext parentContextInnerTemp = parentContext; + parentRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return parentContextInnerTemp.getAccessibleRole(); + } + }, ac); + if ( AccessibleRole.UNKNOWN != parentRole ) { + bExtendedSearch = true; + if ( noExtendedVirtualNameSearchParentRoles.contains (parentRole) ) { + bExtendedSearch = false; + } + } + } + } + + if (false == bExtendedSearch) { + debugString ("bk -- getVirtualAccessibleNameFromContext will not use the extended name search algorithm. role = " + role.toDisplayString (Locale.US) ); + /* + Step 3: + ======= + We have determined that we should not use the extended name + search algorithm for this object (we must obtain the name of + the object from the object itself and not from neighboring + objects). However the object name cannot be obtained from + the Accessible Name or Accessible Description of the object. + + Handle several special cases here that might yield a value for + the Virtual Accessible Name. Return null if the object does + not match the criteria for any of these special cases. + */ + if (AccessibleRole.LABEL == role) { + /* + Does the label support the Accessible Text Interface? + */ + final AccessibleText at = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleText call() throws Exception { + return ac.getAccessibleText(); + } + }, ac); + if (null != at) { + int charCount = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getCharCount(); + } + }, ac); + String text = getAccessibleTextRangeFromContext (ac, 0, charCount); + if (null != text) { + debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Text of the LABEL object."); + references.increment (text); + return text; + } + } + /* + Does the label support the Accessible Icon Interface? + */ + debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information."); + final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleIcon[] call() throws Exception { + return ac.getAccessibleIcon(); + } + }, ac); + if ( (null != ai) && (ai.length > 0) ) { + String iconDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ai[0].getAccessibleIconDescription(); + } + }, ac); + if (iconDescription != null){ + debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the LABEL object."); + references.increment (iconDescription); + return iconDescription; + } + } else { + parentContext = getAccessibleParentFromContext (ac); + if ( null != parentContext ) { + final AccessibleContext parentContextInnerTemp = parentContext; + parentRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return parentContextInnerTemp.getAccessibleRole(); + } + }, ac); + if ( AccessibleRole.TABLE == parentRole ) { + int indexInParent = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac.getAccessibleIndexInParent(); + } + }, ac); + final AccessibleContext acTableCell = getAccessibleChildFromContext (parentContext, indexInParent); + debugString ("bk -- Making a second attempt to obtain the Virtual Accessible Name from the Accessible Icon information for the Table Cell."); + if (acTableCell != null) { + final AccessibleIcon [] aiRet =InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleIcon[] call() throws Exception { + return acTableCell.getAccessibleIcon(); + } + }, ac); + if ( (null != aiRet) && (aiRet.length > 0) ) { + String iconDescription = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return aiRet[0].getAccessibleIconDescription (); + } + }, ac); + if (iconDescription != null){ + debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the Table Cell object."); + references.increment (iconDescription); + return iconDescription; + } + } + } + } + } + } + } else if ( (AccessibleRole.TOGGLE_BUTTON == role) || + (AccessibleRole.PUSH_BUTTON == role) ) { + /* + Does the button support the Accessible Icon Interface? + */ + debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information."); + final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable() { + public AccessibleIcon [] call() { + return ac.getAccessibleIcon (); + } + }, ac); + if ( (null != ai) && (ai.length > 0) ) { + String iconDescription = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return ai[0].getAccessibleIconDescription (); + } + }, ac); + if (iconDescription != null){ + debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the TOGGLE_BUTTON or PUSH_BUTTON object."); + references.increment (iconDescription); + return iconDescription; + } + } + } else if ( AccessibleRole.CHECK_BOX == role ) { + /* + NOTE: The only case I know of in which a check box does not + have a name is when that check box is contained in a table. + + In this case it would be appropriate to use the display string + of the check box object as the name (in US English the display + string is typically either "true" or "false"). + + I am using the AccessibleValue interface to obtain the display + string of the check box. If the Accessible Value is 1, I am + returning Boolean.TRUE.toString (), If the Accessible Value is + 0, I am returning Boolean.FALSE.toString (). If the Accessible + Value is some other number, I will return the display string of + the current numerical value of the check box. + */ + final AccessibleValue av = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleValue call() throws Exception { + return ac.getAccessibleValue(); + } + }, ac); + if ( null != av ) { + nameString = null; + Number value = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Number call() throws Exception { + return av.getCurrentAccessibleValue(); + } + }, ac); + if ( null != value ) { + if ( 1 == value.intValue () ) { + nameString = Boolean.TRUE.toString (); + } else if ( 0 == value.intValue () ) { + nameString = Boolean.FALSE.toString (); + } else { + nameString = value.toString (); + } + if ( null != nameString ) { + references.increment (nameString); + return nameString; + } + } + } + } + return null; + } + + /* + + + Beginning of the extended name search + + + */ + final AccessibleContext parentContextOuterTemp = parentContext; + String parentName = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return parentContextOuterTemp.getAccessibleName(); + } + }, ac); + String parentDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return parentContextOuterTemp.getAccessibleDescription(); + } + }, ac); + + /* + Step 4: + ======= + Special case for Slider Bar objects. + */ + if ( (AccessibleRole.SLIDER == role) && + (AccessibleRole.PANEL == parentRole) && + (null != parentName) ) { + debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Name of the SLIDER object's parent object."); + references.increment (parentName); + return parentName; + } + + boolean bIsEditCombo = false; + + AccessibleContext testContext = ac; + /* + Step 5: + ======= + Special case for Edit Combo Boxes + */ + if ( (AccessibleRole.TEXT == role) && + (AccessibleRole.COMBO_BOX == parentRole) ) { + bIsEditCombo = true; + if (null != parentName) { + debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Name of the object's parent object."); + references.increment (parentName); + return parentName; + } else if (null != parentDescription) { + debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Description of the object's parent object."); + references.increment (parentDescription); + return parentDescription; + } + testContext = parentContext; + parentRole = AccessibleRole.UNKNOWN; + parentContext = getAccessibleParentFromContext (testContext); + if ( null != parentContext ) { + final AccessibleContext parentContextInnerTemp = parentContext; + parentRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return parentContextInnerTemp.getAccessibleRole(); + } + }, ac); + } + } + + /* + Step 6: + ======= + Attempt to get the Virtual Accessible Name of the object using the + Accessible Relation Set Info (the LABELED_BY Accessible Relation). + */ + String version = getJavaVersionProperty (); + if ( (null != version) && (version.compareTo ("1.3") >= 0) ) { + final AccessibleContext parentContextTempInner = parentContext; + AccessibleRelationSet ars = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRelationSet call() throws Exception { + return parentContextTempInner.getAccessibleRelationSet(); + } + }, ac); + if ( ars != null && (ars.size () > 0) && (ars.contains (AccessibleRelation.LABELED_BY)) ) { + AccessibleRelation labeledByRelation = ars.get (AccessibleRelation.LABELED_BY); + if (labeledByRelation != null) { + Object [] targets = labeledByRelation.getTarget (); + Object o = targets [0]; + if (o instanceof Accessible) { + AccessibleContext labelContext = ((Accessible)o).getAccessibleContext (); + if (labelContext != null) { + String labelName = labelContext.getAccessibleName (); + String labelDescription = labelContext.getAccessibleDescription (); + if (null != labelName) { + debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Name Case."); + references.increment (labelName); + return labelName; + } else if (null != labelDescription) { + debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Description Case."); + references.increment (labelDescription); + return labelDescription; + } + } + } + } + } + } else { + debugString ("bk -- This version of Java does not support AccessibleContext::getAccessibleRelationSet."); + } + + //Note: add AccessibleContext to use InvocationUtils.invokeAndWait + /* + Step 7: + ======= + Search for a label object that is positioned either just to the left + or just above the object and get the Accessible Name of the Label + object. + */ + int testIndexMax = 0; + int testX = 0; + int testY = 0; + int testWidth = 0; + int testHeight = 0; + int targetX = 0; + int targetY = 0; + final AccessibleContext tempContext = testContext; + int testIndex = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return tempContext.getAccessibleIndexInParent(); + } + }, ac); + if ( null != parentContext ) { + final AccessibleContext parentContextInnerTemp = parentContext; + testIndexMax = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return parentContextInnerTemp.getAccessibleChildrenCount() - 1; + } + }, ac); + } + testX = getAccessibleXcoordFromContext (testContext); + testY = getAccessibleYcoordFromContext (testContext); + testWidth = getAccessibleWidthFromContext (testContext); + testHeight = getAccessibleHeightFromContext (testContext); + targetX = testX + 2; + targetY = testY + 2; + + int childIndex = testIndex - 1; + /*Accessible child = null; + AccessibleContext childContext = null; + AccessibleRole childRole = AccessibleRole.UNKNOWN;*/ + int childX = 0; + int childY = 0; + int childWidth = 0; + int childHeight = 0; + String childName = null; + String childDescription = null; + while (childIndex >= 0) { + final int childIndexTemp = childIndex; + final AccessibleContext parentContextInnerTemp = parentContext; + final Accessible child = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return parentContextInnerTemp.getAccessibleChild(childIndexTemp); + } + }, ac); + if ( null != child ) { + final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return child.getAccessibleContext(); + } + }, ac); + if ( null != childContext ) { + AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return childContext.getAccessibleRole(); + } + }, ac); + if ( AccessibleRole.LABEL == childRole ) { + childX = getAccessibleXcoordFromContext (childContext); + childY = getAccessibleYcoordFromContext (childContext); + childWidth = getAccessibleWidthFromContext (childContext); + childHeight = getAccessibleHeightFromContext (childContext); + if ( (childX < testX) && + ((childY <= targetY) && (targetY <= (childY + childHeight))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleName (); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleDescription (); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object."); + references.increment (childDescription); + return childDescription; + } + } else if ( (childY < targetY) && + ((childX <= targetX) && (targetX <= (childX + childWidth))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleName (); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleDescription (); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object."); + references.increment (childDescription); + return childDescription; + } + } + } + } + } + childIndex --; + } + childIndex = testIndex + 1; + while (childIndex <= testIndexMax) { + final int childIndexTemp = childIndex; + final AccessibleContext parentContextInnerTemp = parentContext; + final Accessible child = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return parentContextInnerTemp.getAccessibleChild(childIndexTemp); + } + }, ac); + if ( null != child ) { + final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return child.getAccessibleContext(); + } + }, ac); + if ( null != childContext ) { + AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return childContext.getAccessibleRole(); + } + }, ac); + if ( AccessibleRole.LABEL == childRole ) { + childX = getAccessibleXcoordFromContext (childContext); + childY = getAccessibleYcoordFromContext (childContext); + childWidth = getAccessibleWidthFromContext (childContext); + childHeight = getAccessibleHeightFromContext (childContext); + if ( (childX < testX) && + ((childY <= targetY) && (targetY <= (childY + childHeight))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleName (); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleDescription (); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object."); + references.increment (childDescription); + return childDescription; + } + } else if ( (childY < targetY) && + ((childX <= targetX) && (targetX <= (childX + childWidth))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleName (); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleDescription (); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object."); + references.increment (childDescription); + return childDescription; + } + } + } + } + } + childIndex ++; + } + /* + Step 8: + ======= + Special case for combo boxes and text objects, based on a + similar special case I found in some of our internal JAWS code. + + Search for a button object that is positioned either just to the left + or just above the object and get the Accessible Name of the button + object. + */ + if ( (AccessibleRole.TEXT == role) || + (AccessibleRole.COMBO_BOX == role) || + (bIsEditCombo) ) { + childIndex = testIndex - 1; + while (childIndex >= 0) { + final int childIndexTemp = childIndex; + final AccessibleContext parentContextInnerTemp = parentContext; + final Accessible child = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return parentContextInnerTemp.getAccessibleChild(childIndexTemp); + } + }, ac); + if ( null != child ) { + final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return child.getAccessibleContext(); + } + }, ac); + if ( null != childContext ) { + AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return childContext.getAccessibleRole(); + } + }, ac); + if ( ( AccessibleRole.PUSH_BUTTON == childRole ) || + ( AccessibleRole.TOGGLE_BUTTON == childRole )) { + childX = getAccessibleXcoordFromContext (childContext); + childY = getAccessibleYcoordFromContext (childContext); + childWidth = getAccessibleWidthFromContext (childContext); + childHeight = getAccessibleHeightFromContext (childContext); + if ( (childX < testX) && + ((childY <= targetY) && (targetY <= (childY + childHeight))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleName (); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleDescription (); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + references.increment (childDescription); + return childDescription; + } + } + } + } + } + childIndex --; + } + childIndex = testIndex + 1; + while (childIndex <= testIndexMax) { + final int childIndexTemp = childIndex; + final AccessibleContext parentContextInnerTemp = parentContext; + final Accessible child = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return parentContextInnerTemp.getAccessibleChild(childIndexTemp); + } + }, ac); + if ( null != child ) { + final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return child.getAccessibleContext(); + } + }, ac); + if ( null != childContext ) { + AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return childContext.getAccessibleRole(); + } + }, ac); + if ( ( AccessibleRole.PUSH_BUTTON == childRole ) || + ( AccessibleRole.TOGGLE_BUTTON == childRole ) ) { + childX = getAccessibleXcoordFromContext (childContext); + childY = getAccessibleYcoordFromContext (childContext); + childWidth = getAccessibleWidthFromContext (childContext); + childHeight = getAccessibleHeightFromContext (childContext); + if ( (childX < testX) && + ((childY <= targetY) && (targetY <= (childY + childHeight))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleName(); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + public String call() { + return childContext.getAccessibleDescription (); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + references.increment (childDescription); + return childDescription; + } + } + } + } + } + childIndex ++; + } + } + return null; + } else { + debugString ("AccessBridge::getVirtualAccessibleNameFromContext error - ac == null."); + return null; + } + } + + /** + * returns the AccessibleDescription from an AccessibleContext + */ + private String getAccessibleDescriptionFromContext(final AccessibleContext ac) { + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleDescription(); + } + }, ac); + if (s != null) { + references.increment(s); + debugString("Returning AccessibleDescription from Context: " + s); + return s; + } + } else { + debugString("getAccessibleDescriptionFromContext; ac = null"); + } + return null; + } + + /** + * returns the AccessibleRole from an AccessibleContext + */ + private String getAccessibleRoleStringFromContext(final AccessibleContext ac) { + if (ac != null) { + AccessibleRole role = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return ac.getAccessibleRole(); + } + }, ac); + if (role != null) { + String s = role.toDisplayString(Locale.US); + if (s != null) { + references.increment(s); + debugString("Returning AccessibleRole from Context: " + s); + return s; + } + } + } else { + debugString("getAccessibleRoleStringFromContext; ac = null"); + } + return null; + } + + /** + * return the AccessibleRole from an AccessibleContext in the en_US locale + */ + private String getAccessibleRoleStringFromContext_en_US(final AccessibleContext ac) { + return getAccessibleRoleStringFromContext(ac); + } + + /** + * return the AccessibleStates from an AccessibleContext + */ + private String getAccessibleStatesStringFromContext(final AccessibleContext ac) { + if (ac != null) { + AccessibleStateSet stateSet = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleStateSet call() throws Exception { + return ac.getAccessibleStateSet(); + } + }, ac); + if (stateSet != null) { + String s = stateSet.toString(); + if (s != null && + s.indexOf(AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US)) == -1) { + // Indicate whether this component manages its own + // children + AccessibleRole role = ac.getAccessibleRole(); + if (role == AccessibleRole.LIST || + role == AccessibleRole.TABLE || + role == AccessibleRole.TREE) { + s += ","; + s += AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US); + } + references.increment(s); + debugString("Returning AccessibleStateSet from Context: " + s); + return s; + } + } + } else { + debugString("getAccessibleStatesStringFromContext; ac = null"); + } + return null; + } + + /** + * returns the AccessibleStates from an AccessibleContext in the en_US locale + */ + private String getAccessibleStatesStringFromContext_en_US(final AccessibleContext ac) { + if (ac != null) { + AccessibleStateSet stateSet = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleStateSet call() throws Exception { + return ac.getAccessibleStateSet(); + } + }, ac); + if (stateSet != null) { + String s = ""; + AccessibleState[] states = stateSet.toArray(); + if (states != null && states.length > 0) { + s = states[0].toDisplayString(Locale.US); + for (int i = 1; i < states.length; i++) { + s = s + "," + states[i].toDisplayString(Locale.US); + } + } + references.increment(s); + debugString("Returning AccessibleStateSet en_US from Context: " + s); + return s; + } + } + debugString("getAccessibleStatesStringFromContext; ac = null"); + return null; + } + + /** + * returns the AccessibleParent from an AccessibleContext + */ + private AccessibleContext getAccessibleParentFromContext(final AccessibleContext ac) { + if (ac==null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = ac.getAccessibleParent(); + if (a != null) { + AccessibleContext apc = a.getAccessibleContext(); + if (apc != null) { + return apc; + } + } + return null; + } + }, ac); + } + + /** + * returns the AccessibleIndexInParent from an AccessibleContext + */ + private int getAccessibleIndexInParentFromContext(final AccessibleContext ac) { + if (ac==null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac.getAccessibleIndexInParent(); + } + }, ac); + } + + /** + * returns the AccessibleChild count from an AccessibleContext + */ + private int getAccessibleChildrenCountFromContext(final AccessibleContext ac) { + if (ac==null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac.getAccessibleChildrenCount(); + } + }, ac); + } + + /** + * returns the AccessibleChild Context from an AccessibleContext + */ + private AccessibleContext getAccessibleChildFromContext(final AccessibleContext ac, final int index) { + + if (ac == null) { + return null; + } + + final JTable table = InvocationUtils.invokeAndWait(new Callable() { + @Override + public JTable call() throws Exception { + // work-around for AccessibleJTable.getCurrentAccessibleContext returning + // wrong renderer component when cell contains more than one component + Accessible parent = ac.getAccessibleParent(); + if (parent != null) { + int indexInParent = ac.getAccessibleIndexInParent(); + Accessible child = + parent.getAccessibleContext().getAccessibleChild(indexInParent); + if (child instanceof JTable) { + return (JTable) child; + } + } + return null; + } + }, ac); + + if (table == null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = ac.getAccessibleChild(index); + if (a != null) { + return a.getAccessibleContext(); + } + return null; + } + }, ac); + } + + final AccessibleTable at = getAccessibleTableFromContext(ac); + + final int row = getAccessibleTableRow(at, index); + final int column = getAccessibleTableColumn(at, index); + + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + TableCellRenderer renderer = table.getCellRenderer(row, column); + if (renderer == null) { + Class columnClass = table.getColumnClass(column); + renderer = table.getDefaultRenderer(columnClass); + } + Component component = + renderer.getTableCellRendererComponent(table, table.getValueAt(row, column), + false, false, row, column); + if (component instanceof Accessible) { + return component.getAccessibleContext(); + } + return null; + } + }, ac); + } + + /** + * returns the AccessibleComponent bounds on screen from an AccessibleContext + */ + private Rectangle getAccessibleBoundsOnScreenFromContext(final AccessibleContext ac) { + if(ac==null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Rectangle call() throws Exception { + AccessibleComponent acmp = ac.getAccessibleComponent(); + if (acmp != null) { + Rectangle r = acmp.getBounds(); + if (r != null) { + try { + Point p = acmp.getLocationOnScreen(); + if (p != null) { + r.x = p.x; + r.y = p.y; + return r; + } + } catch (Exception e) { + return null; + } + } + } + return null; + } + }, ac); + } + + /** + * returns the AccessibleComponent x-coord from an AccessibleContext + */ + private int getAccessibleXcoordFromContext(AccessibleContext ac) { + if (ac != null) { + Rectangle r = getAccessibleBoundsOnScreenFromContext(ac); + if (r != null) { + debugString(" - Returning Accessible x coord from Context: " + r.x); + return r.x; + } + } else { + debugString("getAccessibleXcoordFromContext ac = null"); + } + return -1; + } + + /** + * returns the AccessibleComponent y-coord from an AccessibleContext + */ + private int getAccessibleYcoordFromContext(AccessibleContext ac) { + debugString("getAccessibleYcoordFromContext() called"); + if (ac != null) { + Rectangle r = getAccessibleBoundsOnScreenFromContext(ac); + if (r != null) { + return r.y; + } + } else { + debugString("getAccessibleYcoordFromContext; ac = null"); + } + return -1; + } + + /** + * returns the AccessibleComponent height from an AccessibleContext + */ + private int getAccessibleHeightFromContext(AccessibleContext ac) { + if (ac != null) { + Rectangle r = getAccessibleBoundsOnScreenFromContext(ac); + if (r != null) { + return r.height; + } + } else { + debugString("getAccessibleHeightFromContext; ac = null"); + } + return -1; + } + + /** + * returns the AccessibleComponent width from an AccessibleContext + */ + private int getAccessibleWidthFromContext(AccessibleContext ac) { + if (ac != null) { + Rectangle r = getAccessibleBoundsOnScreenFromContext(ac); + if (r != null) { + return r.width; + } + } else { + debugString("getAccessibleWidthFromContext; ac = null"); + } + return -1; + } + + + /** + * returns the AccessibleComponent from an AccessibleContext + */ + private AccessibleComponent getAccessibleComponentFromContext(AccessibleContext ac) { + if (ac != null) { + AccessibleComponent acmp = ac.getAccessibleComponent(); + if (acmp != null) { + debugString("Returning AccessibleComponent Context"); + return acmp; + } + } else { + debugString("getAccessibleComponentFromContext; ac = null"); + } + return null; + } + + /** + * returns the AccessibleAction from an AccessibleContext + */ + private AccessibleAction getAccessibleActionFromContext(final AccessibleContext ac) { + debugString("Returning AccessibleAction Context"); + return ac == null ? null : InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleAction call() throws Exception { + return ac.getAccessibleAction(); + } + }, ac); + } + + /** + * returns the AccessibleSelection from an AccessibleContext + */ + private AccessibleSelection getAccessibleSelectionFromContext(final AccessibleContext ac) { + return ac == null ? null : InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleSelection call() throws Exception { + return ac.getAccessibleSelection(); + } + }, ac); + } + + /** + * return the AccessibleText from an AccessibleContext + */ + private AccessibleText getAccessibleTextFromContext(final AccessibleContext ac) { + return ac == null ? null : InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleText call() throws Exception { + return ac.getAccessibleText(); + } + }, ac); + } + + /** + * return the AccessibleComponent from an AccessibleContext + */ + private AccessibleValue getAccessibleValueFromContext(final AccessibleContext ac) { + return ac == null ? null : InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleValue call() throws Exception { + return ac.getAccessibleValue(); + } + }, ac); + } + + /* ===== AccessibleText methods ===== */ + + /** + * returns the bounding rectangle for the text cursor + * XXX + */ + private Rectangle getCaretLocation(final AccessibleContext ac) { + debugString("getCaretLocation"); + if (ac==null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Rectangle call() throws Exception { + // workaround for JAAPI not returning cursor bounding rectangle + Rectangle r = null; + Accessible parent = ac.getAccessibleParent(); + if (parent instanceof Accessible) { + int indexInParent = ac.getAccessibleIndexInParent(); + Accessible child = + parent.getAccessibleContext().getAccessibleChild(indexInParent); + + if (child instanceof JTextComponent) { + JTextComponent text = (JTextComponent) child; + try { + r = text.modelToView(text.getCaretPosition()); + if (r != null) { + Point p = text.getLocationOnScreen(); + r.translate(p.x, p.y); + } + } catch (BadLocationException ble) { + } + } + } + return r; + } + }, ac); + } + + /** + * returns the x-coordinate for the text cursor rectangle + */ + private int getCaretLocationX(AccessibleContext ac) { + Rectangle r = getCaretLocation(ac); + if (r != null) { + return r.x; + } else { + return -1; + } + } + + /** + * returns the y-coordinate for the text cursor rectangle + */ + private int getCaretLocationY(AccessibleContext ac) { + Rectangle r = getCaretLocation(ac); + if (r != null) { + return r.y; + } else { + return -1; + } + } + + /** + * returns the height for the text cursor rectangle + */ + private int getCaretLocationHeight(AccessibleContext ac) { + Rectangle r = getCaretLocation(ac); + if (r != null) { + return r.height; + } else { + return -1; + } + } + + /** + * returns the width for the text cursor rectangle + */ + private int getCaretLocationWidth(AccessibleContext ac) { + Rectangle r = getCaretLocation(ac); + if (r != null) { + return r.width; + } else { + return -1; + } + } + + /** + * returns the character count from an AccessibleContext + */ + private int getAccessibleCharCountFromContext(final AccessibleContext ac) { + if (ac==null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + return at.getCharCount(); + } + return -1; + } + }, ac); + } + + /** + * returns the caret position from an AccessibleContext + */ + private int getAccessibleCaretPositionFromContext(final AccessibleContext ac) { + if (ac==null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + return at.getCaretPosition(); + } + return -1; + } + }, ac); + } + + /** + * Return the index at a specific point from an AccessibleContext + * Point(x, y) is in screen coordinates. + */ + private int getAccessibleIndexAtPointFromContext(final AccessibleContext ac, + final int x, final int y) { + debugString("getAccessibleIndexAtPointFromContext: x = "+x+"; y = "+y); + if (ac==null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + AccessibleComponent acomp = ac.getAccessibleComponent(); + if (at != null && acomp != null) { + // Convert x and y from screen coordinates to + // local coordinates. + try { + Point p = acomp.getLocationOnScreen(); + int x1, y1; + if (p != null) { + x1 = x - p.x; + if (x1 < 0) { + x1 = 0; + } + y1 = y - p.y; + if (y1 < 0) { + y1 = 0; + } + + Point newPoint = new Point(x1, y1); + int indexAtPoint = at.getIndexAtPoint(new Point(x1, y1)); + return indexAtPoint; + } + } catch (Exception e) { + } + } + return -1; + } + }, ac); + } + + /** + * return the letter at a specific point from an AccessibleContext + */ + private String getAccessibleLetterAtIndexFromContext(final AccessibleContext ac, final int index) { + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at == null) return null; + return at.getAtIndex(AccessibleText.CHARACTER, index); + } + }, ac); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getAccessibleLetterAtIndexFromContext; ac = null"); + } + return null; + } + + /** + * return the word at a specific point from an AccessibleContext + */ + private String getAccessibleWordAtIndexFromContext(final AccessibleContext ac, final int index) { + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at == null) return null; + return at.getAtIndex(AccessibleText.WORD, index); + } + }, ac); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getAccessibleWordAtIndexFromContext; ac = null"); + } + return null; + } + + /** + * return the sentence at a specific point from an AccessibleContext + */ + private String getAccessibleSentenceAtIndexFromContext(final AccessibleContext ac, final int index) { + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at == null) return null; + return at.getAtIndex(AccessibleText.SENTENCE, index); + } + }, ac); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getAccessibleSentenceAtIndexFromContext; ac = null"); + } + return null; + } + + /** + * return the text selection start from an AccessibleContext + */ + private int getAccessibleTextSelectionStartFromContext(final AccessibleContext ac) { + if (ac == null) return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + return at.getSelectionStart(); + } + return -1; + } + }, ac); + } + + /** + * return the text selection end from an AccessibleContext + */ + private int getAccessibleTextSelectionEndFromContext(final AccessibleContext ac) { + if (ac == null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + return at.getSelectionEnd(); + } + return -1; + } + }, ac); + } + + /** + * return the selected text from an AccessibleContext + */ + private String getAccessibleTextSelectedTextFromContext(final AccessibleContext ac) { + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at == null) return null; + return at.getSelectedText(); + } + }, ac); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getAccessibleTextSelectedTextFromContext; ac = null"); + } + return null; + } + + /** + * return the attribute string at a given index from an AccessibleContext + */ + private String getAccessibleAttributesAtIndexFromContext(final AccessibleContext ac, + final int index) { + if (ac == null) + return null; + AttributeSet as = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AttributeSet call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + return at.getCharacterAttribute(index); + } + return null; + } + }, ac); + String s = expandStyleConstants(as); + if (s != null) { + references.increment(s); + return s; + } + return null; + } + + /** + * Get line info: left index of line + * + * algorithm: cast back, doubling each time, + * 'till find line boundaries + * + * return -1 if we can't get the info (e.g. index or at passed in + * is bogus; etc.) + */ + private int getAccessibleTextLineLeftBoundsFromContext(final AccessibleContext ac, + final int index) { + if (ac == null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + int lineStart; + int offset; + Rectangle charRect; + Rectangle indexRect = at.getCharacterBounds(index); + int textLen = at.getCharCount(); + if (indexRect == null) { + return -1; + } + // find the start of the line + // + offset = 1; + lineStart = index - offset < 0 ? 0 : index - offset; + charRect = at.getCharacterBounds(lineStart); + // slouch behind beginning of line + while (charRect != null + && charRect.y >= indexRect.y + && lineStart > 0) { + offset = offset << 1; + lineStart = index - offset < 0 ? 0 : index - offset; + charRect = at.getCharacterBounds(lineStart); + } + if (lineStart == 0) { // special case: we're on the first line! + // we found it! + } else { + offset = offset >> 1; // know boundary within last expansion + // ground forward to beginning of line + while (offset > 0) { + charRect = at.getCharacterBounds(lineStart + offset); + if (charRect.y < indexRect.y) { // still before line + lineStart += offset; + } else { + // leave lineStart alone, it's close! + } + offset = offset >> 1; + } + // subtract one 'cause we're already too far... + lineStart += 1; + } + return lineStart; + } + return -1; + } + }, ac); + } + + /** + * Get line info: right index of line + * + * algorithm: cast back, doubling each time, + * 'till find line boundaries + * + * return -1 if we can't get the info (e.g. index or at passed in + * is bogus; etc.) + */ + private int getAccessibleTextLineRightBoundsFromContext(final AccessibleContext ac, final int index) { + if(ac == null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + int lineEnd; + int offset; + Rectangle charRect; + Rectangle indexRect = at.getCharacterBounds(index); + int textLen = at.getCharCount(); + if (indexRect == null) { + return -1; + } + // find the end of the line + // + offset = 1; + lineEnd = index + offset > textLen - 1 + ? textLen - 1 : index + offset; + charRect = at.getCharacterBounds(lineEnd); + // push past end of line + while (charRect != null && + charRect.y <= indexRect.y && + lineEnd < textLen - 1) { + offset = offset << 1; + lineEnd = index + offset > textLen - 1 + ? textLen - 1 : index + offset; + charRect = at.getCharacterBounds(lineEnd); + } + if (lineEnd == textLen - 1) { // special case: on the last line! + // we found it! + } else { + offset = offset >> 1; // know boundary within last expansion + // pull back to end of line + while (offset > 0) { + charRect = at.getCharacterBounds(lineEnd - offset); + if (charRect.y > indexRect.y) { // still beyond line + lineEnd -= offset; + } else { + // leave lineEnd alone, it's close! + } + offset = offset >> 1; + } + // subtract one 'cause we're already too far... + lineEnd -= 1; + } + return lineEnd; + } + return -1; + } + }, ac); + } + + /** + * Get a range of text; null if indicies are bogus + */ + private String getAccessibleTextRangeFromContext(final AccessibleContext ac, + final int start, final int end) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + if (ac != null) { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + // start - end is inclusive + if (start > end) { + return null; + } + if (end >= at.getCharCount()) { + return null; + } + StringBuffer buf = new StringBuffer(end - start + 1); + for (int i = start; i <= end; i++) { + buf.append(at.getAtIndex(AccessibleText.CHARACTER, i)); + } + return buf.toString(); + } + } + return null; + } + }, ac); + if (s != null) { + references.increment(s); + return s; + } else { + return null; + } + } + + /** + * return the AttributeSet object at a given index from an AccessibleContext + */ + private AttributeSet getAccessibleAttributeSetAtIndexFromContext(final AccessibleContext ac, + final int index) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AttributeSet call() throws Exception { + if (ac != null) { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + AttributeSet as = at.getCharacterAttribute(index); + if (as != null) { + AccessBridge.this.references.increment(as); + return as; + } + } + } + return null; + } + }, ac); + } + + + /** + * return the bounding rectangle at index from an AccessibleContext + */ + private Rectangle getAccessibleTextRectAtIndexFromContext(final AccessibleContext ac, + final int index) { + // want to do this in global coords, so need to combine w/ac global coords + Rectangle r = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Rectangle call() throws Exception { + // want to do this in global coords, so need to combine w/ac global coords + if (ac != null) { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + Rectangle rect = at.getCharacterBounds(index); + if (rect != null) { + String s = at.getAtIndex(AccessibleText.CHARACTER, index); + if (s != null && s.equals("\n")) { + rect.width = 0; + } + return rect; + } + } + } + return null; + } + }, ac); + Rectangle acRect = getAccessibleBoundsOnScreenFromContext(ac); + if (r != null && acRect != null) { + r.translate(acRect.x, acRect.y); + return r; + } + return null; + } + + /** + * return the AccessibleText character x-coord at index from an AccessibleContext + */ + private int getAccessibleXcoordTextRectAtIndexFromContext(AccessibleContext ac, int index) { + if (ac != null) { + Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index); + if (r != null) { + return r.x; + } + } else { + debugString("getAccessibleXcoordTextRectAtIndexFromContext; ac = null"); + } + return -1; + } + + /** + * return the AccessibleText character y-coord at index from an AccessibleContext + */ + private int getAccessibleYcoordTextRectAtIndexFromContext(AccessibleContext ac, int index) { + if (ac != null) { + Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index); + if (r != null) { + return r.y; + } + } else { + debugString("getAccessibleYcoordTextRectAtIndexFromContext; ac = null"); + } + return -1; + } + + /** + * return the AccessibleText character height at index from an AccessibleContext + */ + private int getAccessibleHeightTextRectAtIndexFromContext(AccessibleContext ac, int index) { + if (ac != null) { + Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index); + if (r != null) { + return r.height; + } + } else { + debugString("getAccessibleHeightTextRectAtIndexFromContext; ac = null"); + } + return -1; + } + + /** + * return the AccessibleText character width at index from an AccessibleContext + */ + private int getAccessibleWidthTextRectAtIndexFromContext(AccessibleContext ac, int index) { + if (ac != null) { + Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index); + if (r != null) { + return r.width; + } + } else { + debugString("getAccessibleWidthTextRectAtIndexFromContext; ac = null"); + } + return -1; + } + + /* ===== AttributeSet methods for AccessibleText ===== */ + + /** + * return the bold setting from an AttributeSet + */ + private boolean getBoldFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isBold(as); + } else { + debugString("getBoldFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the italic setting from an AttributeSet + */ + private boolean getItalicFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isItalic(as); + } else { + debugString("getItalicFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the underline setting from an AttributeSet + */ + private boolean getUnderlineFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isUnderline(as); + } else { + debugString("getUnderlineFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the strikethrough setting from an AttributeSet + */ + private boolean getStrikethroughFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isStrikeThrough(as); + } else { + debugString("getStrikethroughFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the superscript setting from an AttributeSet + */ + private boolean getSuperscriptFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isSuperscript(as); + } else { + debugString("getSuperscriptFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the subscript setting from an AttributeSet + */ + private boolean getSubscriptFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isSubscript(as); + } else { + debugString("getSubscriptFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the background color from an AttributeSet + */ + private String getBackgroundColorFromAttributeSet(AttributeSet as) { + if (as != null) { + String s = StyleConstants.getBackground(as).toString(); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getBackgroundColorFromAttributeSet; as = null"); + } + return null; + } + + /** + * return the foreground color from an AttributeSet + */ + private String getForegroundColorFromAttributeSet(AttributeSet as) { + if (as != null) { + String s = StyleConstants.getForeground(as).toString(); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getForegroundColorFromAttributeSet; as = null"); + } + return null; + } + + /** + * return the font family from an AttributeSet + */ + private String getFontFamilyFromAttributeSet(AttributeSet as) { + if (as != null) { + String s = StyleConstants.getFontFamily(as).toString(); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getFontFamilyFromAttributeSet; as = null"); + } + return null; + } + + /** + * return the font size from an AttributeSet + */ + private int getFontSizeFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getFontSize(as); + } else { + debugString("getFontSizeFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the alignment from an AttributeSet + */ + private int getAlignmentFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getAlignment(as); + } else { + debugString("getAlignmentFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the BiDi level from an AttributeSet + */ + private int getBidiLevelFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getBidiLevel(as); + } else { + debugString("getBidiLevelFromAttributeSet; as = null"); + } + return -1; + } + + + /** + * return the first line indent from an AttributeSet + */ + private float getFirstLineIndentFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getFirstLineIndent(as); + } else { + debugString("getFirstLineIndentFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the left indent from an AttributeSet + */ + private float getLeftIndentFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getLeftIndent(as); + } else { + debugString("getLeftIndentFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the right indent from an AttributeSet + */ + private float getRightIndentFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getRightIndent(as); + } else { + debugString("getRightIndentFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the line spacing from an AttributeSet + */ + private float getLineSpacingFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getLineSpacing(as); + } else { + debugString("getLineSpacingFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the space above from an AttributeSet + */ + private float getSpaceAboveFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getSpaceAbove(as); + } else { + debugString("getSpaceAboveFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the space below from an AttributeSet + */ + private float getSpaceBelowFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getSpaceBelow(as); + } else { + debugString("getSpaceBelowFromAttributeSet; as = null"); + } + return -1; + } + + /** + * Enumerate all StyleConstants in the AttributeSet + * + * We need to check explicitly, 'cause of the HTML package conversion + * mechanism (they may not be stored as StyleConstants, just translated + * to them when asked). + * + * (Use convenience methods where they are defined...) + * + * Not checking the following (which the IBM SNS guidelines says + * should be defined): + * - ComponentElementName + * - IconElementName + * - NameAttribute + * - ResolveAttribute + */ + private String expandStyleConstants(AttributeSet as) { + Color c; + Object o; + String attrString = ""; + + // ---------- check for various Character Constants + + attrString += "BidiLevel = " + StyleConstants.getBidiLevel(as); + + final Component comp = StyleConstants.getComponent(as); + if (comp != null) { + if (comp instanceof Accessible) { + final AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return comp.getAccessibleContext(); + } + }, comp); + if (ac != null) { + attrString += "; Accessible Component = " + InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleName(); + } + }, ac); + } else { + attrString += "; Innaccessible Component = " + comp; + } + } else { + attrString += "; Innaccessible Component = " + comp; + } + } + + Icon i = StyleConstants.getIcon(as); + if (i != null) { + if (i instanceof ImageIcon) { + attrString += "; ImageIcon = " + ((ImageIcon) i).getDescription(); + } else { + attrString += "; Icon = " + i; + } + } + + attrString += "; FontFamily = " + StyleConstants.getFontFamily(as); + + attrString += "; FontSize = " + StyleConstants.getFontSize(as); + + if (StyleConstants.isBold(as)) { + attrString += "; bold"; + } + + if (StyleConstants.isItalic(as)) { + attrString += "; italic"; + } + + if (StyleConstants.isUnderline(as)) { + attrString += "; underline"; + } + + if (StyleConstants.isStrikeThrough(as)) { + attrString += "; strikethrough"; + } + + if (StyleConstants.isSuperscript(as)) { + attrString += "; superscript"; + } + + if (StyleConstants.isSubscript(as)) { + attrString += "; subscript"; + } + + c = StyleConstants.getForeground(as); + if (c != null) { + attrString += "; Foreground = " + c; + } + + c = StyleConstants.getBackground(as); + if (c != null) { + attrString += "; Background = " + c; + } + + attrString += "; FirstLineIndent = " + StyleConstants.getFirstLineIndent(as); + + attrString += "; RightIndent = " + StyleConstants.getRightIndent(as); + + attrString += "; LeftIndent = " + StyleConstants.getLeftIndent(as); + + attrString += "; LineSpacing = " + StyleConstants.getLineSpacing(as); + + attrString += "; SpaceAbove = " + StyleConstants.getSpaceAbove(as); + + attrString += "; SpaceBelow = " + StyleConstants.getSpaceBelow(as); + + attrString += "; Alignment = " + StyleConstants.getAlignment(as); + + TabSet ts = StyleConstants.getTabSet(as); + if (ts != null) { + attrString += "; TabSet = " + ts; + } + + return attrString; + } + + + /* ===== AccessibleValue methods ===== */ + + /** + * return the AccessibleValue current value from an AccessibleContext + * returned using a String 'cause the value is a java Number + * + */ + private String getCurrentAccessibleValueFromContext(final AccessibleContext ac) { + if (ac != null) { + final Number value = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Number call() throws Exception { + AccessibleValue av = ac.getAccessibleValue(); + if (av == null) return null; + return av.getCurrentAccessibleValue(); + } + }, ac); + if (value != null) { + String s = value.toString(); + if (s != null) { + references.increment(s); + return s; + } + } + } else { + debugString("getCurrentAccessibleValueFromContext; ac = null"); + } + return null; + } + + /** + * return the AccessibleValue maximum value from an AccessibleContext + * returned using a String 'cause the value is a java Number + * + */ + private String getMaximumAccessibleValueFromContext(final AccessibleContext ac) { + if (ac != null) { + final Number value = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Number call() throws Exception { + AccessibleValue av = ac.getAccessibleValue(); + if (av == null) return null; + return av.getMaximumAccessibleValue(); + } + }, ac); + if (value != null) { + String s = value.toString(); + if (s != null) { + references.increment(s); + return s; + } + } + } else { + debugString("getMaximumAccessibleValueFromContext; ac = null"); + } + return null; + } + + /** + * return the AccessibleValue minimum value from an AccessibleContext + * returned using a String 'cause the value is a java Number + * + */ + private String getMinimumAccessibleValueFromContext(final AccessibleContext ac) { + if (ac != null) { + final Number value = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Number call() throws Exception { + AccessibleValue av = ac.getAccessibleValue(); + if (av == null) return null; + return av.getMinimumAccessibleValue(); + } + }, ac); + if (value != null) { + String s = value.toString(); + if (s != null) { + references.increment(s); + return s; + } + } + } else { + debugString("getMinimumAccessibleValueFromContext; ac = null"); + } + return null; + } + + + /* ===== AccessibleSelection methods ===== */ + + /** + * add to the AccessibleSelection of an AccessibleContext child i + * + */ + private void addAccessibleSelectionFromContext(final AccessibleContext ac, final int i) { + try { + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Object call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + as.addAccessibleSelection(i); + } + } + return null; + } + }, ac); + } catch(Exception e){} + } + + /** + * clear all of the AccessibleSelection of an AccessibleContex + * + */ + private void clearAccessibleSelectionFromContext(final AccessibleContext ac) { + try { + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Object call() throws Exception { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + as.clearAccessibleSelection(); + } + return null; + } + }, ac); + } catch(Exception e){} + + } + + /** + * get the AccessibleContext of the i-th AccessibleSelection of an AccessibleContext + * + */ + private AccessibleContext getAccessibleSelectionFromContext(final AccessibleContext ac, final int i) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + Accessible a = as.getAccessibleSelection(i); + if (a == null) + return null; + else + return a.getAccessibleContext(); + } + } + return null; + } + }, ac); + } + + /** + * get number of things selected in the AccessibleSelection of an AccessibleContext + * + */ + private int getAccessibleSelectionCountFromContext(final AccessibleContext ac) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + return as.getAccessibleSelectionCount(); + } + } + return -1; + } + }, ac); + } + + /** + * return true if the i-th child of the AccessibleSelection of an AccessibleContext is selected + * + */ + private boolean isAccessibleChildSelectedFromContext(final AccessibleContext ac, final int i) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + return as.isAccessibleChildSelected(i); + } + } + return false; + } + }, ac); + } + + /** + * remove the i-th child from the AccessibleSelection of an AccessibleContext + * + */ + private void removeAccessibleSelectionFromContext(final AccessibleContext ac, final int i) { + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Object call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + as.removeAccessibleSelection(i); + } + } + return null; + } + }, ac); + } + + /** + * select all (if possible) of the children of the AccessibleSelection of an AccessibleContext + * + */ + private void selectAllAccessibleSelectionFromContext(final AccessibleContext ac) { + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Object call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + as.selectAllAccessibleSelection(); + } + } + return null; + } + }, ac); + } + + // ======== AccessibleTable ======== + + ConcurrentHashMap hashtab = new ConcurrentHashMap<>(); + + /** + * returns the AccessibleTable for an AccessibleContext + */ + private AccessibleTable getAccessibleTableFromContext(final AccessibleContext ac) { + String version = getJavaVersionProperty(); + if ((version != null && version.compareTo("1.3") >= 0)) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleTable call() throws Exception { + if (ac != null) { + AccessibleTable at = ac.getAccessibleTable(); + if (at != null) { + AccessBridge.this.hashtab.put(at, ac); + return at; + } + } + return null; + } + }, ac); + } + return null; + } + + + /* + * returns the AccessibleContext that contains an AccessibleTable + */ + private AccessibleContext getContextFromAccessibleTable(AccessibleTable at) { + return hashtab.get(at); + } + + /* + * returns the row count for an AccessibleTable + */ + private int getAccessibleTableRowCount(final AccessibleContext ac) { + debugString("##### getAccessibleTableRowCount"); + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (ac != null) { + AccessibleTable at = ac.getAccessibleTable(); + if (at != null) { + return at.getAccessibleRowCount(); + } + } + return -1; + } + }, ac); + } + + /* + * returns the column count for an AccessibleTable + */ + private int getAccessibleTableColumnCount(final AccessibleContext ac) { + debugString("##### getAccessibleTableColumnCount"); + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (ac != null) { + AccessibleTable at = ac.getAccessibleTable(); + if (at != null) { + return at.getAccessibleColumnCount(); + } + } + return -1; + } + }, ac); + } + + /* + * returns the AccessibleContext for an AccessibleTable cell + */ + private AccessibleContext getAccessibleTableCellAccessibleContext(final AccessibleTable at, + final int row, final int column) { + debugString("getAccessibleTableCellAccessibleContext: at = "+at.getClass()); + if (at == null) return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + if (!(at instanceof AccessibleContext)) { + Accessible a = at.getAccessibleAt(row, column); + if (a != null) { + return a.getAccessibleContext(); + } + } else { + // work-around for AccessibleJTable.getCurrentAccessibleContext returning + // wrong renderer component when cell contains more than one component + AccessibleContext ac = (AccessibleContext) at; + Accessible parent = ac.getAccessibleParent(); + if (parent != null) { + int indexInParent = ac.getAccessibleIndexInParent(); + Accessible child = + parent.getAccessibleContext().getAccessibleChild(indexInParent); + if (child instanceof JTable) { + JTable table = (JTable) child; + + TableCellRenderer renderer = table.getCellRenderer(row, column); + if (renderer == null) { + Class columnClass = table.getColumnClass(column); + renderer = table.getDefaultRenderer(columnClass); + } + Component component = + renderer.getTableCellRendererComponent(table, table.getValueAt(row, column), + false, false, row, column); + if (component instanceof Accessible) { + return component.getAccessibleContext(); + } + } + } + } + return null; + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns the index of a cell at a given row and column in an AccessibleTable + */ + private int getAccessibleTableCellIndex(final AccessibleTable at, int row, int column) { + debugString("##### getAccessibleTableCellIndex: at="+at); + if (at != null) { + int cellIndex = row * + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleColumnCount(); + } + }, getContextFromAccessibleTable(at)) + + column; + debugString(" ##### getAccessibleTableCellIndex="+cellIndex); + return cellIndex; + } + debugString(" ##### getAccessibleTableCellIndex FAILED"); + return -1; + } + + /* + * returns the row extent of a cell at a given row and column in an AccessibleTable + */ + private int getAccessibleTableCellRowExtent(final AccessibleTable at, final int row, final int column) { + debugString("##### getAccessibleTableCellRowExtent"); + if (at != null) { + int rowExtent = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleRowExtentAt(row, column); + } + }, + getContextFromAccessibleTable(at)); + debugString(" ##### getAccessibleTableCellRowExtent="+rowExtent); + return rowExtent; + } + debugString(" ##### getAccessibleTableCellRowExtent FAILED"); + return -1; + } + + /* + * returns the column extent of a cell at a given row and column in an AccessibleTable + */ + private int getAccessibleTableCellColumnExtent(final AccessibleTable at, final int row, final int column) { + debugString("##### getAccessibleTableCellColumnExtent"); + if (at != null) { + int columnExtent = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleColumnExtentAt(row, column); + } + }, + getContextFromAccessibleTable(at)); + debugString(" ##### getAccessibleTableCellColumnExtent="+columnExtent); + return columnExtent; + } + debugString(" ##### getAccessibleTableCellColumnExtent FAILED"); + return -1; + } + + /* + * returns whether a cell is selected at a given row and column in an AccessibleTable + */ + private boolean isAccessibleTableCellSelected(final AccessibleTable at, final int row, + final int column) { + debugString("##### isAccessibleTableCellSelected: ["+row+"]["+column+"]"); + if (at == null) + return false; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + boolean isSelected = false; + Accessible a = at.getAccessibleAt(row, column); + if (a != null) { + AccessibleContext ac = a.getAccessibleContext(); + if (ac == null) + return false; + AccessibleStateSet as = ac.getAccessibleStateSet(); + if (as != null) { + isSelected = as.contains(AccessibleState.SELECTED); + } + } + return isSelected; + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns an AccessibleTable that represents the row header in an + * AccessibleTable + */ + private AccessibleTable getAccessibleTableRowHeader(final AccessibleContext ac) { + debugString(" ##### getAccessibleTableRowHeader called"); + AccessibleTable at = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleTable call() throws Exception { + if (ac != null) { + AccessibleTable at = ac.getAccessibleTable(); + if (at != null) { + return at.getAccessibleRowHeader(); + } + } + return null; + } + }, ac); + if (at != null) { + hashtab.put(at, ac); + } + return at; + } + + /* + * returns an AccessibleTable that represents the column header in an + * AccessibleTable + */ + private AccessibleTable getAccessibleTableColumnHeader(final AccessibleContext ac) { + debugString("##### getAccessibleTableColumnHeader"); + if (ac == null) + return null; + AccessibleTable at = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleTable call() throws Exception { + // workaround for getAccessibleColumnHeader NPE + // when the table header is null + Accessible parent = ac.getAccessibleParent(); + if (parent != null) { + int indexInParent = ac.getAccessibleIndexInParent(); + Accessible child = + parent.getAccessibleContext().getAccessibleChild(indexInParent); + if (child instanceof JTable) { + JTable table = (JTable) child; + if (table.getTableHeader() == null) { + return null; + } + } + } + AccessibleTable at = ac.getAccessibleTable(); + if (at != null) { + return at.getAccessibleColumnHeader(); + } + return null; + } + }, ac); + if (at != null) { + hashtab.put(at, ac); + } + return at; + } + + /* + * returns the number of row headers in an AccessibleTable that represents + * the row header in an AccessibleTable + */ + private int getAccessibleTableRowHeaderRowCount(AccessibleContext ac) { + + debugString(" ##### getAccessibleTableRowHeaderRowCount called"); + if (ac != null) { + final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac); + if (atRowHeader != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (atRowHeader != null) { + return atRowHeader.getAccessibleRowCount(); + } + return -1; + } + }, ac); + } + } + return -1; + } + + /* + * returns the number of column headers in an AccessibleTable that represents + * the row header in an AccessibleTable + */ + private int getAccessibleTableRowHeaderColumnCount(AccessibleContext ac) { + debugString(" ##### getAccessibleTableRowHeaderColumnCount called"); + if (ac != null) { + final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac); + if (atRowHeader != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (atRowHeader != null) { + return atRowHeader.getAccessibleColumnCount(); + } + return -1; + } + }, ac); + } + } + debugString(" ##### getAccessibleTableRowHeaderColumnCount FAILED"); + return -1; + } + + /* + * returns the number of row headers in an AccessibleTable that represents + * the column header in an AccessibleTable + */ + private int getAccessibleTableColumnHeaderRowCount(AccessibleContext ac) { + + debugString("##### getAccessibleTableColumnHeaderRowCount"); + if (ac != null) { + final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac); + if (atColumnHeader != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (atColumnHeader != null) { + return atColumnHeader.getAccessibleRowCount(); + } + return -1; + } + }, ac); + } + } + debugString(" ##### getAccessibleTableColumnHeaderRowCount FAILED"); + return -1; + } + + /* + * returns the number of column headers in an AccessibleTable that represents + * the column header in an AccessibleTable + */ + private int getAccessibleTableColumnHeaderColumnCount(AccessibleContext ac) { + + debugString("##### getAccessibleTableColumnHeaderColumnCount"); + if (ac != null) { + final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac); + if (atColumnHeader != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (atColumnHeader != null) { + return atColumnHeader.getAccessibleColumnCount(); + } + return -1; + } + }, ac); + } + } + debugString(" ##### getAccessibleTableColumnHeaderColumnCount FAILED"); + return -1; + } + + /* + * returns the description of a row header in an AccessibleTable + */ + private AccessibleContext getAccessibleTableRowDescription(final AccessibleTable table, + final int row) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + if (table != null) { + Accessible a = table.getAccessibleRowDescription(row); + if (a != null) { + return a.getAccessibleContext(); + } + } + return null; + } + }, getContextFromAccessibleTable(table)); + } + + /* + * returns the description of a column header in an AccessibleTable + */ + private AccessibleContext getAccessibleTableColumnDescription(final AccessibleTable at, + final int column) { + if (at == null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = at.getAccessibleColumnDescription(column); + if (a != null) { + return a.getAccessibleContext(); + } + return null; + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns the number of rows selected in an AccessibleTable + */ + private int getAccessibleTableRowSelectionCount(final AccessibleTable at) { + if (at != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + int[] selections = at.getSelectedAccessibleRows(); + if (selections != null) + return selections.length; + else + return -1; + } + }, getContextFromAccessibleTable(at)); + } + return -1; + } + + /* + * returns the row number of the i-th selected row in an AccessibleTable + */ + private int getAccessibleTableRowSelections(final AccessibleTable at, final int i) { + if (at != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + int[] selections = at.getSelectedAccessibleRows(); + if (selections.length > i) { + return selections[i]; + } + return -1; + } + }, getContextFromAccessibleTable(at)); + } + return -1; + } + + /* + * returns whether a row is selected in an AccessibleTable + */ + private boolean isAccessibleTableRowSelected(final AccessibleTable at, + final int row) { + if (at == null) + return false; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + return at.isAccessibleRowSelected(row); + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns whether a column is selected in an AccessibleTable + */ + private boolean isAccessibleTableColumnSelected(final AccessibleTable at, + final int column) { + if (at == null) + return false; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + return at.isAccessibleColumnSelected(column); + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns the number of columns selected in an AccessibleTable + */ + private int getAccessibleTableColumnSelectionCount(final AccessibleTable at) { + if (at == null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + int[] selections = at.getSelectedAccessibleColumns(); + if (selections != null) + return selections.length; + else + return -1; + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns the row number of the i-th selected row in an AccessibleTable + */ + private int getAccessibleTableColumnSelections(final AccessibleTable at, final int i) { + if (at == null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + int[] selections = at.getSelectedAccessibleColumns(); + if (selections != null && selections.length > i) { + return selections[i]; + } + return -1; + } + }, getContextFromAccessibleTable(at)); + } + + /* ===== AccessibleExtendedTable (since 1.4) ===== */ + + /* + * returns the row number for a cell at a given index in an AccessibleTable + */ + private int getAccessibleTableRow(final AccessibleTable at, int index) { + if (at == null) + return -1; + int colCount=InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleColumnCount(); + } + }, getContextFromAccessibleTable(at)); + return index / colCount; + } + + /* + * returns the column number for a cell at a given index in an AccessibleTable + */ + private int getAccessibleTableColumn(final AccessibleTable at, int index) { + if (at == null) + return -1; + int colCount=InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleColumnCount(); + } + }, getContextFromAccessibleTable(at)); + return index % colCount; + } + + /* + * returns the index for a cell at a given row and column in an + * AccessibleTable + */ + private int getAccessibleTableIndex(final AccessibleTable at, int row, int column) { + if (at == null) + return -1; + int colCount = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleColumnCount(); + } + }, getContextFromAccessibleTable(at)); + return row * colCount + column; + } + + // ===== AccessibleRelationSet ===== + + /* + * returns the number of relations in the AccessibleContext's + * AccessibleRelationSet + */ + private int getAccessibleRelationCount(final AccessibleContext ac) { + String version = getJavaVersionProperty(); + if ((version != null && version.compareTo("1.3") >= 0)) { + if (ac != null) { + AccessibleRelationSet ars = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRelationSet call() throws Exception { + return ac.getAccessibleRelationSet(); + } + }, ac); + if (ars != null) + return ars.size(); + } + } + return 0; + } + + /* + * returns the ith relation key in the AccessibleContext's + * AccessibleRelationSet + */ + private String getAccessibleRelationKey(final AccessibleContext ac, final int i) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + if (ac != null) { + AccessibleRelationSet ars = ac.getAccessibleRelationSet(); + if (ars != null) { + AccessibleRelation[] relations = ars.toArray(); + if (relations != null && i >= 0 && i < relations.length) { + return relations[i].getKey(); + } + } + } + return null; + } + }, ac); + } + + /* + * returns the number of targets in a relation in the AccessibleContext's + * AccessibleRelationSet + */ + private int getAccessibleRelationTargetCount(final AccessibleContext ac, final int i) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (ac != null) { + AccessibleRelationSet ars = ac.getAccessibleRelationSet(); + if (ars != null) { + AccessibleRelation[] relations = ars.toArray(); + if (relations != null && i >= 0 && i < relations.length) { + Object[] targets = relations[i].getTarget(); + return targets.length; + } + } + } + return -1; + } + }, ac); + } + + /* + * returns the jth target in the ith relation in the AccessibleContext's + * AccessibleRelationSet + */ + private AccessibleContext getAccessibleRelationTarget(final AccessibleContext ac, + final int i, final int j) { + debugString("***** getAccessibleRelationTarget"); + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + if (ac != null) { + AccessibleRelationSet ars = ac.getAccessibleRelationSet(); + if (ars != null) { + AccessibleRelation[] relations = ars.toArray(); + if (relations != null && i >= 0 && i < relations.length) { + Object[] targets = relations[i].getTarget(); + if (targets != null && j >= 0 & j < targets.length) { + Object o = targets[j]; + if (o instanceof Accessible) { + return ((Accessible) o).getAccessibleContext(); + } + } + } + } + } + return null; + } + }, ac); + } + + // ========= AccessibleHypertext ========= + + private Map hyperTextContextMap = new WeakHashMap<>(); + private Map hyperLinkContextMap = new WeakHashMap<>(); + + /* + * Returns the AccessibleHypertext + */ + private AccessibleHypertext getAccessibleHypertext(final AccessibleContext ac) { + debugString("getAccessibleHyperlink"); + if (ac==null) + return null; + AccessibleHypertext hypertext = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleHypertext call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (!(at instanceof AccessibleHypertext)) { + return null; + } + return ((AccessibleHypertext) at); + } + }, ac); + hyperTextContextMap.put(hypertext, ac); + return hypertext; + } + + /* + * Returns the number of AccessibleHyperlinks + */ + private int getAccessibleHyperlinkCount(AccessibleContext ac) { + debugString("getAccessibleHyperlinkCount"); + if (ac == null) { + return 0; + } + final AccessibleHypertext hypertext = getAccessibleHypertext(ac); + if (hypertext == null) { + return 0; + } + //return hypertext.getLinkCount(); + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return hypertext.getLinkCount(); + } + }, ac); + } + + /* + * Returns the hyperlink at the specified index + */ + private AccessibleHyperlink getAccessibleHyperlink(final AccessibleHypertext hypertext, final int i) { + debugString("getAccessibleHyperlink"); + if (hypertext == null) { + return null; + } + AccessibleContext ac = hyperTextContextMap.get(hypertext); + if ( i < 0 || i >= + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return hypertext.getLinkCount(); + } + }, ac) ) { + return null; + } + AccessibleHyperlink acLink = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleHyperlink call() throws Exception { + AccessibleHyperlink link = hypertext.getLink(i); + if (link == null || (!link.isValid())) { + return null; + } + return link; + } + }, ac); + hyperLinkContextMap.put(acLink, ac); + return acLink; + } + + /* + * Returns the hyperlink object description + */ + private String getAccessibleHyperlinkText(final AccessibleHyperlink link) { + debugString("getAccessibleHyperlinkText"); + if (link == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + Object o = link.getAccessibleActionDescription(0); + if (o != null) { + return o.toString(); + } + return null; + } + }, hyperLinkContextMap.get(link)); + } + + /* + * Returns the hyperlink URL + */ + private String getAccessibleHyperlinkURL(final AccessibleHyperlink link) { + debugString("getAccessibleHyperlinkURL"); + if (link == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + Object o = link.getAccessibleActionObject(0); + if (o != null) { + return o.toString(); + } else { + return null; + } + } + }, hyperLinkContextMap.get(link)); + } + + /* + * Returns the start index of the hyperlink text + */ + private int getAccessibleHyperlinkStartIndex(final AccessibleHyperlink link) { + debugString("getAccessibleHyperlinkStartIndex"); + if (link == null) { + return -1; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return link.getStartIndex(); + } + }, hyperLinkContextMap.get(link)); + } + + /* + * Returns the end index of the hyperlink text + */ + private int getAccessibleHyperlinkEndIndex(final AccessibleHyperlink link) { + debugString("getAccessibleHyperlinkEndIndex"); + if (link == null) { + return -1; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return link.getEndIndex(); + } + }, hyperLinkContextMap.get(link)); + } + + /* + * Returns the index into an array of hyperlinks that + * is associated with this character index, or -1 if there + * is no hyperlink associated with this index. + */ + private int getAccessibleHypertextLinkIndex(final AccessibleHypertext hypertext, final int charIndex) { + debugString("getAccessibleHypertextLinkIndex: charIndex = "+charIndex); + if (hypertext == null) { + return -1; + } + int linkIndex = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return hypertext.getLinkIndex(charIndex); + } + }, hyperTextContextMap.get(hypertext)); + debugString("getAccessibleHypertextLinkIndex returning "+linkIndex); + return linkIndex; + } + + /* + * Actives the hyperlink + */ + private boolean activateAccessibleHyperlink(final AccessibleContext ac, + final AccessibleHyperlink link) { + //debugString("activateAccessibleHyperlink: link = "+link.getClass()); + if (link == null) { + return false; + } + boolean retval = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + return link.doAccessibleAction(0); + } + }, ac); + debugString("activateAccessibleHyperlink: returning = "+retval); + return retval; + } + + + // ============ AccessibleKeyBinding ============= + + /* + * returns the component mnemonic + */ + private KeyStroke getMnemonic(final AccessibleContext ac) { + if (ac == null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public KeyStroke call() throws Exception { + AccessibleComponent comp = ac.getAccessibleComponent(); + if (!(comp instanceof AccessibleExtendedComponent)) { + return null; + } + AccessibleExtendedComponent aec = (AccessibleExtendedComponent) comp; + if (aec != null) { + AccessibleKeyBinding akb = aec.getAccessibleKeyBinding(); + if (akb != null) { + Object o = akb.getAccessibleKeyBinding(0); + if (o instanceof KeyStroke) { + return (KeyStroke) o; + } + } + } + return null; + } + }, ac); + } + + /* + * returns the JMenuItem accelerator + */ + private KeyStroke getAccelerator(final AccessibleContext ac) { + // workaround for getAccessibleKeyBinding not returning the + // JMenuItem accelerator + if (ac == null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public KeyStroke call() throws Exception { + Accessible parent = ac.getAccessibleParent(); + if (parent instanceof Accessible) { + int indexInParent = ac.getAccessibleIndexInParent(); + Accessible child = + parent.getAccessibleContext().getAccessibleChild(indexInParent); + if (child instanceof JMenuItem) { + JMenuItem menuItem = (JMenuItem) child; + if (menuItem == null) + return null; + KeyStroke keyStroke = menuItem.getAccelerator(); + return keyStroke; + } + } + return null; + } + }, ac); + } + + /* + * returns 1-24 to indicate which F key is being used for a shortcut or 0 otherwise + */ + private int fKeyNumber(KeyStroke keyStroke) { + if (keyStroke == null) + return 0; + int fKey = 0; + String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode()); + if (keyText != null && (keyText.length() == 2 || keyText.length() == 3)) { + String prefix = keyText.substring(0, 1); + if (prefix.equals("F")) { + try { + int suffix = Integer.parseInt(keyText.substring(1)); + if (suffix >= 1 && suffix <= 24) { + fKey = suffix; + } + } catch (Exception e) { // ignore NumberFormatException + } + } + } + return fKey; + } + + /* + * returns one of several important control characters or 0 otherwise + */ + private int controlCode(KeyStroke keyStroke) { + if (keyStroke == null) + return 0; + int code = keyStroke.getKeyCode(); + switch (code) { + case KeyEvent.VK_BACK_SPACE: + case KeyEvent.VK_DELETE: + case KeyEvent.VK_DOWN: + case KeyEvent.VK_END: + case KeyEvent.VK_HOME: + case KeyEvent.VK_INSERT: + case KeyEvent.VK_KP_DOWN: + case KeyEvent.VK_KP_LEFT: + case KeyEvent.VK_KP_RIGHT: + case KeyEvent.VK_KP_UP: + case KeyEvent.VK_LEFT: + case KeyEvent.VK_PAGE_DOWN: + case KeyEvent.VK_PAGE_UP: + case KeyEvent.VK_RIGHT: + case KeyEvent.VK_UP: + break; + default: + code = 0; + break; + } + return code; + } + + /* + * returns the KeyStoke character + */ + private char getKeyChar(KeyStroke keyStroke) { + // If the shortcut is an FKey return 1-24 + if (keyStroke == null) + return 0; + int fKey = fKeyNumber(keyStroke); + if (fKey != 0) { + // return 0x00000001 through 0x00000018 + debugString(" Shortcut is: F" + fKey); + return (char)fKey; + } + // If the accelerator is a control character, return it + int keyCode = controlCode(keyStroke); + if (keyCode != 0) { + debugString(" Shortcut is control character: " + Integer.toHexString(keyCode)); + return (char)keyCode; + } + String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode()); + debugString(" Shortcut is: " + keyText); + if (keyText != null || keyText.length() > 0) { + CharSequence seq = keyText.subSequence(0, 1); + if (seq != null || seq.length() > 0) { + return seq.charAt(0); + } + } + return 0; + } + + /* + * returns the KeyStroke modifiers as an int + */ + private int getModifiers(KeyStroke keyStroke) { + if (keyStroke == null) + return 0; + debugString("In AccessBridge.getModifiers"); + // modifiers is a bit strip where bits 0-7 indicate a traditional modifier + // such as Ctrl/Alt/Shift, bit 8 indicates an F key shortcut, and bit 9 indicates + // a control code shortcut such as the delete key. + + int modifiers = 0; + // Is the shortcut an FKey? + if (fKeyNumber(keyStroke) != 0) { + modifiers |= 1 << 8; + } + // Is the shortcut a control code? + if (controlCode(keyStroke) != 0) { + modifiers |= 1 << 9; + } + // The following is needed in order to handle translated modifiers. + // getKeyModifiersText doesn't work because for example in German Strg is + // returned for Ctrl. + + // There can be more than one modifier, e.g. if the modifier is ctrl + shift + B + // the toString text is "shift ctrl pressed B". Need to parse through that. + StringTokenizer st = new StringTokenizer(keyStroke.toString()); + while (st.hasMoreTokens()) { + String text = st.nextToken(); + // Meta+Ctrl+Alt+Shift + // 0-3 are shift, ctrl, meta, alt + // 4-7 are for Solaris workstations (though not being used) + if (text.startsWith("met")) { + debugString(" found meta"); + modifiers |= ActionEvent.META_MASK; + } + if (text.startsWith("ctr")) { + debugString(" found ctrl"); + modifiers |= ActionEvent.CTRL_MASK; + } + if (text.startsWith("alt")) { + debugString(" found alt"); + modifiers |= ActionEvent.ALT_MASK; + } + if (text.startsWith("shi")) { + debugString(" found shift"); + modifiers |= ActionEvent.SHIFT_MASK; + } + } + debugString(" returning modifiers: 0x" + Integer.toHexString(modifiers)); + return modifiers; + } + + /* + * returns the number of key bindings associated with this context + */ + private int getAccessibleKeyBindingsCount(AccessibleContext ac) { + if (ac == null || (! runningOnJDK1_4) ) + return 0; + int count = 0; + + if (getMnemonic(ac) != null) { + count++; + } + if (getAccelerator(ac) != null) { + count++; + } + return count; + } + + /* + * returns the key binding character at the specified index + */ + private char getAccessibleKeyBindingChar(AccessibleContext ac, int index) { + if (ac == null || (! runningOnJDK1_4) ) + return 0; + if((index == 0) && getMnemonic(ac)==null) {// special case when there is no mnemonic + KeyStroke keyStroke = getAccelerator(ac); + if (keyStroke != null) { + return getKeyChar(keyStroke); + } + } + if (index == 0) { // mnemonic + KeyStroke keyStroke = getMnemonic(ac); + if (keyStroke != null) { + return getKeyChar(keyStroke); + } + } else if (index == 1) { // accelerator + KeyStroke keyStroke = getAccelerator(ac); + if (keyStroke != null) { + return getKeyChar(keyStroke); + } + } + return 0; + } + + /* + * returns the key binding modifiers at the specified index + */ + private int getAccessibleKeyBindingModifiers(AccessibleContext ac, int index) { + if (ac == null || (! runningOnJDK1_4) ) + return 0; + if((index == 0) && getMnemonic(ac)==null) {// special case when there is no mnemonic + KeyStroke keyStroke = getAccelerator(ac); + if (keyStroke != null) { + return getModifiers(keyStroke); + } + } + if (index == 0) { // mnemonic + KeyStroke keyStroke = getMnemonic(ac); + if (keyStroke != null) { + return getModifiers(keyStroke); + } + } else if (index == 1) { // accelerator + KeyStroke keyStroke = getAccelerator(ac); + if (keyStroke != null) { + return getModifiers(keyStroke); + } + } + return 0; + } + + // ========== AccessibleIcon ============ + + /* + * return the number of icons associated with this context + */ + private int getAccessibleIconsCount(final AccessibleContext ac) { + debugString("getAccessibleIconsCount"); + if (ac == null) { + return 0; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleIcon[] ai = ac.getAccessibleIcon(); + if (ai == null) { + return 0; + } + return ai.length; + } + }, ac); + } + + /* + * return icon description at the specified index + */ + private String getAccessibleIconDescription(final AccessibleContext ac, final int index) { + debugString("getAccessibleIconDescription: index = "+index); + if (ac == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleIcon[] ai = ac.getAccessibleIcon(); + if (ai == null || index < 0 || index >= ai.length) { + return null; + } + return ai[index].getAccessibleIconDescription(); + } + }, ac); + } + + /* + * return icon height at the specified index + */ + private int getAccessibleIconHeight(final AccessibleContext ac, final int index) { + debugString("getAccessibleIconHeight: index = "+index); + if (ac == null) { + return 0; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleIcon[] ai = ac.getAccessibleIcon(); + if (ai == null || index < 0 || index >= ai.length) { + return 0; + } + return ai[index].getAccessibleIconHeight(); + } + }, ac); + } + + /* + * return icon width at the specified index + */ + private int getAccessibleIconWidth(final AccessibleContext ac, final int index) { + debugString("getAccessibleIconWidth: index = "+index); + if (ac == null) { + return 0; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleIcon[] ai = ac.getAccessibleIcon(); + if (ai == null || index < 0 || index >= ai.length) { + return 0; + } + return ai[index].getAccessibleIconWidth(); + } + }, ac); + } + + // ========= AccessibleAction =========== + + /* + * return the number of icons associated with this context + */ + private int getAccessibleActionsCount(final AccessibleContext ac) { + debugString("getAccessibleActionsCount"); + if (ac == null) { + return 0; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa == null) + return 0; + return aa.getAccessibleActionCount(); + } + }, ac); + } + + /* + * return icon description at the specified index + */ + private String getAccessibleActionName(final AccessibleContext ac, final int index) { + debugString("getAccessibleActionName: index = "+index); + if (ac == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa == null) { + return null; + } + return aa.getAccessibleActionDescription(index); + } + }, ac); + } + /* + * return icon description at the specified index + */ + private boolean doAccessibleActions(final AccessibleContext ac, final String name) { + debugString("doAccessibleActions: action name = "+name); + if (ac == null || name == null) { + return false; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa == null) { + return false; + } + int index = -1; + int numActions = aa.getAccessibleActionCount(); + for (int i = 0; i < numActions; i++) { + String actionName = aa.getAccessibleActionDescription(i); + if (name.equals(actionName)) { + index = i; + break; + } + } + if (index == -1) { + return false; + } + boolean retval = aa.doAccessibleAction(index); + return retval; + } + }, ac); + } + + /* ===== AT utility methods ===== */ + + /** + * Sets the contents of an AccessibleContext that + * implements AccessibleEditableText with the + * specified text string. + * Returns whether successful. + */ + private boolean setTextContents(final AccessibleContext ac, final String text) { + debugString("setTextContents: ac = "+ac+"; text = "+text); + + if (! (ac instanceof AccessibleEditableText)) { + debugString(" ac not instanceof AccessibleEditableText: "+ac); + return false; + } + if (text == null) { + debugString(" text is null"); + return false; + } + + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + // check whether the text field is editable + AccessibleStateSet ass = ac.getAccessibleStateSet(); + if (!ass.contains(AccessibleState.ENABLED)) { + return false; + } + ((AccessibleEditableText) ac).setTextContents(text); + return true; + } + }, ac); + } + + /** + * Returns the Accessible Context of an Internal Frame object that is + * the ancestor of a given object. If the object is an Internal Frame + * object or an Internal Frame ancestor object was found, returns the + * object's AccessibleContext. + * If there is no ancestor object that has an Accessible Role of + * Internal Frame, returns (AccessibleContext)0. + */ + private AccessibleContext getInternalFrame (AccessibleContext ac) { + return getParentWithRole(ac, AccessibleRole.INTERNAL_FRAME.toString()); + } + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + private AccessibleContext getTopLevelObject (final AccessibleContext ac) { + debugString("getTopLevelObject; ac = "+ac); + if (ac == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + if (ac.getAccessibleRole() == AccessibleRole.DIALOG) { + // return the dialog, not the parent window + return ac; + } + + Accessible parent = ac.getAccessibleParent(); + if (parent == null) { + return ac; + } + Accessible tmp = parent; + while (tmp != null && tmp.getAccessibleContext() != null) { + AccessibleContext ac2 = tmp.getAccessibleContext(); + if (ac2 != null && ac2.getAccessibleRole() == AccessibleRole.DIALOG) { + // return the dialog, not the parent window + return ac2; + } + parent = tmp; + tmp = parent.getAccessibleContext().getAccessibleParent(); + } + return parent.getAccessibleContext(); + } + }, ac); + } + + /** + * Returns the parent AccessibleContext that has the specified AccessibleRole. + * Returns null on error or if the AccessibleContext does not exist. + */ + private AccessibleContext getParentWithRole (final AccessibleContext ac, + final String roleName) { + debugString("getParentWithRole; ac = "+ac); + debugString("role = "+roleName); + if (ac == null || roleName == null) { + return null; + } + + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + AccessibleRole role = AccessBridge.this.accessibleRoleMap.get(roleName); + if (role == null) { + return ac; + } + + Accessible parent = ac.getAccessibleParent(); + if (parent == null && ac.getAccessibleRole() == role) { + return ac; + } + + Accessible tmp = parent; + AccessibleContext tmp_ac = null; + + while (tmp != null && (tmp_ac = tmp.getAccessibleContext()) != null) { + AccessibleRole ar = tmp_ac.getAccessibleRole(); + if (ar == role) { + // found + return tmp_ac; + } + parent = tmp; + tmp = parent.getAccessibleContext().getAccessibleParent(); + } + // not found + return null; + } + }, ac); + } + + /** + * Returns the parent AccessibleContext that has the specified AccessibleRole. + * Otherwise, returns the top level object for the Java Window. + * Returns (AccessibleContext)0 on error. + */ + private AccessibleContext getParentWithRoleElseRoot (AccessibleContext ac, + String roleName) { + AccessibleContext retval = getParentWithRole(ac, roleName); + if (retval == null) { + retval = getTopLevelObject(ac); + } + return retval; + } + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + private int getObjectDepth(final AccessibleContext ac) { + debugString("getObjectDepth: ac = "+ac); + + if (ac == null) { + return -1; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + int count = 0; + Accessible parent = ac.getAccessibleParent(); + if (parent == null) { + return count; + } + Accessible tmp = parent; + while (tmp != null && tmp.getAccessibleContext() != null) { + parent = tmp; + tmp = parent.getAccessibleContext().getAccessibleParent(); + count++; + } + return count; + } + }, ac); + } + + /** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * Returns (AccessibleContext)0 on error. + */ + private AccessibleContext getActiveDescendent (final AccessibleContext ac) { + debugString("getActiveDescendent: ac = "+ac); + if (ac == null) { + return null; + } + // workaround for JTree bug where the only possible active + // descendent is the JTree root + final Accessible parent = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return ac.getAccessibleParent(); + } + }, ac); + + if (parent != null) { + Accessible child = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + int indexInParent = ac.getAccessibleIndexInParent(); + return parent.getAccessibleContext().getAccessibleChild(indexInParent); + } + }, ac); + + if (child instanceof JTree) { + // return the selected node + final JTree tree = (JTree)child; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return new AccessibleJTreeNode(tree, + tree.getSelectionPath(), + null); + } + }, child); + } + } + + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as == null) { + return null; + } + // assume single selection + if (as.getAccessibleSelectionCount() != 1) { + return null; + } + Accessible a = as.getAccessibleSelection(0); + if (a == null) { + return null; + } + return a.getAccessibleContext(); + } + }, ac); + } + + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. + * Returns whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + private String getJAWSAccessibleName(final AccessibleContext ac) { + debugString("getJAWSAccessibleName"); + if (ac == null) { + return null; + } + // placeholder + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleName(); + } + }, ac); + } + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + private boolean requestFocus(final AccessibleContext ac) { + debugString("requestFocus"); + if (ac == null) { + return false; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + AccessibleComponent acomp = ac.getAccessibleComponent(); + if (acomp == null) { + return false; + } + acomp.requestFocus(); + return ac.getAccessibleStateSet().contains(AccessibleState.FOCUSED); + } + }, ac); + } + + /** + * Selects text between two indices. Selection includes the + * text at the start index and the text at the end index. Returns + * whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + private boolean selectTextRange(final AccessibleContext ac, final int startIndex, final int endIndex) { + debugString("selectTextRange: start = "+startIndex+"; end = "+endIndex); + if (ac == null) { + return false; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (!(at instanceof AccessibleEditableText)) { + return false; + } + ((AccessibleEditableText) at).selectText(startIndex, endIndex); + + boolean result = at.getSelectionStart() == startIndex && + at.getSelectionEnd() == endIndex; + return result; + } + }, ac); + } + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + private boolean setCaretPosition(final AccessibleContext ac, final int position) { + debugString("setCaretPosition: position = "+position); + if (ac == null) { + return false; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (!(at instanceof AccessibleEditableText)) { + return false; + } + ((AccessibleEditableText) at).selectText(position, position); + return at.getCaretPosition() == position; + } + }, ac); + } + + /** + * Gets the number of visible children of an AccessibleContext. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + private int _visibleChildrenCount; + private AccessibleContext _visibleChild; + private int _currentVisibleIndex; + private boolean _foundVisibleChild; + + private int getVisibleChildrenCount(AccessibleContext ac) { + debugString("getVisibleChildrenCount"); + if (ac == null) { + return -1; + } + _visibleChildrenCount = 0; + _getVisibleChildrenCount(ac); + debugString(" _visibleChildrenCount = "+_visibleChildrenCount); + return _visibleChildrenCount; + } + + /* + * Recursively descends AccessibleContext and gets the number + * of visible children + */ + private void _getVisibleChildrenCount(final AccessibleContext ac) { + if (ac == null) + return; + int numChildren = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac.getAccessibleChildrenCount(); + } + }, ac); + for (int i = 0; i < numChildren; i++) { + final int idx = i; + final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = ac.getAccessibleChild(idx); + if (a != null) + return a.getAccessibleContext(); + else + return null; + } + }, ac); + if ( ac2 == null || + (!InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING); + } + }, ac)) + ) { + continue; + } + _visibleChildrenCount++; + + if (InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac2.getAccessibleChildrenCount(); + } + }, ac) > 0 ) { + _getVisibleChildrenCount(ac2); + } + } + } + + /** + * Gets the visible child of an AccessibleContext at the + * specified index + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + private AccessibleContext getVisibleChild(AccessibleContext ac, int index) { + debugString("getVisibleChild: index = "+index); + if (ac == null) { + return null; + } + _visibleChild = null; + _currentVisibleIndex = 0; + _foundVisibleChild = false; + _getVisibleChild(ac, index); + + if (_visibleChild != null) { + debugString( " getVisibleChild: found child = " + + InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return AccessBridge.this._visibleChild.getAccessibleName(); + } + }, ac) ); + } + return _visibleChild; + } + + /* + * Recursively searchs AccessibleContext and finds the visible component + * at the specified index + */ + private void _getVisibleChild(final AccessibleContext ac, final int index) { + if (_visibleChild != null) { + return; + } + + int numChildren = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac.getAccessibleChildrenCount(); + } + }, ac); + for (int i = 0; i < numChildren; i++) { + final int idx=i; + final AccessibleContext ac2=InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = ac.getAccessibleChild(idx); + if (a == null) + return null; + else + return a.getAccessibleContext(); + } + }, ac); + if (ac2 == null || + (!InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING); + } + }, ac))) { + continue; + } + if (!_foundVisibleChild && _currentVisibleIndex == index) { + _visibleChild = ac2; + _foundVisibleChild = true; + return; + } + _currentVisibleIndex++; + + if ( InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac2.getAccessibleChildrenCount(); + } + }, ac) > 0 ) { + _getVisibleChild(ac2, index); + } + } + } + + + /* ===== Java object memory management code ===== */ + + /** + * Class to track object references to ensure the + * Java VM doesn't garbage collect them + */ + private class ObjectReferences { + + private class Reference { + private int value; + + Reference(int i) { + value = i; + } + + public String toString() { + return ("refCount: " + value); + } + } + + /** + * table object references, to keep 'em from being garbage collected + */ + private ConcurrentHashMap refs; + + /** + * Constructor + */ + ObjectReferences() { + refs = new ConcurrentHashMap<>(4); + } + + /** + * Debugging: dump the contents of ObjectReferences' refs Hashtable + */ + String dump() { + return refs.toString(); + } + + /** + * Increment ref count; set to 1 if we have no references for it + */ + void increment(Object o) { + if (o == null){ + debugString("ObjectReferences::increment - Passed in object is null"); + return; + } + + if (refs.containsKey(o)) { + (refs.get(o)).value++; + } else { + refs.put(o, new Reference(1)); + } + } + + /** + * Decrement ref count; remove if count drops to 0 + */ + void decrement(Object o) { + Reference aRef = refs.get(o); + if (aRef != null) { + aRef.value--; + if (aRef.value == 0) { + refs.remove(o); + } else if (aRef.value < 0) { + debugString("ERROR: decrementing reference count below 0"); + } + } else { + debugString("ERROR: object to decrement not in ObjectReferences table"); + } + } + + } + + /* ===== event handling code ===== */ + + /** + * native method for handling property change events + */ + private native void propertyCaretChange(PropertyChangeEvent e, + AccessibleContext src, + int oldValue, int newValue); + private native void propertyDescriptionChange(PropertyChangeEvent e, + AccessibleContext src, + String oldValue, String newValue); + private native void propertyNameChange(PropertyChangeEvent e, + AccessibleContext src, + String oldValue, String newValue); + private native void propertySelectionChange(PropertyChangeEvent e, + AccessibleContext src); + private native void propertyStateChange(PropertyChangeEvent e, + AccessibleContext src, + String oldValue, String newValue); + private native void propertyTextChange(PropertyChangeEvent e, + AccessibleContext src); + private native void propertyValueChange(PropertyChangeEvent e, + AccessibleContext src, + String oldValue, String newValue); + private native void propertyVisibleDataChange(PropertyChangeEvent e, + AccessibleContext src); + private native void propertyChildChange(PropertyChangeEvent e, + AccessibleContext src, + AccessibleContext oldValue, + AccessibleContext newValue); + private native void propertyActiveDescendentChange(PropertyChangeEvent e, + AccessibleContext src, + AccessibleContext oldValue, + AccessibleContext newValue); + + private native void javaShutdown(); + + /** + * native methods for handling focus events + */ + private native void focusGained(FocusEvent e, AccessibleContext src); + private native void focusLost(FocusEvent e, AccessibleContext src); + + /** + * native method for handling caret events + */ + private native void caretUpdate(CaretEvent e, AccessibleContext src); + + /** + * native methods for handling mouse events + */ + private native void mouseClicked(MouseEvent e, AccessibleContext src); + private native void mouseEntered(MouseEvent e, AccessibleContext src); + private native void mouseExited(MouseEvent e, AccessibleContext src); + private native void mousePressed(MouseEvent e, AccessibleContext src); + private native void mouseReleased(MouseEvent e, AccessibleContext src); + + /** + * native methods for handling menu & popupMenu events + */ + private native void menuCanceled(MenuEvent e, AccessibleContext src); + private native void menuDeselected(MenuEvent e, AccessibleContext src); + private native void menuSelected(MenuEvent e, AccessibleContext src); + private native void popupMenuCanceled(PopupMenuEvent e, AccessibleContext src); + private native void popupMenuWillBecomeInvisible(PopupMenuEvent e, + AccessibleContext src); + private native void popupMenuWillBecomeVisible(PopupMenuEvent e, + AccessibleContext src); + + /* ===== event definitions ===== */ + + private static final long PROPERTY_CHANGE_EVENTS = 1; + private static final long FOCUS_GAINED_EVENTS = 2; + private static final long FOCUS_LOST_EVENTS = 4; + private static final long FOCUS_EVENTS = (FOCUS_GAINED_EVENTS | FOCUS_LOST_EVENTS); + + private static final long CARET_UPATE_EVENTS = 8; + private static final long CARET_EVENTS = CARET_UPATE_EVENTS; + + private static final long MOUSE_CLICKED_EVENTS = 16; + private static final long MOUSE_ENTERED_EVENTS = 32; + private static final long MOUSE_EXITED_EVENTS = 64; + private static final long MOUSE_PRESSED_EVENTS = 128; + private static final long MOUSE_RELEASED_EVENTS = 256; + private static final long MOUSE_EVENTS = (MOUSE_CLICKED_EVENTS | MOUSE_ENTERED_EVENTS | + MOUSE_EXITED_EVENTS | MOUSE_PRESSED_EVENTS | + MOUSE_RELEASED_EVENTS); + + private static final long MENU_CANCELED_EVENTS = 512; + private static final long MENU_DESELECTED_EVENTS = 1024; + private static final long MENU_SELECTED_EVENTS = 2048; + private static final long MENU_EVENTS = (MENU_CANCELED_EVENTS | MENU_DESELECTED_EVENTS | + MENU_SELECTED_EVENTS); + + private static final long POPUPMENU_CANCELED_EVENTS = 4096; + private static final long POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS = 8192; + private static final long POPUPMENU_WILL_BECOME_VISIBLE_EVENTS = 16384; + private static final long POPUPMENU_EVENTS = (POPUPMENU_CANCELED_EVENTS | + POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS | + POPUPMENU_WILL_BECOME_VISIBLE_EVENTS); + + /* These use their own numbering scheme, to ensure sufficient expansion room */ + private static final long PROPERTY_NAME_CHANGE_EVENTS = 1; + private static final long PROPERTY_DESCRIPTION_CHANGE_EVENTS = 2; + private static final long PROPERTY_STATE_CHANGE_EVENTS = 4; + private static final long PROPERTY_VALUE_CHANGE_EVENTS = 8; + private static final long PROPERTY_SELECTION_CHANGE_EVENTS = 16; + private static final long PROPERTY_TEXT_CHANGE_EVENTS = 32; + private static final long PROPERTY_CARET_CHANGE_EVENTS = 64; + private static final long PROPERTY_VISIBLEDATA_CHANGE_EVENTS = 128; + private static final long PROPERTY_CHILD_CHANGE_EVENTS = 256; + private static final long PROPERTY_ACTIVEDESCENDENT_CHANGE_EVENTS = 512; + + + private static final long PROPERTY_EVENTS = (PROPERTY_NAME_CHANGE_EVENTS | + PROPERTY_DESCRIPTION_CHANGE_EVENTS | + PROPERTY_STATE_CHANGE_EVENTS | + PROPERTY_VALUE_CHANGE_EVENTS | + PROPERTY_SELECTION_CHANGE_EVENTS | + PROPERTY_TEXT_CHANGE_EVENTS | + PROPERTY_CARET_CHANGE_EVENTS | + PROPERTY_VISIBLEDATA_CHANGE_EVENTS | + PROPERTY_CHILD_CHANGE_EVENTS | + PROPERTY_ACTIVEDESCENDENT_CHANGE_EVENTS); + + /** + * The EventHandler class listens for Java events and + * forwards them to the AT + */ + private class EventHandler implements PropertyChangeListener, + FocusListener, CaretListener, + MenuListener, PopupMenuListener, + MouseListener, WindowListener, + ChangeListener { + + private AccessBridge accessBridge; + private long javaEventMask = 0; + private long accessibilityEventMask = 0; + + EventHandler(AccessBridge bridge) { + accessBridge = bridge; + + // Register to receive WINDOW_OPENED and WINDOW_CLOSED + // events. Add the event source as a native window + // handler is it implements NativeWindowHandler. + // SwingEventMonitor.addWindowListener(this); + } + + // --------- Event Notification Registration methods + + /** + * Invoked the first time a window is made visible. + */ + public void windowOpened(WindowEvent e) { + // If the window is a NativeWindowHandler, add it. + Object o = null; + if (e != null) + o = e.getSource(); + if (o instanceof NativeWindowHandler) { + addNativeWindowHandler((NativeWindowHandler)o); + } + } + + /** + * Invoked when the user attempts to close the window + * from the window's system menu. If the program does not + * explicitly hide or dispose the window while processing + * this event, the window close operation will be canceled. + */ + public void windowClosing(WindowEvent e) {} + + /** + * Invoked when a window has been closed as the result + * of calling dispose on the window. + */ + public void windowClosed(WindowEvent e) { + // If the window is a NativeWindowHandler, remove it. + Object o = null; + if (e != null) + o = e.getSource(); + if (o instanceof NativeWindowHandler) { + removeNativeWindowHandler((NativeWindowHandler)o); + } + } + + /** + * Invoked when a window is changed from a normal to a + * minimized state. For many platforms, a minimized window + * is displayed as the icon specified in the window's + * iconImage property. + * @see java.awt.Frame#setIconImage + */ + public void windowIconified(WindowEvent e) {} + + /** + * Invoked when a window is changed from a minimized + * to a normal state. + */ + public void windowDeiconified(WindowEvent e) {} + + /** + * Invoked when the Window is set to be the active Window. Only a Frame or + * a Dialog can be the active Window. The native windowing system may + * denote the active Window or its children with special decorations, such + * as a highlighted title bar. The active Window is always either the + * focused Window, or the first Frame or Dialog that is an owner of the + * focused Window. + */ + public void windowActivated(WindowEvent e) {} + + /** + * Invoked when a Window is no longer the active Window. Only a Frame or a + * Dialog can be the active Window. The native windowing system may denote + * the active Window or its children with special decorations, such as a + * highlighted title bar. The active Window is always either the focused + * Window, or the first Frame or Dialog that is an owner of the focused + * Window. + */ + public void windowDeactivated(WindowEvent e) {} + + /** + * Turn on event monitoring for the event type passed in + * If necessary, add the appropriate event listener (if + * no other event of that type is being listened for) + */ + void addJavaEventNotification(long type) { + long newEventMask = javaEventMask | type; + /* + if ( ((javaEventMask & PROPERTY_EVENTS) == 0) && + ((newEventMask & PROPERTY_EVENTS) != 0) ) { + AccessibilityEventMonitor.addPropertyChangeListener(this); + } + */ + if ( ((javaEventMask & FOCUS_EVENTS) == 0) && + ((newEventMask & FOCUS_EVENTS) != 0) ) { + SwingEventMonitor.addFocusListener(this); + } + if ( ((javaEventMask & CARET_EVENTS) == 0) && + ((newEventMask & CARET_EVENTS) != 0) ) { + SwingEventMonitor.addCaretListener(this); + } + if ( ((javaEventMask & MOUSE_EVENTS) == 0) && + ((newEventMask & MOUSE_EVENTS) != 0) ) { + SwingEventMonitor.addMouseListener(this); + } + if ( ((javaEventMask & MENU_EVENTS) == 0) && + ((newEventMask & MENU_EVENTS) != 0) ) { + SwingEventMonitor.addMenuListener(this); + SwingEventMonitor.addPopupMenuListener(this); + } + if ( ((javaEventMask & POPUPMENU_EVENTS) == 0) && + ((newEventMask & POPUPMENU_EVENTS) != 0) ) { + SwingEventMonitor.addPopupMenuListener(this); + } + + javaEventMask = newEventMask; + } + + /** + * Turn off event monitoring for the event type passed in + * If necessary, remove the appropriate event listener (if + * no other event of that type is being listened for) + */ + void removeJavaEventNotification(long type) { + long newEventMask = javaEventMask & (~type); + /* + if ( ((javaEventMask & PROPERTY_EVENTS) != 0) && + ((newEventMask & PROPERTY_EVENTS) == 0) ) { + AccessibilityEventMonitor.removePropertyChangeListener(this); + } + */ + if (((javaEventMask & FOCUS_EVENTS) != 0) && + ((newEventMask & FOCUS_EVENTS) == 0)) { + SwingEventMonitor.removeFocusListener(this); + } + if (((javaEventMask & CARET_EVENTS) != 0) && + ((newEventMask & CARET_EVENTS) == 0)) { + SwingEventMonitor.removeCaretListener(this); + } + if (((javaEventMask & MOUSE_EVENTS) == 0) && + ((newEventMask & MOUSE_EVENTS) != 0)) { + SwingEventMonitor.removeMouseListener(this); + } + if (((javaEventMask & MENU_EVENTS) == 0) && + ((newEventMask & MENU_EVENTS) != 0)) { + SwingEventMonitor.removeMenuListener(this); + } + if (((javaEventMask & POPUPMENU_EVENTS) == 0) && + ((newEventMask & POPUPMENU_EVENTS) != 0)) { + SwingEventMonitor.removePopupMenuListener(this); + } + + javaEventMask = newEventMask; + } + + /** + * Turn on event monitoring for the event type passed in + * If necessary, add the appropriate event listener (if + * no other event of that type is being listened for) + */ + void addAccessibilityEventNotification(long type) { + long newEventMask = accessibilityEventMask | type; + if ( ((accessibilityEventMask & PROPERTY_EVENTS) == 0) && + ((newEventMask & PROPERTY_EVENTS) != 0) ) { + AccessibilityEventMonitor.addPropertyChangeListener(this); + } + accessibilityEventMask = newEventMask; + } + + /** + * Turn off event monitoring for the event type passed in + * If necessary, remove the appropriate event listener (if + * no other event of that type is being listened for) + */ + void removeAccessibilityEventNotification(long type) { + long newEventMask = accessibilityEventMask & (~type); + if ( ((accessibilityEventMask & PROPERTY_EVENTS) != 0) && + ((newEventMask & PROPERTY_EVENTS) == 0) ) { + AccessibilityEventMonitor.removePropertyChangeListener(this); + } + accessibilityEventMask = newEventMask; + } + + /** + * ------- property change event glue + */ + // This is invoked on the EDT , as + public void propertyChange(PropertyChangeEvent e) { + + accessBridge.debugString("propertyChange(" + e.toString() + ") called"); + + if (e != null && (accessibilityEventMask & PROPERTY_EVENTS) != 0) { + Object o = e.getSource(); + AccessibleContext ac; + + if (o instanceof AccessibleContext) { + ac = (AccessibleContext) o; + } else { + Accessible a = Translator.getAccessible(e.getSource()); + if (a == null) + return; + else + ac = a.getAccessibleContext(); + } + if (ac != null) { + InvocationUtils.registerAccessibleContext(ac, AppContext.getAppContext()); + + accessBridge.debugString("AccessibleContext: " + ac); + String propertyName = e.getPropertyName(); + + if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CARET_PROPERTY) == 0) { + int oldValue = 0; + int newValue = 0; + + if (e.getOldValue() instanceof Integer) { + oldValue = ((Integer) e.getOldValue()).intValue(); + } + if (e.getNewValue() instanceof Integer) { + newValue = ((Integer) e.getNewValue()).intValue(); + } + accessBridge.debugString(" - about to call propertyCaretChange()"); + accessBridge.debugString(" old value: " + oldValue + "new value: " + newValue); + accessBridge.propertyCaretChange(e, ac, oldValue, newValue); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY) == 0) { + String oldValue = null; + String newValue = null; + + if (e.getOldValue() != null) { + oldValue = e.getOldValue().toString(); + } + if (e.getNewValue() != null) { + newValue = e.getNewValue().toString(); + } + accessBridge.debugString(" - about to call propertyDescriptionChange()"); + accessBridge.debugString(" old value: " + oldValue + "new value: " + newValue); + accessBridge.propertyDescriptionChange(e, ac, oldValue, newValue); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_NAME_PROPERTY) == 0) { + String oldValue = null; + String newValue = null; + + if (e.getOldValue() != null) { + oldValue = e.getOldValue().toString(); + } + if (e.getNewValue() != null) { + newValue = e.getNewValue().toString(); + } + accessBridge.debugString(" - about to call propertyNameChange()"); + accessBridge.debugString(" old value: " + oldValue + " new value: " + newValue); + accessBridge.propertyNameChange(e, ac, oldValue, newValue); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY) == 0) { + accessBridge.debugString(" - about to call propertySelectionChange() " + ac + " " + Thread.currentThread() + " " + e.getSource()); + + accessBridge.propertySelectionChange(e, ac); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_STATE_PROPERTY) == 0) { + String oldValue = null; + String newValue = null; + + // Localization fix requested by Oliver for EA-1 + if (e.getOldValue() != null) { + AccessibleState oldState = (AccessibleState) e.getOldValue(); + oldValue = oldState.toDisplayString(Locale.US); + } + if (e.getNewValue() != null) { + AccessibleState newState = (AccessibleState) e.getNewValue(); + newValue = newState.toDisplayString(Locale.US); + } + + accessBridge.debugString(" - about to call propertyStateChange()"); + accessBridge.propertyStateChange(e, ac, oldValue, newValue); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_TEXT_PROPERTY) == 0) { + accessBridge.debugString(" - about to call propertyTextChange()"); + accessBridge.propertyTextChange(e, ac); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY) == 0) { // strings 'cause of floating point, etc. + String oldValue = null; + String newValue = null; + + if (e.getOldValue() != null) { + oldValue = e.getOldValue().toString(); + } + if (e.getNewValue() != null) { + newValue = e.getNewValue().toString(); + } + accessBridge.debugString(" - about to call propertyDescriptionChange()"); + accessBridge.propertyValueChange(e, ac, oldValue, newValue); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY) == 0) { + accessBridge.propertyVisibleDataChange(e, ac); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY) == 0) { + AccessibleContext oldAC = null; + AccessibleContext newAC = null; + Accessible a; + + if (e.getOldValue() instanceof AccessibleContext) { + oldAC = (AccessibleContext) e.getOldValue(); + InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext()); + } + if (e.getNewValue() instanceof AccessibleContext) { + newAC = (AccessibleContext) e.getNewValue(); + InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext()); + } + accessBridge.debugString(" - about to call propertyChildChange()"); + accessBridge.debugString(" old AC: " + oldAC + "new AC: " + newAC); + accessBridge.propertyChildChange(e, ac, oldAC, newAC); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0) { + handleActiveDescendentEvent(e, ac); + } + } + } + } + + /* + * Handle an ActiveDescendent PropertyChangeEvent. This + * method works around a JTree bug where ActiveDescendent + * PropertyChangeEvents have the wrong parent. + */ + private AccessibleContext prevAC = null; // previous AccessibleContext + + private void handleActiveDescendentEvent(PropertyChangeEvent e, + AccessibleContext ac) { + if (e == null || ac == null) + return; + AccessibleContext oldAC = null; + AccessibleContext newAC = null; + Accessible a; + + // get the old active descendent + if (e.getOldValue() instanceof Accessible) { + oldAC = ((Accessible) e.getOldValue()).getAccessibleContext(); + } else if (e.getOldValue() instanceof Component) { + a = Translator.getAccessible(e.getOldValue()); + if (a != null) { + oldAC = a.getAccessibleContext(); + } + } + if (oldAC != null) { + Accessible parent = oldAC.getAccessibleParent(); + if (parent instanceof JTree) { + // use the previous AccessibleJTreeNode + oldAC = prevAC; + } + } + + // get the new active descendent + if (e.getNewValue() instanceof Accessible) { + newAC = ((Accessible) e.getNewValue()).getAccessibleContext(); + } else if (e.getNewValue() instanceof Component) { + a = Translator.getAccessible(e.getNewValue()); + if (a != null) { + newAC = a.getAccessibleContext(); + } + } + if (newAC != null) { + Accessible parent = newAC.getAccessibleParent(); + if (parent instanceof JTree) { + // use a new AccessibleJTreeNode with the right parent + JTree tree = (JTree)parent; + newAC = new AccessibleJTreeNode(tree, + tree.getSelectionPath(), + null); + } + } + prevAC = newAC; + + accessBridge.debugString(" - about to call propertyActiveDescendentChange()"); + accessBridge.debugString(" AC: " + ac); + accessBridge.debugString(" old AC: " + oldAC + "new AC: " + newAC); + + InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext()); + InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext()); + accessBridge.propertyActiveDescendentChange(e, ac, oldAC, newAC); + } + + /** + * ------- focus event glue + */ + private boolean stateChangeListenerAdded = false; + + public void focusGained(FocusEvent e) { + if (runningOnJDK1_4) { + processFocusGained(); + } else { + if ((javaEventMask & FOCUS_GAINED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, SunToolkit.targetToAppContext(e.getSource())); + accessBridge.focusGained(e, context); + } + } + } + } + + public void stateChanged(ChangeEvent e) { + processFocusGained(); + } + + private void processFocusGained() { + Component focusOwner = KeyboardFocusManager. + getCurrentKeyboardFocusManager().getFocusOwner(); + if (focusOwner == null) { + return; + } + + // Only menus and popup selections are handled by the JRootPane. + if (focusOwner instanceof JRootPane) { + MenuElement [] path = + MenuSelectionManager.defaultManager().getSelectedPath(); + if (path.length > 1) { + Component penult = path[path.length-2].getComponent(); + Component last = path[path.length-1].getComponent(); + + if (last instanceof JPopupMenu) { + // This is a popup with nothing in the popup + // selected. The menu itself is selected. + FocusEvent e = new FocusEvent(penult, FocusEvent.FOCUS_GAINED); + AccessibleContext context = penult.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, SunToolkit.targetToAppContext(penult)); + accessBridge.focusGained(e, context); + } else if (penult instanceof JPopupMenu) { + // This is a popup with an item selected + FocusEvent e = + new FocusEvent(last, FocusEvent.FOCUS_GAINED); + accessBridge.debugString(" - about to call focusGained()"); + AccessibleContext focusedAC = last.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(last)); + accessBridge.debugString(" AC: " + focusedAC); + accessBridge.focusGained(e, focusedAC); + } + } + } else { + // The focus owner has the selection. + if (focusOwner instanceof Accessible) { + FocusEvent e = new FocusEvent(focusOwner, + FocusEvent.FOCUS_GAINED); + accessBridge.debugString(" - about to call focusGained()"); + AccessibleContext focusedAC = focusOwner.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(focusOwner)); + accessBridge.debugString(" AC: " + focusedAC); + accessBridge.focusGained(e, focusedAC); + } + } + } + + public void focusLost(FocusEvent e) { + if (e != null && (javaEventMask & FOCUS_LOST_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + accessBridge.debugString(" - about to call focusLost()"); + accessBridge.debugString(" AC: " + a.getAccessibleContext()); + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.focusLost(e, context); + } + } + } + + /** + * ------- caret event glue + */ + public void caretUpdate(CaretEvent e) { + if (e != null && (javaEventMask & CARET_UPATE_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.caretUpdate(e, context); + } + } + } + + /** + * ------- mouse event glue + */ + + public void mouseClicked(MouseEvent e) { + if (e != null && (javaEventMask & MOUSE_CLICKED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.mouseClicked(e, context); + } + } + } + + public void mouseEntered(MouseEvent e) { + if (e != null && (javaEventMask & MOUSE_ENTERED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.mouseEntered(e, context); + } + } + } + + public void mouseExited(MouseEvent e) { + if (e != null && (javaEventMask & MOUSE_EXITED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.mouseExited(e, context); + } + } + } + + public void mousePressed(MouseEvent e) { + if (e != null && (javaEventMask & MOUSE_PRESSED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.mousePressed(e, context); + } + } + } + + public void mouseReleased(MouseEvent e) { + if (e != null && (javaEventMask & MOUSE_RELEASED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.mouseReleased(e, context); + } + } + } + + /** + * ------- menu event glue + */ + public void menuCanceled(MenuEvent e) { + if (e != null && (javaEventMask & MENU_CANCELED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.menuCanceled(e, context); + } + } + } + + public void menuDeselected(MenuEvent e) { + if (e != null && (javaEventMask & MENU_DESELECTED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.menuDeselected(e, context); + } + } + } + + public void menuSelected(MenuEvent e) { + if (e != null && (javaEventMask & MENU_SELECTED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.menuSelected(e, context); + } + } + } + + public void popupMenuCanceled(PopupMenuEvent e) { + if (e != null && (javaEventMask & POPUPMENU_CANCELED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.popupMenuCanceled(e, context); + } + } + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + if (e != null && (javaEventMask & POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.popupMenuWillBecomeInvisible(e, context); + } + } + } + + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + if (e != null && (javaEventMask & POPUPMENU_WILL_BECOME_VISIBLE_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.popupMenuWillBecomeVisible(e, context); + } + } + } + + } // End of EventHandler Class + + // --------- Event Notification Registration methods + + /** + * Wrapper method around eventHandler.addJavaEventNotification() + */ + private void addJavaEventNotification(final long type) { + EventQueue.invokeLater(new Runnable() { + public void run(){ + eventHandler.addJavaEventNotification(type); + } + }); + } + + /** + * Wrapper method around eventHandler.removeJavaEventNotification() + */ + private void removeJavaEventNotification(final long type) { + EventQueue.invokeLater(new Runnable() { + public void run(){ + eventHandler.removeJavaEventNotification(type); + } + }); + } + + + /** + * Wrapper method around eventHandler.addAccessibilityEventNotification() + */ + private void addAccessibilityEventNotification(final long type) { + EventQueue.invokeLater(new Runnable() { + public void run(){ + eventHandler.addAccessibilityEventNotification(type); + } + }); + } + + /** + * Wrapper method around eventHandler.removeAccessibilityEventNotification() + */ + private void removeAccessibilityEventNotification(final long type) { + EventQueue.invokeLater(new Runnable() { + public void run(){ + eventHandler.removeAccessibilityEventNotification(type); + } + }); + } + + /** + ****************************************************** + * All AccessibleRoles + * + * We shouldn't have to do this since it requires us + * to synchronize the allAccessibleRoles array when + * the AccessibleRoles class interface changes. However, + * there is no Accessibility API method to get all + * AccessibleRoles + ****************************************************** + */ + private AccessibleRole [] allAccessibleRoles = { + /** + * Object is used to alert the user about something. + */ + AccessibleRole.ALERT, + + /** + * The header for a column of data. + */ + AccessibleRole.COLUMN_HEADER, + + /** + * Object that can be drawn into and is used to trap + * events. + * @see #FRAME + * @see #GLASS_PANE + * @see #LAYERED_PANE + */ + AccessibleRole.CANVAS, + + /** + * A list of choices the user can select from. Also optionally + * allows the user to enter a choice of their own. + */ + AccessibleRole.COMBO_BOX, + + /** + * An iconified internal frame in a DESKTOP_PANE. + * @see #DESKTOP_PANE + * @see #INTERNAL_FRAME + */ + AccessibleRole.DESKTOP_ICON, + + /** + * A frame-like object that is clipped by a desktop pane. The + * desktop pane, internal frame, and desktop icon objects are + * often used to create multiple document interfaces within an + * application. + * @see #DESKTOP_ICON + * @see #DESKTOP_PANE + * @see #FRAME + */ + AccessibleRole.INTERNAL_FRAME, + + /** + * A pane that supports internal frames and + * iconified versions of those internal frames. + * @see #DESKTOP_ICON + * @see #INTERNAL_FRAME + */ + AccessibleRole.DESKTOP_PANE, + + /** + * A specialized pane whose primary use is inside a DIALOG + * @see #DIALOG + */ + AccessibleRole.OPTION_PANE, + + /** + * A top level window with no title or border. + * @see #FRAME + * @see #DIALOG + */ + AccessibleRole.WINDOW, + + /** + * A top level window with a title bar, border, menu bar, etc. It is + * often used as the primary window for an application. + * @see #DIALOG + * @see #CANVAS + * @see #WINDOW + */ + AccessibleRole.FRAME, + + /** + * A top level window with title bar and a border. A dialog is similar + * to a frame, but it has fewer properties and is often used as a + * secondary window for an application. + * @see #FRAME + * @see #WINDOW + */ + AccessibleRole.DIALOG, + + /** + * A specialized dialog that lets the user choose a color. + */ + AccessibleRole.COLOR_CHOOSER, + + + /** + * A pane that allows the user to navigate through + * and select the contents of a directory. May be used + * by a file chooser. + * @see #FILE_CHOOSER + */ + AccessibleRole.DIRECTORY_PANE, + + /** + * A specialized dialog that displays the files in the directory + * and lets the user select a file, browse a different directory, + * or specify a filename. May use the directory pane to show the + * contents of a directory. + * @see #DIRECTORY_PANE + */ + AccessibleRole.FILE_CHOOSER, + + /** + * An object that fills up space in a user interface. It is often + * used in interfaces to tweak the spacing between components, + * but serves no other purpose. + */ + AccessibleRole.FILLER, + + /** + * A hypertext anchor + */ + // AccessibleRole.HYPERLINK, + + /** + * A small fixed size picture, typically used to decorate components. + */ + AccessibleRole.ICON, + + /** + * An object used to present an icon or short string in an interface. + */ + AccessibleRole.LABEL, + + /** + * A specialized pane that has a glass pane and a layered pane as its + * children. + * @see #GLASS_PANE + * @see #LAYERED_PANE + */ + AccessibleRole.ROOT_PANE, + + /** + * A pane that is guaranteed to be painted on top + * of all panes beneath it. + * @see #ROOT_PANE + * @see #CANVAS + */ + AccessibleRole.GLASS_PANE, + + /** + * A specialized pane that allows its children to be drawn in layers, + * providing a form of stacking order. This is usually the pane that + * holds the menu bar as well as the pane that contains most of the + * visual components in a window. + * @see #GLASS_PANE + * @see #ROOT_PANE + */ + AccessibleRole.LAYERED_PANE, + + /** + * An object that presents a list of objects to the user and allows the + * user to select one or more of them. A list is usually contained + * within a scroll pane. + * @see #SCROLL_PANE + * @see #LIST_ITEM + */ + AccessibleRole.LIST, + + /** + * An object that presents an element in a list. A list is usually + * contained within a scroll pane. + * @see #SCROLL_PANE + * @see #LIST + */ + AccessibleRole.LIST_ITEM, + + /** + * An object usually drawn at the top of the primary dialog box of + * an application that contains a list of menus the user can choose + * from. For example, a menu bar might contain menus for "File," + * "Edit," and "Help." + * @see #MENU + * @see #POPUP_MENU + * @see #LAYERED_PANE + */ + AccessibleRole.MENU_BAR, + + /** + * A temporary window that is usually used to offer the user a + * list of choices, and then hides when the user selects one of + * those choices. + * @see #MENU + * @see #MENU_ITEM + */ + AccessibleRole.POPUP_MENU, + + /** + * An object usually found inside a menu bar that contains a list + * of actions the user can choose from. A menu can have any object + * as its children, but most often they are menu items, other menus, + * or rudimentary objects such as radio buttons, check boxes, or + * separators. For example, an application may have an "Edit" menu + * that contains menu items for "Cut" and "Paste." + * @see #MENU_BAR + * @see #MENU_ITEM + * @see #SEPARATOR + * @see #RADIO_BUTTON + * @see #CHECK_BOX + * @see #POPUP_MENU + */ + AccessibleRole.MENU, + + /** + * An object usually contained in a menu that presents an action + * the user can choose. For example, the "Cut" menu item in an + * "Edit" menu would be an action the user can select to cut the + * selected area of text in a document. + * @see #MENU_BAR + * @see #SEPARATOR + * @see #POPUP_MENU + */ + AccessibleRole.MENU_ITEM, + + /** + * An object usually contained in a menu to provide a visual + * and logical separation of the contents in a menu. For example, + * the "File" menu of an application might contain menu items for + * "Open," "Close," and "Exit," and will place a separator between + * "Close" and "Exit" menu items. + * @see #MENU + * @see #MENU_ITEM + */ + AccessibleRole.SEPARATOR, + + /** + * An object that presents a series of panels (or page tabs), one at a + * time, through some mechanism provided by the object. The most common + * mechanism is a list of tabs at the top of the panel. The children of + * a page tab list are all page tabs. + * @see #PAGE_TAB + */ + AccessibleRole.PAGE_TAB_LIST, + + /** + * An object that is a child of a page tab list. Its sole child is + * the panel that is to be presented to the user when the user + * selects the page tab from the list of tabs in the page tab list. + * @see #PAGE_TAB_LIST + */ + AccessibleRole.PAGE_TAB, + + /** + * A generic container that is often used to group objects. + */ + AccessibleRole.PANEL, + + /** + * An object used to indicate how much of a task has been completed. + */ + AccessibleRole.PROGRESS_BAR, + + /** + * A text object used for passwords, or other places where the + * text contents is not shown visibly to the user + */ + AccessibleRole.PASSWORD_TEXT, + + /** + * An object the user can manipulate to tell the application to do + * something. + * @see #CHECK_BOX + * @see #TOGGLE_BUTTON + * @see #RADIO_BUTTON + */ + AccessibleRole.PUSH_BUTTON, + + /** + * A specialized push button that can be checked or unchecked, but + * does not provide a separate indicator for the current state. + * @see #PUSH_BUTTON + * @see #CHECK_BOX + * @see #RADIO_BUTTON + */ + AccessibleRole.TOGGLE_BUTTON, + + /** + * A choice that can be checked or unchecked and provides a + * separate indicator for the current state. + * @see #PUSH_BUTTON + * @see #TOGGLE_BUTTON + * @see #RADIO_BUTTON + */ + AccessibleRole.CHECK_BOX, + + /** + * A specialized check box that will cause other radio buttons in the + * same group to become unchecked when this one is checked. + * @see #PUSH_BUTTON + * @see #TOGGLE_BUTTON + * @see #CHECK_BOX + */ + AccessibleRole.RADIO_BUTTON, + + /** + * The header for a row of data. + */ + AccessibleRole.ROW_HEADER, + + /** + * An object that allows a user to incrementally view a large amount + * of information. Its children can include scroll bars and a viewport. + * @see #SCROLL_BAR + * @see #VIEWPORT + */ + AccessibleRole.SCROLL_PANE, + + /** + * An object usually used to allow a user to incrementally view a + * large amount of data. Usually used only by a scroll pane. + * @see #SCROLL_PANE + */ + AccessibleRole.SCROLL_BAR, + + /** + * An object usually used in a scroll pane. It represents the portion + * of the entire data that the user can see. As the user manipulates + * the scroll bars, the contents of the viewport can change. + * @see #SCROLL_PANE + */ + AccessibleRole.VIEWPORT, + + /** + * An object that allows the user to select from a bounded range. For + * example, a slider might be used to select a number between 0 and 100. + */ + AccessibleRole.SLIDER, + + /** + * A specialized panel that presents two other panels at the same time. + * Between the two panels is a divider the user can manipulate to make + * one panel larger and the other panel smaller. + */ + AccessibleRole.SPLIT_PANE, + + /** + * An object used to present information in terms of rows and columns. + * An example might include a spreadsheet application. + */ + AccessibleRole.TABLE, + + /** + * An object that presents text to the user. The text is usually + * editable by the user as opposed to a label. + * @see #LABEL + */ + AccessibleRole.TEXT, + + /** + * An object used to present hierarchical information to the user. + * The individual nodes in the tree can be collapsed and expanded + * to provide selective disclosure of the tree's contents. + */ + AccessibleRole.TREE, + + /** + * A bar or palette usually composed of push buttons or toggle buttons. + * It is often used to provide the most frequently used functions for an + * application. + */ + AccessibleRole.TOOL_BAR, + + /** + * An object that provides information about another object. The + * accessibleDescription property of the tool tip is often displayed + * to the user in a small "help bubble" when the user causes the + * mouse to hover over the object associated with the tool tip. + */ + AccessibleRole.TOOL_TIP, + + /** + * An AWT component, but nothing else is known about it. + * @see #SWING_COMPONENT + * @see #UNKNOWN + */ + AccessibleRole.AWT_COMPONENT, + + /** + * A Swing component, but nothing else is known about it. + * @see #AWT_COMPONENT + * @see #UNKNOWN + */ + AccessibleRole.SWING_COMPONENT, + + /** + * The object contains some Accessible information, but its role is + * not known. + * @see #AWT_COMPONENT + * @see #SWING_COMPONENT + */ + AccessibleRole.UNKNOWN, + + // These roles are only available in JDK 1.4 + + /** + * A STATUS_BAR is an simple component that can contain + * multiple labels of status information to the user. + AccessibleRole.STATUS_BAR, + + /** + * A DATE_EDITOR is a component that allows users to edit + * java.util.Date and java.util.Time objects + AccessibleRole.DATE_EDITOR, + + /** + * A SPIN_BOX is a simple spinner component and its main use + * is for simple numbers. + AccessibleRole.SPIN_BOX, + + /** + * A FONT_CHOOSER is a component that lets the user pick various + * attributes for fonts. + AccessibleRole.FONT_CHOOSER, + + /** + * A GROUP_BOX is a simple container that contains a border + * around it and contains components inside it. + AccessibleRole.GROUP_BOX + + /** + * Since JDK 1.5 + * + * A text header + + AccessibleRole.HEADER, + + /** + * A text footer + + AccessibleRole.FOOTER, + + /** + * A text paragraph + + AccessibleRole.PARAGRAPH, + + /** + * A ruler is an object used to measure distance + + AccessibleRole.RULER, + + /** + * A role indicating the object acts as a formula for + * calculating a value. An example is a formula in + * a spreadsheet cell. + AccessibleRole.EDITBAR + */ + }; + + /** + * This class implements accessibility support for the + * JTree child. It provides an implementation of the + * Java Accessibility API appropriate to tree nodes. + * + * Copied from JTree.java to work around a JTree bug where + * ActiveDescendent PropertyChangeEvents contain the wrong + * parent. + */ + /** + * This class in invoked on the EDT as its part of ActiveDescendant, + * hence the calls do not need to be specifically made on the EDT + */ + private class AccessibleJTreeNode extends AccessibleContext + implements Accessible, AccessibleComponent, AccessibleSelection, + AccessibleAction { + + private JTree tree = null; + private TreeModel treeModel = null; + private Object obj = null; + private TreePath path = null; + private Accessible accessibleParent = null; + private int index = 0; + private boolean isLeaf = false; + + /** + * Constructs an AccessibleJTreeNode + */ + AccessibleJTreeNode(JTree t, TreePath p, Accessible ap) { + tree = t; + path = p; + accessibleParent = ap; + if (t != null) + treeModel = t.getModel(); + if (p != null) { + obj = p.getLastPathComponent(); + if (treeModel != null && obj != null) { + isLeaf = treeModel.isLeaf(obj); + } + } + debugString("AccessibleJTreeNode: name = "+getAccessibleName()+"; TreePath = "+p+"; parent = "+ap); + } + + private TreePath getChildTreePath(int i) { + // Tree nodes can't be so complex that they have + // two sets of children -> we're ignoring that case + if (i < 0 || i >= getAccessibleChildrenCount() || path == null || treeModel == null) { + return null; + } else { + Object childObj = treeModel.getChild(obj, i); + Object[] objPath = path.getPath(); + Object[] objChildPath = new Object[objPath.length+1]; + java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length); + objChildPath[objChildPath.length-1] = childObj; + return new TreePath(objChildPath); + } + } + + /** + * Get the AccessibleContext associated with this tree node. + * In the implementation of the Java Accessibility API for + * this class, return this object, which is its own + * AccessibleContext. + * + * @return this object + */ + public AccessibleContext getAccessibleContext() { + return this; + } + + private AccessibleContext getCurrentAccessibleContext() { + Component c = getCurrentComponent(); + if (c instanceof Accessible) { + return (c.getAccessibleContext()); + } else { + return null; + } + } + + private Component getCurrentComponent() { + debugString("AccessibleJTreeNode: getCurrentComponent"); + // is the object visible? + // if so, get row, selected, focus & leaf state, + // and then get the renderer component and return it + if (tree != null && tree.isVisible(path)) { + TreeCellRenderer r = tree.getCellRenderer(); + if (r == null) { + debugString(" returning null 1"); + return null; + } + TreeUI ui = tree.getUI(); + if (ui != null) { + int row = ui.getRowForPath(tree, path); + boolean selected = tree.isPathSelected(path); + boolean expanded = tree.isExpanded(path); + boolean hasFocus = false; // how to tell?? -PK + Component retval = r.getTreeCellRendererComponent(tree, obj, + selected, expanded, + isLeaf, row, hasFocus); + debugString(" returning = "+retval.getClass()); + return retval; + } + } + debugString(" returning null 2"); + return null; + } + + // AccessibleContext methods + + /** + * Get the accessible name of this object. + * + * @return the localized name of the object; null if this + * object does not have a name + */ + public String getAccessibleName() { + debugString("AccessibleJTreeNode: getAccessibleName"); + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + String name = ac.getAccessibleName(); + if ((name != null) && (!name.isEmpty())) { + String retval = ac.getAccessibleName(); + debugString(" returning "+retval); + return retval; + } else { + return null; + } + } + if ((accessibleName != null) && (accessibleName.isEmpty())) { + return accessibleName; + } else { + return null; + } + } + + /** + * Set the localized accessible name of this object. + * + * @param s the new localized name of the object. + */ + public void setAccessibleName(String s) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + ac.setAccessibleName(s); + } else { + super.setAccessibleName(s); + } + } + + // + // *** should check tooltip text for desc. (needs MouseEvent) + // + /** + * Get the accessible description of this object. + * + * @return the localized description of the object; null if + * this object does not have a description + */ + public String getAccessibleDescription() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + return ac.getAccessibleDescription(); + } else { + return super.getAccessibleDescription(); + } + } + + /** + * Set the accessible description of this object. + * + * @param s the new localized description of the object + */ + public void setAccessibleDescription(String s) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + ac.setAccessibleDescription(s); + } else { + super.setAccessibleDescription(s); + } + } + + /** + * Get the role of this object. + * + * @return an instance of AccessibleRole describing the role of the object + * @see AccessibleRole + */ + public AccessibleRole getAccessibleRole() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + return ac.getAccessibleRole(); + } else { + return AccessibleRole.UNKNOWN; + } + } + + /** + * Get the state set of this object. + * + * @return an instance of AccessibleStateSet containing the + * current state set of the object + * @see AccessibleState + */ + public AccessibleStateSet getAccessibleStateSet() { + if (tree == null) + return null; + AccessibleContext ac = getCurrentAccessibleContext(); + AccessibleStateSet states; + int row = tree.getUI().getRowForPath(tree,path); + int lsr = tree.getLeadSelectionRow(); + if (ac != null) { + states = ac.getAccessibleStateSet(); + } else { + states = new AccessibleStateSet(); + } + // need to test here, 'cause the underlying component + // is a cellRenderer, which is never showing... + if (isShowing()) { + states.add(AccessibleState.SHOWING); + } else if (states.contains(AccessibleState.SHOWING)) { + states.remove(AccessibleState.SHOWING); + } + if (isVisible()) { + states.add(AccessibleState.VISIBLE); + } else if (states.contains(AccessibleState.VISIBLE)) { + states.remove(AccessibleState.VISIBLE); + } + if (tree.isPathSelected(path)){ + states.add(AccessibleState.SELECTED); + } + if (lsr == row) { + states.add(AccessibleState.ACTIVE); + } + if (!isLeaf) { + states.add(AccessibleState.EXPANDABLE); + } + if (tree.isExpanded(path)) { + states.add(AccessibleState.EXPANDED); + } else { + states.add(AccessibleState.COLLAPSED); + } + if (tree.isEditable()) { + states.add(AccessibleState.EDITABLE); + } + return states; + } + + /** + * Get the Accessible parent of this object. + * + * @return the Accessible parent of this object; null if this + * object does not have an Accessible parent + */ + public Accessible getAccessibleParent() { + // someone wants to know, so we need to create our parent + // if we don't have one (hey, we're a talented kid!) + if (accessibleParent == null && path != null) { + Object[] objPath = path.getPath(); + if (objPath.length > 1) { + Object objParent = objPath[objPath.length-2]; + if (treeModel != null) { + index = treeModel.getIndexOfChild(objParent, obj); + } + Object[] objParentPath = new Object[objPath.length-1]; + java.lang.System.arraycopy(objPath, 0, objParentPath, + 0, objPath.length-1); + TreePath parentPath = new TreePath(objParentPath); + accessibleParent = new AccessibleJTreeNode(tree, + parentPath, + null); + this.setAccessibleParent(accessibleParent); + } else if (treeModel != null) { + accessibleParent = tree; // we're the top! + index = 0; // we're an only child! + this.setAccessibleParent(accessibleParent); + } + } + return accessibleParent; + } + + /** + * Get the index of this object in its accessible parent. + * + * @return the index of this object in its parent; -1 if this + * object does not have an accessible parent. + * @see #getAccessibleParent + */ + public int getAccessibleIndexInParent() { + // index is invalid 'till we have an accessibleParent... + if (accessibleParent == null) { + getAccessibleParent(); + } + if (path != null) { + Object[] objPath = path.getPath(); + if (objPath.length > 1) { + Object objParent = objPath[objPath.length-2]; + if (treeModel != null) { + index = treeModel.getIndexOfChild(objParent, obj); + } + } + } + return index; + } + + /** + * Returns the number of accessible children in the object. + * + * @return the number of accessible children in the object. + */ + public int getAccessibleChildrenCount() { + // Tree nodes can't be so complex that they have + // two sets of children -> we're ignoring that case + if (obj != null && treeModel != null) { + return treeModel.getChildCount(obj); + } + return 0; + } + + /** + * Return the specified Accessible child of the object. + * + * @param i zero-based index of child + * @return the Accessible child of the object + */ + public Accessible getAccessibleChild(int i) { + // Tree nodes can't be so complex that they have + // two sets of children -> we're ignoring that case + if (i < 0 || i >= getAccessibleChildrenCount() || path == null || treeModel == null) { + return null; + } else { + Object childObj = treeModel.getChild(obj, i); + Object[] objPath = path.getPath(); + Object[] objChildPath = new Object[objPath.length+1]; + java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length); + objChildPath[objChildPath.length-1] = childObj; + TreePath childPath = new TreePath(objChildPath); + return new AccessibleJTreeNode(tree, childPath, this); + } + } + + /** + * Gets the locale of the component. If the component does not have + * a locale, then the locale of its parent is returned. + * + * @return This component's locale. If this component does not have + * a locale, the locale of its parent is returned. + * @exception IllegalComponentStateException + * If the Component does not have its own locale and has not yet + * been added to a containment hierarchy such that the locale can be + * determined from the containing parent. + * @see #setLocale + */ + public Locale getLocale() { + if (tree == null) + return null; + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + return ac.getLocale(); + } else { + return tree.getLocale(); + } + } + + /** + * Add a PropertyChangeListener to the listener list. + * The listener is registered for all properties. + * + * @param l The PropertyChangeListener to be added + */ + public void addPropertyChangeListener(PropertyChangeListener l) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + ac.addPropertyChangeListener(l); + } else { + super.addPropertyChangeListener(l); + } + } + + /** + * Remove a PropertyChangeListener from the listener list. + * This removes a PropertyChangeListener that was registered + * for all properties. + * + * @param l The PropertyChangeListener to be removed + */ + public void removePropertyChangeListener(PropertyChangeListener l) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + ac.removePropertyChangeListener(l); + } else { + super.removePropertyChangeListener(l); + } + } + + /** + * Get the AccessibleAction associated with this object. In the + * implementation of the Java Accessibility API for this class, + * return this object, which is responsible for implementing the + * AccessibleAction interface on behalf of itself. + * + * @return this object + */ + public AccessibleAction getAccessibleAction() { + return this; + } + + /** + * Get the AccessibleComponent associated with this object. In the + * implementation of the Java Accessibility API for this class, + * return this object, which is responsible for implementing the + * AccessibleComponent interface on behalf of itself. + * + * @return this object + */ + public AccessibleComponent getAccessibleComponent() { + return this; // to override getBounds() + } + + /** + * Get the AccessibleSelection associated with this object if one + * exists. Otherwise return null. + * + * @return the AccessibleSelection, or null + */ + public AccessibleSelection getAccessibleSelection() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null && isLeaf) { + return getCurrentAccessibleContext().getAccessibleSelection(); + } else { + return this; + } + } + + /** + * Get the AccessibleText associated with this object if one + * exists. Otherwise return null. + * + * @return the AccessibleText, or null + */ + public AccessibleText getAccessibleText() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + return getCurrentAccessibleContext().getAccessibleText(); + } else { + return null; + } + } + + /** + * Get the AccessibleValue associated with this object if one + * exists. Otherwise return null. + * + * @return the AccessibleValue, or null + */ + public AccessibleValue getAccessibleValue() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + return getCurrentAccessibleContext().getAccessibleValue(); + } else { + return null; + } + } + + + // AccessibleComponent methods + + /** + * Get the background color of this object. + * + * @return the background color, if supported, of the object; + * otherwise, null + */ + public Color getBackground() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getBackground(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.getBackground(); + } else { + return null; + } + } + } + + /** + * Set the background color of this object. + * + * @param c the new Color for the background + */ + public void setBackground(Color c) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setBackground(c); + } else { + Component cp = getCurrentComponent(); + if ( cp != null) { + cp.setBackground(c); + } + } + } + + + /** + * Get the foreground color of this object. + * + * @return the foreground color, if supported, of the object; + * otherwise, null + */ + public Color getForeground() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getForeground(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.getForeground(); + } else { + return null; + } + } + } + + public void setForeground(Color c) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setForeground(c); + } else { + Component cp = getCurrentComponent(); + if (cp != null) { + cp.setForeground(c); + } + } + } + + public Cursor getCursor() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getCursor(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.getCursor(); + } else { + Accessible ap = getAccessibleParent(); + if (ap instanceof AccessibleComponent) { + return ((AccessibleComponent) ap).getCursor(); + } else { + return null; + } + } + } + } + + public void setCursor(Cursor c) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setCursor(c); + } else { + Component cp = getCurrentComponent(); + if (cp != null) { + cp.setCursor(c); + } + } + } + + public Font getFont() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getFont(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.getFont(); + } else { + return null; + } + } + } + + public void setFont(Font f) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setFont(f); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.setFont(f); + } + } + } + + public FontMetrics getFontMetrics(Font f) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getFontMetrics(f); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.getFontMetrics(f); + } else { + return null; + } + } + } + + public boolean isEnabled() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).isEnabled(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.isEnabled(); + } else { + return false; + } + } + } + + public void setEnabled(boolean b) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setEnabled(b); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.setEnabled(b); + } + } + } + + public boolean isVisible() { + if (tree == null) + return false; + Rectangle pathBounds = tree.getPathBounds(path); + Rectangle parentBounds = tree.getVisibleRect(); + if ( pathBounds != null && parentBounds != null && + parentBounds.intersects(pathBounds) ) { + return true; + } else { + return false; + } + } + + public void setVisible(boolean b) { + } + + public boolean isShowing() { + return (tree.isShowing() && isVisible()); + } + + public boolean contains(Point p) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + Rectangle r = ((AccessibleComponent) ac).getBounds(); + return r.contains(p); + } else { + Component c = getCurrentComponent(); + if (c != null) { + Rectangle r = c.getBounds(); + return r.contains(p); + } else { + return getBounds().contains(p); + } + } + } + + public Point getLocationOnScreen() { + if (tree != null) { + Point treeLocation = tree.getLocationOnScreen(); + Rectangle pathBounds = tree.getPathBounds(path); + if (treeLocation != null && pathBounds != null) { + Point nodeLocation = new Point(pathBounds.x, + pathBounds.y); + nodeLocation.translate(treeLocation.x, treeLocation.y); + return nodeLocation; + } else { + return null; + } + } else { + return null; + } + } + + private Point getLocationInJTree() { + Rectangle r = tree.getPathBounds(path); + if (r != null) { + return r.getLocation(); + } else { + return null; + } + } + + public Point getLocation() { + Rectangle r = getBounds(); + if (r != null) { + return r.getLocation(); + } else { + return null; + } + } + + public void setLocation(Point p) { + } + + public Rectangle getBounds() { + if (tree == null) + return null; + Rectangle r = tree.getPathBounds(path); + Accessible parent = getAccessibleParent(); + if (parent instanceof AccessibleJTreeNode) { + Point parentLoc = ((AccessibleJTreeNode) parent).getLocationInJTree(); + if (parentLoc != null && r != null) { + r.translate(-parentLoc.x, -parentLoc.y); + } else { + return null; // not visible! + } + } + return r; + } + + public void setBounds(Rectangle r) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setBounds(r); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.setBounds(r); + } + } + } + + public Dimension getSize() { + return getBounds().getSize(); + } + + public void setSize (Dimension d) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setSize(d); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.setSize(d); + } + } + } + + /** + * Returns the Accessible child, if one exists, + * contained at the local coordinate Point. + * Otherwise returns null. + * + * @param p point in local coordinates of this + * Accessible + * @return the Accessible, if it exists, + * at the specified location; else null + */ + public Accessible getAccessibleAt(Point p) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getAccessibleAt(p); + } else { + return null; + } + } + + public boolean isFocusTraversable() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).isFocusTraversable(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.isFocusable(); + } else { + return false; + } + } + } + + public void requestFocus() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).requestFocus(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.requestFocus(); + } + } + } + + public void addFocusListener(FocusListener l) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).addFocusListener(l); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.addFocusListener(l); + } + } + } + + public void removeFocusListener(FocusListener l) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).removeFocusListener(l); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.removeFocusListener(l); + } + } + } + + // AccessibleSelection methods + + /** + * Returns the number of items currently selected. + * If no items are selected, the return value will be 0. + * + * @return the number of items currently selected. + */ + public int getAccessibleSelectionCount() { + int count = 0; + int childCount = getAccessibleChildrenCount(); + for (int i = 0; i < childCount; i++) { + TreePath childPath = getChildTreePath(i); + if (tree.isPathSelected(childPath)) { + count++; + } + } + return count; + } + + /** + * Returns an Accessible representing the specified selected item + * in the object. If there isn't a selection, or there are + * fewer items selected than the integer passed in, the return + * value will be null. + * + * @param i the zero-based index of selected items + * @return an Accessible containing the selected item + */ + public Accessible getAccessibleSelection(int i) { + int childCount = getAccessibleChildrenCount(); + if (i < 0 || i >= childCount) { + return null; // out of range + } + int count = 0; + for (int j = 0; j < childCount && i >= count; j++) { + TreePath childPath = getChildTreePath(j); + if (tree.isPathSelected(childPath)) { + if (count == i) { + return new AccessibleJTreeNode(tree, childPath, this); + } else { + count++; + } + } + } + return null; + } + + /** + * Returns true if the current child of this object is selected. + * + * @param i the zero-based index of the child in this Accessible + * object. + * @see AccessibleContext#getAccessibleChild + */ + public boolean isAccessibleChildSelected(int i) { + int childCount = getAccessibleChildrenCount(); + if (i < 0 || i >= childCount) { + return false; // out of range + } else { + TreePath childPath = getChildTreePath(i); + return tree.isPathSelected(childPath); + } + } + + /** + * Adds the specified selected item in the object to the object's + * selection. If the object supports multiple selections, + * the specified item is added to any existing selection, otherwise + * it replaces any existing selection in the object. If the + * specified item is already selected, this method has no effect. + * + * @param i the zero-based index of selectable items + */ + public void addAccessibleSelection(int i) { + if (tree == null) + return; + TreeModel model = tree.getModel(); + if (model != null) { + if (i >= 0 && i < getAccessibleChildrenCount()) { + TreePath path = getChildTreePath(i); + tree.addSelectionPath(path); + } + } + } + + /** + * Removes the specified selected item in the object from the + * object's + * selection. If the specified item isn't currently selected, this + * method has no effect. + * + * @param i the zero-based index of selectable items + */ + public void removeAccessibleSelection(int i) { + if (tree == null) + return; + TreeModel model = tree.getModel(); + if (model != null) { + if (i >= 0 && i < getAccessibleChildrenCount()) { + TreePath path = getChildTreePath(i); + tree.removeSelectionPath(path); + } + } + } + + /** + * Clears the selection in the object, so that nothing in the + * object is selected. + */ + public void clearAccessibleSelection() { + int childCount = getAccessibleChildrenCount(); + for (int i = 0; i < childCount; i++) { + removeAccessibleSelection(i); + } + } + + /** + * Causes every selected item in the object to be selected + * if the object supports multiple selections. + */ + public void selectAllAccessibleSelection() { + if (tree == null) + return; + TreeModel model = tree.getModel(); + if (model != null) { + int childCount = getAccessibleChildrenCount(); + TreePath path; + for (int i = 0; i < childCount; i++) { + path = getChildTreePath(i); + tree.addSelectionPath(path); + } + } + } + + // AccessibleAction methods + + /** + * Returns the number of accessible actions available in this + * tree node. If this node is not a leaf, there is at least + * one action (toggle expand), in addition to any available + * on the object behind the TreeCellRenderer. + * + * @return the number of Actions in this object + */ + public int getAccessibleActionCount() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa != null) { + return (aa.getAccessibleActionCount() + (isLeaf ? 0 : 1)); + } + } + return isLeaf ? 0 : 1; + } + + /** + * Return a description of the specified action of the tree node. + * If this node is not a leaf, there is at least one action + * description (toggle expand), in addition to any available + * on the object behind the TreeCellRenderer. + * + * @param i zero-based index of the actions + * @return a description of the action + */ + public String getAccessibleActionDescription(int i) { + if (i < 0 || i >= getAccessibleActionCount()) { + return null; + } + AccessibleContext ac = getCurrentAccessibleContext(); + if (i == 0) { + // TIGER - 4766636 + // return AccessibleAction.TOGGLE_EXPAND; + return "toggle expand"; + } else if (ac != null) { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa != null) { + return aa.getAccessibleActionDescription(i - 1); + } + } + return null; + } + + /** + * Perform the specified Action on the tree node. If this node + * is not a leaf, there is at least one action which can be + * done (toggle expand), in addition to any available on the + * object behind the TreeCellRenderer. + * + * @param i zero-based index of actions + * @return true if the the action was performed; else false. + */ + public boolean doAccessibleAction(int i) { + if (i < 0 || i >= getAccessibleActionCount()) { + return false; + } + AccessibleContext ac = getCurrentAccessibleContext(); + if (i == 0) { + if (tree.isExpanded(path)) { + tree.collapsePath(path); + } else { + tree.expandPath(path); + } + return true; + } else if (ac != null) { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa != null) { + return aa.doAccessibleAction(i - 1); + } + } + return false; + } + + } // inner class AccessibleJTreeNode + + /** + * A helper class to perform {@code Callable} objects on the event dispatch thread appropriate + * for the provided {@code AccessibleContext}. + */ + private static class InvocationUtils { + + /** + * Invokes a {@code Callable} in the {@code AppContext} of the given {@code Accessible} + * and waits for it to finish blocking the caller thread. + * + * @param callable the {@code Callable} to invoke + * @param accessible the {@code Accessible} which would be used to find the right context + * for the task execution + * @param type parameter for the result value + * + * @return the result of the {@code Callable} execution + */ + public static T invokeAndWait(final Callable callable, + final Accessible accessible) { + if (accessible instanceof Component) { + return invokeAndWait(callable, (Component)accessible); + } + if (accessible instanceof AccessibleContext) { + // This case also covers the Translator + return invokeAndWait(callable, (AccessibleContext)accessible); + } + throw new RuntimeException("Unmapped Accessible used to dispatch event: " + accessible); + } + + /** + * Invokes a {@code Callable} in the {@code AppContext} of the given {@code Component} + * and waits for it to finish blocking the caller thread. + * + * @param callable the {@code Callable} to invoke + * @param component the {@code Component} which would be used to find the right context + * for the task execution + * @param type parameter for the result value + * + * @return the result of the {@code Callable} execution + */ + public static T invokeAndWait(final Callable callable, + final Component component) { + return invokeAndWait(callable, SunToolkit.targetToAppContext(component)); + } + + /** + * Invokes a {@code Callable} in the {@code AppContext} mapped to the given {@code AccessibleContext} + * and waits for it to finish blocking the caller thread. + * + * @param callable the {@code Callable} to invoke + * @param accessibleContext the {@code AccessibleContext} which would be used to determine the right + * context for the task execution. + * @param type parameter for the result value + * + * @return the result of the {@code Callable} execution + */ + public static T invokeAndWait(final Callable callable, + final AccessibleContext accessibleContext) { + AppContext targetContext = AWTAccessor.getAccessibleContextAccessor() + .getAppContext(accessibleContext); + if (targetContext != null) { + return invokeAndWait(callable, targetContext); + } else { + // Normally this should not happen, unmapped context provided and + // the target AppContext is unknown. + + // Try to recover in case the context is a translator. + if (accessibleContext instanceof Translator) { + Object source = ((Translator)accessibleContext).getSource(); + if (source instanceof Component) { + return invokeAndWait(callable, (Component)source); + } + } + } + throw new RuntimeException("Unmapped AccessibleContext used to dispatch event: " + accessibleContext); + } + + private static T invokeAndWait(final Callable callable, + final AppContext targetAppContext) { + final CallableWrapper wrapper = new CallableWrapper(callable); + try { + invokeAndWait(wrapper, targetAppContext); + T result = wrapper.getResult(); + updateAppContextMap(result, targetAppContext); + return result; + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + + private static void invokeAndWait(final Runnable runnable, + final AppContext appContext) + throws InterruptedException, InvocationTargetException { + + EventQueue eq = SunToolkit.getSystemEventQueueImplPP(appContext); + Object lock = new Object(); + Toolkit source = Toolkit.getDefaultToolkit(); + InvocationEvent event = + new InvocationEvent(source, runnable, lock, true); + synchronized (lock) { + eq.postEvent(event); + lock.wait(); + } + + Throwable eventThrowable = event.getThrowable(); + if (eventThrowable != null) { + throw new InvocationTargetException(eventThrowable); + } + } + + /** + * Maps the {@code AccessibleContext} to the {@code AppContext} which should be used + * to dispatch events related to the {@code AccessibleContext} + * @param accessibleContext the {@code AccessibleContext} for the mapping + * @param targetContext the {@code AppContext} for the mapping + */ + public static void registerAccessibleContext(final AccessibleContext accessibleContext, + final AppContext targetContext) { + if (accessibleContext != null) { + AWTAccessor.getAccessibleContextAccessor().setAppContext(accessibleContext, targetContext); + } + } + + private static void updateAppContextMap(final T accessibleContext, + final AppContext targetContext) { + if (accessibleContext instanceof AccessibleContext) { + registerAccessibleContext((AccessibleContext)accessibleContext, targetContext); + } + } + + private static class CallableWrapper implements Runnable { + private final Callable callable; + private volatile T object; + private Exception e; + + CallableWrapper(final Callable callable) { + this.callable = callable; + } + + public void run() { + try { + if (callable != null) { + object = callable.call(); + } + } catch (final Exception e) { + this.e = e; + } + } + + T getResult() throws Exception { + if (e != null) + throw e; + return object; + } + } + } +} --- /dev/null 2015-03-30 10:53:33.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRelation.java 2015-03-30 10:53:32.069298700 -0500 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +package com.sun.java.accessibility.extensions; + +import javax.accessibility.*; + +/** + *

Class AccessibleExtendedRelation contains extensions to the class + * AccessibleRelation that are currently not in a public API. + * + *

Class AccessibleRelation describes a relation between the + * object that implements the AccessibleRelation and one or more other + * objects. The actual relations that an object has with other + * objects are defined as an AccessibleRelationSet, which is a composed + * set of AccessibleRelations. + *

The toDisplayString method allows you to obtain the localized string + * for a locale independent key from a predefined ResourceBundle for the + * keys defined in this class. + *

The constants in this class present a strongly typed enumeration + * of common object roles. If the constants in this class are not sufficient + * to describe the role of an object, a subclass should be generated + * from this class and it should provide constants in a similar manner. + * + */ + +public class AccessibleExtendedRelation + extends AccessibleExtendedRelationConstants { + + public AccessibleExtendedRelation(String s) { + super(s); + } + + public AccessibleExtendedRelation(String key, Object target) { + super(key, target); + } +} --- /dev/null 2015-03-30 10:53:36.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRelationConstants.java 2015-03-30 10:53:35.202309400 -0500 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +package com.sun.java.accessibility.extensions; + +import javax.accessibility.*; + +/** + *

Class AccessibleExtendedRelation contains extensions to the class + * AccessibleRelation that are currently not in a public API. + * + *

Class AccessibleRelation describes a relation between the + * object that implements the AccessibleRelation and one or more other + * objects. The actual relations that an object has with other + * objects are defined as an AccessibleRelationSet, which is a composed + * set of AccessibleRelations. + *

The toDisplayString method allows you to obtain the localized string + * for a locale independent key from a predefined ResourceBundle for the + * keys defined in this class. + *

The constants in this class present a strongly typed enumeration + * of common object roles. If the constants in this class are not sufficient + * to describe the role of an object, a subclass should be generated + * from this class and it should provide constants in a similar manner. + * + */ + +public abstract class AccessibleExtendedRelationConstants + extends AccessibleRelation { + + /** + * Indicates that one AccessibleText object is linked to the + * target AccessibleText object(s).

A good example is a StarOffice + * text window with the bottom of one page, a footer, a header, + * and the top of another page all visible in the window. There + * should be a FLOWS_TO relation from the last chunk of AccessibleText + * in the bottom of one page to the first AccessibleText object at the + * top of the next page, skipping over the AccessibleText object(s) + * that make up the header and footer. A corresponding FLOWS_FROM + * relation would link the AccessibleText object in the next page to + * the last one in the previous page. + * @see AccessibleExtendedRole.FLOWS_FROM + */ + public static final String FLOWS_TO = "flowsTo"; + + /** + * Indicates that one AccessibleText object is linked to the + * target AccessibleText object(s). + * @see AccessibleExtendedRole.FLOWS_TO + */ + public static final String FLOWS_FROM = "flowsFrom"; + + /** + * Indicates a component is a subwindow of a target component + */ + public static final String SUBWINDOW_OF = "subwindowOf"; + + /** + * Identifies that the linkage between one AccessibleText + * object and the target AccessibleText object(s) has changed. + * @see AccessibleExtendedRole.FLOWS_TO + * @see AccessibleExtendedRole.FLOWS_FROM + */ + public static final String FLOWS_TO_PROPERTY = "flowsToProperty"; + + /** + * Identifies that the linkage between one AccessibleText + * object and the target AccessibleText object(s) has changed. + * @see AccessibleExtendedRole.FLOWS_TO + * @see AccessibleExtendedRole.FLOWS_FROM + */ + public static final String FLOWS_FROM_PROPERTY = "flowsFromProperty"; + + /** + * Identifies the subwindow relationship between two components + * has changed + */ + public static final String SUBWINDOW_OF_PROPERTY = "subwindowOfProperty"; + + public AccessibleExtendedRelationConstants(String s) { + super(s); + } + + public AccessibleExtendedRelationConstants(String key, Object target) { + super(key, target); + } +} --- /dev/null 2015-03-30 10:53:39.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRole.java 2015-03-30 10:53:38.309317500 -0500 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +package com.sun.java.accessibility.extensions; + +import javax.accessibility.*; + +/** + *

Class AccessibleExtendedRole contains extensions to the class + * AccessibleRole that are currently not in a public API. + * + *

Class AccessibleRole determines the role of a component. The role + * of a component describes its generic function. (E.G., + * "push button," "table," or "list.") + *

The constants in this class present a strongly typed enumeration + * of common object roles. A public constructor for this class has been + * purposely omitted and applications should use one of the constants + * from this class. If the constants in this class are not sufficient + * to describe the role of an object, a subclass should be generated + * from this class and it should provide constants in a similar manner. + * + */ + +public class AccessibleExtendedRole extends AccessibleExtendedRoleConstants { + + public AccessibleExtendedRole(String s) { + super(s); + } +} --- /dev/null 2015-03-30 10:53:42.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRoleConstants.java 2015-03-30 10:53:41.701341900 -0500 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +package com.sun.java.accessibility.extensions; + +import javax.accessibility.*; + +/** + *

Class AccessibleExtendedRole contains extensions to the class + * AccessibleRole that are currently not in a public API. + * + *

Class AccessibleRole determines the role of a component. The role + * of a component describes its generic function. (E.G., + * "push button," "table," or "list.") + *

The constants in this class present a strongly typed enumeration + * of common object roles. A public constructor for this class has been + * purposely omitted and applications should use one of the constants + * from this class. If the constants in this class are not sufficient + * to describe the role of an object, a subclass should be generated + * from this class and it should provide constants in a similar manner. + * + */ + +public abstract class AccessibleExtendedRoleConstants extends AccessibleRole { + + /** + * Indicates this component is a text header. + */ + public static final AccessibleExtendedRole HEADER + = new AccessibleExtendedRole("Header"); + + /** + * Indicates this component is a text footer. + */ + public static final AccessibleExtendedRole FOOTER + = new AccessibleExtendedRole("Footer"); + + /** + * Indicates this component is a text paragraph. + */ + public static final AccessibleExtendedRole PARAGRAPH + = new AccessibleExtendedRole("Paragraph"); + + /** + * Indicates this component is a ruler. + */ + public static final AccessibleExtendedRole RULER + = new AccessibleExtendedRole("RULER"); + + public AccessibleExtendedRoleConstants(String s) { + super(s); + } +} --- /dev/null 2015-03-30 10:53:46.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedState.java 2015-03-30 10:53:45.031360000 -0500 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +package com.sun.java.accessibility.extensions; + +import javax.accessibility.*; + +/** + *

Class AccessibleState describes a component's particular state. The actual + * state of the component is defined as an AccessibleStateSet, which is a + * composed set of AccessibleStates. + *

The toDisplayString method allows you to obtain the localized string + * for a locale independent key from a predefined ResourceBundle for the + * keys defined in this class. + *

The constants in this class present a strongly typed enumeration + * of common object roles. A public constructor for this class has been + * purposely omitted and applications should use one of the constants + * from this class. If the constants in this class are not sufficient + * to describe the role of an object, a subclass should be generated + * from this class and it should provide constants in a similar manner. + * + */ + +public abstract class AccessibleExtendedState + extends AccessibleExtendedStateConstants { + + public AccessibleExtendedState(String s) { + super(s); + } +} --- /dev/null 2015-03-30 10:53:49.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedStateConstants.java 2015-03-30 10:53:48.252367900 -0500 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +package com.sun.java.accessibility.extensions; + +import javax.accessibility.*; + +/** + *

Class AccessibleState describes a component's particular state. The actual + * state of the component is defined as an AccessibleStateSet, which is a + * composed set of AccessibleStates. + *

The toDisplayString method allows you to obtain the localized string + * for a locale independent key from a predefined ResourceBundle for the + * keys defined in this class. + *

The constants in this class present a strongly typed enumeration + * of common object roles. A public constructor for this class has been + * purposely omitted and applications should use one of the constants + * from this class. If the constants in this class are not sufficient + * to describe the role of an object, a subclass should be generated + * from this class and it should provide constants in a similar manner. + * + */ + +public abstract class AccessibleExtendedStateConstants extends AccessibleState { + + /** + * Indicates a component is responsible for managing + * its subcomponents. + */ + public static final AccessibleExtendedState MANAGES_DESCENDENTS + = new AccessibleExtendedState("managesDescendents"); + + public AccessibleExtendedStateConstants(String s) { + super(s); + } +} --- /dev/null 2015-03-30 10:53:52.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/legacy/AccessBridgeLoader.java 2015-03-30 10:53:51.586382200 -0500 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package com.sun.java.accessibility; + +@jdk.Exported(false) +abstract class AccessBridgeLoader { + + /** + * Load JavaAccessBridge.DLL (our native half) + */ + static { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + System.loadLibrary("JavaAccessBridge"); + return null; + } + }, null, new RuntimePermission("loadLibrary.JavaAccessBridge") + ); + } + + boolean useJAWT_DLL = false; + + /** + * AccessBridgeLoader constructor + */ + AccessBridgeLoader() { + String version = System.getProperty("java.version"); + if (version != null) + useJAWT_DLL = (version.compareTo("1.4.1") >= 0); + + // load JAWTAccessBridge.DLL on JDK 1.4.1 or later + if (useJAWT_DLL) { + // Note that we have to explicitly load JAWT.DLL + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + System.loadLibrary("JAWT"); + System.loadLibrary("JAWTAccessBridge"); + return null; + } + }, null, new RuntimePermission("loadLibrary.JAWT"), + new RuntimePermission("loadLibrary.JAWTAccessBridge") + ); + } + } +} --- /dev/null 2015-03-30 10:53:55.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/AWTEventMonitor.java 2015-03-30 10:53:54.919407200 -0500 @@ -0,0 +1,1495 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import javax.accessibility.*; +import javax.swing.*; +import javax.swing.event.*; +import sun.security.util.SecurityConstants.AWT; + +/** + *

The {@code AWTEventMonitor} implements a suite of listeners that are + * conditionally installed on every AWT component instance in the Java + * Virtual Machine. The events captured by these listeners are made + * available through a unified set of listeners supported by {@code AWTEventMonitor}. + * With this, all the individual events on each of the AWT component + * instances are funneled into one set of listeners broken down by category + * (see {@link EventID} for the categories). + *

This class depends upon {@link EventQueueMonitor}, which provides the base + * level support for capturing the top-level containers as they are created. + */ + +@jdk.Exported +public class AWTEventMonitor { + + static private boolean runningOnJDK1_4 = false; + + /** + * The current component with keyboard focus. + * + * @see #getComponentWithFocus + * + * @deprecated This field is unused; to get the component with focus use the + * getComponentWithFocus method. + */ + @Deprecated + static protected Component componentWithFocus = null; + + static private Component componentWithFocus_private = null; + + // Low-level listeners + /** + * The current list of registered ComponentListener classes. + * + * @see #addComponentListener + * @see #removeComponentListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected ComponentListener componentListener = null; + + static private ComponentListener componentListener_private = null; + + /** + * The current list of registered ContainerListener classes. + * + * @see #addContainerListener + * @see #removeContainerListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected ContainerListener containerListener = null; + + static private ContainerListener containerListener_private = null; + + /** + * The current list of registered FocusListener classes. + * + * @see #addFocusListener + * @see #removeFocusListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected FocusListener focusListener = null; + + static private FocusListener focusListener_private = null; + + /** + * The current list of registered KeyListener classes. + * + * @see #addKeyListener + * @see #removeKeyListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected KeyListener keyListener = null; + + static private KeyListener keyListener_private = null; + + /** + * The current list of registered MouseListener classes. + * + * @see #addMouseListener + * @see #removeMouseListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected MouseListener mouseListener = null; + + static private MouseListener mouseListener_private = null; + + /** + * The current list of registered MouseMotionListener classes. + * + * @see #addMouseMotionListener + * @see #removeMouseMotionListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected MouseMotionListener mouseMotionListener = null; + + static private MouseMotionListener mouseMotionListener_private = null; + + /** + * The current list of registered WindowListener classes. + * + * @see #addWindowListener + * @see #removeWindowListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected WindowListener windowListener = null; + + static private WindowListener windowListener_private = null; + + + // Semantic listeners + /** + * The current list of registered ActionListener classes. + * + * @see #addActionListener + * @see #removeActionListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected ActionListener actionListener = null; + + static private ActionListener actionListener_private = null; + + /** + * The current list of registered AdjustmentListener classes. + * + * @see #addAdjustmentListener + * @see #removeAdjustmentListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected AdjustmentListener adjustmentListener = null; + + static private AdjustmentListener adjustmentListener_private = null; + + /** + * The current list of registered ItemListener classes. + * + * @see #addItemListener + * @see #removeItemListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected ItemListener itemListener = null; + + static private ItemListener itemListener_private = null; + + /** + * The current list of registered TextListener classes. + * + * @see #addTextListener + * @see #removeTextListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected TextListener textListener = null; + + static private TextListener textListener_private = null; + + + /** + * The actual listener that is installed on the component instances. + * This listener calls the other registered listeners when an event + * occurs. By doing things this way, the actual number of listeners + * installed on a component instance is drastically reduced. + * + * @deprecated This field is unused. + */ + @Deprecated + static protected AWTEventsListener awtListener = new AWTEventsListener(); + + static private final AWTEventsListener awtListener_private = new AWTEventsListener(); + + /** + * Returns the component that currently has keyboard focus. The return + * value can be null. + * + * @return the component that has keyboard focus + */ + static public Component getComponentWithFocus() { + return componentWithFocus_private; + } + + /* + * Check permissions + */ + static private void checkInstallPermission() { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPermission(AWT.ALL_AWT_EVENTS_PERMISSION); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#COMPONENT COMPONENT} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeComponentListener + */ + static public void addComponentListener(ComponentListener l) { + if (componentListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.COMPONENT); + } + componentListener_private = AWTEventMulticaster.add(componentListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#COMPONENT COMPONENT} events when they occur. + * + * @param l the listener to remove + * @see #addComponentListener + */ + static public void removeComponentListener(ComponentListener l) { + componentListener_private = AWTEventMulticaster.remove(componentListener_private, l); + if (componentListener_private == null) { + awtListener_private.removeListeners(EventID.COMPONENT); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#CONTAINER CONTAINER} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeContainerListener + */ + static public void addContainerListener(ContainerListener l) { + containerListener_private = AWTEventMulticaster.add(containerListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#CONTAINER CONTAINER} events when they occur. + * + * @param l the listener to remove + * @see #addContainerListener + */ + static public void removeContainerListener(ContainerListener l) { + containerListener_private = AWTEventMulticaster.remove(containerListener_private, l); + } + + /** + * Adds the specified listener to receive all {@link EventID#FOCUS FOCUS} events + * on each component instance in the Java Virtual Machine when they occur. + *

Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeFocusListener + */ + static public void addFocusListener(FocusListener l) { + focusListener_private = AWTEventMulticaster.add(focusListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives {@link EventID#FOCUS FOCUS} + * events when they occur. + * + * @param l the listener to remove + * @see #addFocusListener + */ + static public void removeFocusListener(FocusListener l) { + focusListener_private = AWTEventMulticaster.remove(focusListener_private, l); + } + + /** + * Adds the specified listener to receive all {@link EventID#KEY KEY} events on each + * component instance in the Java Virtual Machine when they occur. + *

Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeKeyListener + */ + static public void addKeyListener(KeyListener l) { + if (keyListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.KEY); + } + keyListener_private = AWTEventMulticaster.add(keyListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives {@link EventID#KEY KEY} + * events when they occur. + * + * @param l the listener to remove + * @see #addKeyListener + */ + static public void removeKeyListener(KeyListener l) { + keyListener_private = AWTEventMulticaster.remove(keyListener_private, l); + if (keyListener_private == null) { + awtListener_private.removeListeners(EventID.KEY); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#MOUSE MOUSE} events + * on each component instance in the Java Virtual Machine when they occur. + *

Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeMouseListener + */ + static public void addMouseListener(MouseListener l) { + if (mouseListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.MOUSE); + } + mouseListener_private = AWTEventMulticaster.add(mouseListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#MOUSE MOUSE} events when they occur. + * + * @param l the listener to remove + * @see #addMouseListener + */ + static public void removeMouseListener(MouseListener l) { + mouseListener_private = AWTEventMulticaster.remove(mouseListener_private, l); + if (mouseListener_private == null) { + awtListener_private.removeListeners(EventID.MOUSE); + } + } + + /** + * Adds the specified listener to receive all mouse {@link EventID#MOTION MOTION} + * events on each component instance in the Java Virtual Machine when they occur. + *

Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeMouseMotionListener + */ + static public void addMouseMotionListener(MouseMotionListener l) { + if (mouseMotionListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.MOTION); + } + mouseMotionListener_private = AWTEventMulticaster.add(mouseMotionListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#MOTION MOTION} events when they occur. + * + * @param l the listener to remove + * @see #addMouseMotionListener + */ + static public void removeMouseMotionListener(MouseMotionListener l) { + mouseMotionListener_private = AWTEventMulticaster.remove(mouseMotionListener_private, l); + if (mouseMotionListener_private == null) { + awtListener_private.removeListeners(EventID.MOTION); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#WINDOW WINDOW} + * events on each component instance in the Java Virtual Machine when they occur. + *

Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeWindowListener + */ + static public void addWindowListener(WindowListener l) { + if (windowListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.WINDOW); + } + windowListener_private = AWTEventMulticaster.add(windowListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#WINDOW WINDOW} events when they occur. + * + * @param l the listener to remove + * @see #addWindowListener + */ + static public void removeWindowListener(WindowListener l) { + windowListener_private = AWTEventMulticaster.remove(windowListener_private, l); + if (windowListener_private == null) { + awtListener_private.removeListeners(EventID.WINDOW); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#ACTION ACTION} + * events on each component instance in the Java Virtual Machine when they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeActionListener + */ + static public void addActionListener(ActionListener l) { + if (actionListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.ACTION); + } + actionListener_private = AWTEventMulticaster.add(actionListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#ACTION ACTION} events when they occur. + * + * @param l the listener to remove + * @see #addActionListener + */ + static public void removeActionListener(ActionListener l) { + actionListener_private = AWTEventMulticaster.remove(actionListener_private, l); + if (actionListener_private == null) { + awtListener_private.removeListeners(EventID.ACTION); + } + } + + /** + * Adds the specified listener to receive all + * {@link EventID#ADJUSTMENT ADJUSTMENT} events on each component instance + * in the Java Virtual Machine when they occur. + *

Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeAdjustmentListener + */ + static public void addAdjustmentListener(AdjustmentListener l) { + if (adjustmentListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.ADJUSTMENT); + } + adjustmentListener_private = AWTEventMulticaster.add(adjustmentListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#ADJUSTMENT ADJUSTMENT} events when they occur. + * + * @param l the listener to remove + * @see #addAdjustmentListener + */ + static public void removeAdjustmentListener(AdjustmentListener l) { + adjustmentListener_private = AWTEventMulticaster.remove(adjustmentListener_private, l); + if (adjustmentListener_private == null) { + awtListener_private.removeListeners(EventID.ADJUSTMENT); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#ITEM ITEM} events + * on each component instance in the Java Virtual Machine when they occur. + *

Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeItemListener + */ + static public void addItemListener(ItemListener l) { + if (itemListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.ITEM); + } + itemListener_private = AWTEventMulticaster.add(itemListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives {@link EventID#ITEM ITEM} + * events when they occur. + * + * @param l the listener to remove + * @see #addItemListener + */ + static public void removeItemListener(ItemListener l) { + itemListener_private = AWTEventMulticaster.remove(itemListener_private, l); + if (itemListener_private == null) { + awtListener_private.removeListeners(EventID.ITEM); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#TEXT TEXT} events + * on each component instance in the Java Virtual Machine when they occur. + *

Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeTextListener + */ + static public void addTextListener(TextListener l) { + if (textListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.TEXT); + } + textListener_private = AWTEventMulticaster.add(textListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives {@link EventID#TEXT TEXT} + * events when they occur. + * + * @param l the listener to remove + * @see #addTextListener + */ + static public void removeTextListener(TextListener l) { + textListener_private = AWTEventMulticaster.remove(textListener_private, l); + if (textListener_private == null) { + awtListener_private.removeListeners(EventID.TEXT); + } + } + + + /** + * AWTEventsListener is the class that does all the work for AWTEventMonitor. + * It is not intended for use by any other class except AWTEventMonitor. + * + */ + + static class AWTEventsListener implements TopLevelWindowListener, + ActionListener, AdjustmentListener, ComponentListener, + ContainerListener, FocusListener, ItemListener, KeyListener, + MouseListener, MouseMotionListener, TextListener, WindowListener, + ChangeListener { + + /** + * internal variables for Action introspection + */ + private java.lang.Class actionListeners[]; + private java.lang.reflect.Method removeActionMethod; + private java.lang.reflect.Method addActionMethod; + private java.lang.Object actionArgs[]; + + /** + * internal variables for Item introspection + */ + private java.lang.Class itemListeners[]; + private java.lang.reflect.Method removeItemMethod; + private java.lang.reflect.Method addItemMethod; + private java.lang.Object itemArgs[]; + + /** + * internal variables for Text introspection + */ + private java.lang.Class textListeners[]; + private java.lang.reflect.Method removeTextMethod; + private java.lang.reflect.Method addTextMethod; + private java.lang.Object textArgs[]; + + /** + * internal variables for Window introspection + */ + private java.lang.Class windowListeners[]; + private java.lang.reflect.Method removeWindowMethod; + private java.lang.reflect.Method addWindowMethod; + private java.lang.Object windowArgs[]; + + /** + * Create a new instance of this class and install it on each component + * instance in the virtual machine that supports any of the currently + * registered listeners in AWTEventMonitor. Also registers itself + * as a TopLevelWindowListener with EventQueueMonitor so it can + * automatically add new listeners to new components. + * + * @see EventQueueMonitor + * @see AWTEventMonitor + */ + public AWTEventsListener() { + String version = System.getProperty("java.version"); + if (version != null) { + runningOnJDK1_4 = (version.compareTo("1.4") >= 0); + } + initializeIntrospection(); + installListeners(); + if (runningOnJDK1_4) { + MenuSelectionManager.defaultManager().addChangeListener(this); + } + EventQueueMonitor.addTopLevelWindowListener(this); + } + + /** + * Set up all of the variables needed for introspection + */ + private boolean initializeIntrospection() { + try { + actionListeners = new java.lang.Class[1]; + actionArgs = new java.lang.Object[1]; + actionListeners[0] = Class.forName("java.awt.event.ActionListener"); + actionArgs[0] = this; + + itemListeners = new java.lang.Class[1]; + itemArgs = new java.lang.Object[1]; + itemListeners[0] = Class.forName("java.awt.event.ItemListener"); + itemArgs[0] = this; + + textListeners = new java.lang.Class[1]; + textArgs = new java.lang.Object[1]; + textListeners[0] = Class.forName("java.awt.event.TextListener"); + textArgs[0] = this; + + windowListeners = new java.lang.Class[1]; + windowArgs = new java.lang.Object[1]; + windowListeners[0] = Class.forName("java.awt.event.WindowListener"); + windowArgs[0] = this; + + return true; + } catch (ClassNotFoundException e) { + System.out.println("EXCEPTION - Class 'java.awt.event.*' not in CLASSPATH"); + return false; + } + } + + /** + * Installs all currently registered listeners on all components based + * upon the current topLevelWindows cached by EventQueueMonitor. + * @see EventQueueMonitor + * @see AWTEventMonitor + */ + protected void installListeners() { + Window topLevelWindows[] = EventQueueMonitor.getTopLevelWindows(); + if (topLevelWindows != null) { + for (int i = 0; i < topLevelWindows.length; i++) { + installListeners(topLevelWindows[i]); + } + } + } + + /** + * Installs listeners for the given event ID on all components based + * upon the current topLevelWindows cached by EventQueueMonitor. + * @see EventID + * @param eventID the event ID + */ + protected void installListeners(int eventID) { + Window topLevelWindows[] = EventQueueMonitor.getTopLevelWindows(); + if (topLevelWindows != null) { + for (int i = 0; i < topLevelWindows.length; i++) { + installListeners(topLevelWindows[i], eventID); + } + } + } + + /** + * Installs all currently registered listeners to just the component. + * @param c the component to add listeners to + */ + protected void installListeners(Component c) { + + // Container and focus listeners are always installed for our own use. + // + installListeners(c,EventID.CONTAINER); + installListeners(c,EventID.FOCUS); + + // conditionally install low-level listeners + // + if (AWTEventMonitor.componentListener_private != null) { + installListeners(c,EventID.COMPONENT); + } + if (AWTEventMonitor.keyListener_private != null) { + installListeners(c,EventID.KEY); + } + if (AWTEventMonitor.mouseListener_private != null) { + installListeners(c,EventID.MOUSE); + } + if (AWTEventMonitor.mouseMotionListener_private != null) { + installListeners(c,EventID.MOTION); + } + if (AWTEventMonitor.windowListener_private != null) { + installListeners(c,EventID.WINDOW); + } + + // conditionally install Semantic listeners + // + if (AWTEventMonitor.actionListener_private != null) { + installListeners(c,EventID.ACTION); + } + if (AWTEventMonitor.adjustmentListener_private != null) { + installListeners(c,EventID.ADJUSTMENT); + } + if (AWTEventMonitor.itemListener_private != null) { + installListeners(c,EventID.ITEM); + } + if (AWTEventMonitor.textListener_private != null) { + installListeners(c,EventID.TEXT); + } + } + + public void stateChanged(ChangeEvent e) { + processFocusGained(); + } + + private void processFocusGained() { + Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + if (focusOwner == null) { + return; + } + MenuSelectionManager.defaultManager().removeChangeListener(this); + MenuSelectionManager.defaultManager().addChangeListener(this); + + // Only menus and popup selections are handled by the JRootPane. + if (focusOwner instanceof JRootPane) { + MenuElement [] path = + MenuSelectionManager.defaultManager().getSelectedPath(); + if (path.length > 1) { + Component penult = path[path.length-2].getComponent(); + Component last = path[path.length-1].getComponent(); + + if (last instanceof JPopupMenu || + last instanceof JMenu) { + // This is a popup with nothing in the popup + // selected. The menu itself is selected. + componentWithFocus_private = last; + } else if (penult instanceof JPopupMenu) { + // This is a popup with an item selected + componentWithFocus_private = penult; + } + } + } else { + // The focus owner has the selection. + componentWithFocus_private = focusOwner; + } + } + + /** + * Installs the given listener on the component and any of its children. + * As a precaution, it always attempts to remove itself as a listener + * first so it's always guaranteed to have installed itself just once. + * @param c the component to add listeners to + * @param eventID the eventID to add listeners for + * @see EventID + */ + protected void installListeners(Component c, int eventID) { + + // install the appropriate listener hook into this component + // + switch (eventID) { + + case EventID.ACTION: + try { + removeActionMethod = c.getClass().getMethod( + "removeActionListener", actionListeners); + addActionMethod = c.getClass().getMethod( + "addActionListener", actionListeners); + try { + removeActionMethod.invoke(c, actionArgs); + addActionMethod.invoke(c, actionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.ADJUSTMENT: + if (c instanceof Adjustable) { + ((Adjustable) c).removeAdjustmentListener(this); + ((Adjustable) c).addAdjustmentListener(this); + } + break; + + case EventID.COMPONENT: + c.removeComponentListener(this); + c.addComponentListener(this); + break; + + case EventID.CONTAINER: + if (c instanceof Container) { + ((Container) c).removeContainerListener(this); + ((Container) c).addContainerListener(this); + } + break; + + case EventID.FOCUS: + c.removeFocusListener(this); + c.addFocusListener(this); + + if (runningOnJDK1_4) { + processFocusGained(); + + } else { // not runningOnJDK1_4 + if ((c != componentWithFocus_private) && c.hasFocus()) { + componentWithFocus_private = c; + } + } + break; + + case EventID.ITEM: + try { + removeItemMethod = c.getClass().getMethod( + "removeItemListener", itemListeners); + addItemMethod = c.getClass().getMethod( + "addItemListener", itemListeners); + try { + removeItemMethod.invoke(c, itemArgs); + addItemMethod.invoke(c, itemArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + // [PK] CheckboxMenuItem isn't a component but it does + // implement Interface ItemSelectable!! + // if (c instanceof CheckboxMenuItem) { + // ((CheckboxMenuItem) c).removeItemListener(this); + // ((CheckboxMenuItem) c).addItemListener(this); + break; + + case EventID.KEY: + c.removeKeyListener(this); + c.addKeyListener(this); + break; + + case EventID.MOUSE: + c.removeMouseListener(this); + c.addMouseListener(this); + break; + + case EventID.MOTION: + c.removeMouseMotionListener(this); + c.addMouseMotionListener(this); + break; + + case EventID.TEXT: + try { + removeTextMethod = c.getClass().getMethod( + "removeTextListener", textListeners); + addTextMethod = c.getClass().getMethod( + "addTextListener", textListeners); + try { + removeTextMethod.invoke(c, textArgs); + addTextMethod.invoke(c, textArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.WINDOW: + try { + removeWindowMethod = c.getClass().getMethod( + "removeWindowListener", windowListeners); + addWindowMethod = c.getClass().getMethod( + "addWindowListener", windowListeners); + try { + removeWindowMethod.invoke(c, windowArgs); + addWindowMethod.invoke(c, windowArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + // Don't bother recursing the children if this isn't going to + // accomplish anything. + // + default: + return; + } + + // if this component is a container, recurse through children + // + if (c instanceof Container) { + int count = ((Container) c).getComponentCount(); + for (int i = 0; i < count; i++) { + installListeners(((Container) c).getComponent(i), eventID); + } + } + } + + /** + * Removes all listeners for the given event ID on all components based + * upon the topLevelWindows cached by EventQueueMonitor. + * @param eventID the event ID + * @see EventID + */ + protected void removeListeners(int eventID) { + Window topLevelWindows[] = EventQueueMonitor.getTopLevelWindows(); + if (topLevelWindows != null) { + for (int i = 0; i < topLevelWindows.length; i++) { + removeListeners(topLevelWindows[i], eventID); + } + } + } + + /** + * Removes all listeners for the given component and all its children. + * @param c the component + */ + protected void removeListeners(Component c) { + + // conditionally remove low-level listeners + // + if (AWTEventMonitor.componentListener_private != null) { + removeListeners(c,EventID.COMPONENT); + } + if (AWTEventMonitor.keyListener_private != null) { + removeListeners(c,EventID.KEY); + } + if (AWTEventMonitor.mouseListener_private != null) { + removeListeners(c,EventID.MOUSE); + } + if (AWTEventMonitor.mouseMotionListener_private != null) { + removeListeners(c,EventID.MOTION); + } + if (AWTEventMonitor.windowListener_private != null) { + removeListeners(c,EventID.WINDOW); + } + + // Remove semantic listeners + // + if (AWTEventMonitor.actionListener_private != null) { + removeListeners(c,EventID.ACTION); + } + if (AWTEventMonitor.adjustmentListener_private != null) { + removeListeners(c,EventID.ADJUSTMENT); + } + if (AWTEventMonitor.itemListener_private != null) { + removeListeners(c,EventID.ITEM); + } + if (AWTEventMonitor.textListener_private != null) { + removeListeners(c,EventID.TEXT); + } + } + + /** + * Removes all listeners for the event ID from the component and all + * of its children. + * @param c the component to remove listeners from + * @see EventID + */ + protected void removeListeners(Component c, int eventID) { + + // remove the appropriate listener hook into this component + // + switch (eventID) { + + case EventID.ACTION: + try { + removeActionMethod = c.getClass().getMethod( + "removeActionListener", + actionListeners); + try { + removeActionMethod.invoke(c, actionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.ADJUSTMENT: + if (c instanceof Adjustable) { + ((Adjustable) c).removeAdjustmentListener(this); + } + break; + + case EventID.COMPONENT: + c.removeComponentListener(this); + break; + + // Never remove these because we're always interested in them + // for our own use. + //case EventID.CONTAINER: + // if (c instanceof Container) { + // ((Container) c).removeContainerListener(this); + // } + // break; + // + //case EventID.FOCUS: + // c.removeFocusListener(this); + // break; + + case EventID.ITEM: + try { + removeItemMethod = c.getClass().getMethod( + "removeItemListener", itemListeners); + try { + removeItemMethod.invoke(c, itemArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + // [PK] CheckboxMenuItem isn't a component but it does + // implement Interface ItemSelectable!! + // if (c instanceof CheckboxMenuItem) { + // ((CheckboxMenuItem) c).removeItemListener(this); + break; + + case EventID.KEY: + c.removeKeyListener(this); + break; + + case EventID.MOUSE: + c.removeMouseListener(this); + break; + + case EventID.MOTION: + c.removeMouseMotionListener(this); + break; + + case EventID.TEXT: + try { + removeTextMethod = c.getClass().getMethod( + "removeTextListener", textListeners); + try { + removeTextMethod.invoke(c, textArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.WINDOW: + try { + removeWindowMethod = c.getClass().getMethod( + "removeWindowListener", windowListeners); + try { + removeWindowMethod.invoke(c, windowArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + default: + return; + } + + if (c instanceof Container) { + int count = ((Container) c).getComponentCount(); + for (int i = 0; i < count; i++) { + removeListeners(((Container) c).getComponent(i), eventID); + } + } + } + + /********************************************************************/ + /* */ + /* Listener Interface Methods */ + /* */ + /********************************************************************/ + + /* TopLevelWindow Methods ***************************************/ + + /** + * Called when top level window is created. + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + */ + public void topLevelWindowCreated(Window w) { + installListeners(w); + } + + /** + * Called when top level window is destroyed. + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + */ + public void topLevelWindowDestroyed(Window w) { + } + + /* ActionListener Methods ***************************************/ + + /** + * Called when an action is performed. + * @see AWTEventMonitor#addActionListener + */ + public void actionPerformed(ActionEvent e) { + if (AWTEventMonitor.actionListener_private != null) { + AWTEventMonitor.actionListener_private.actionPerformed(e); + } + } + + /* AdjustmentListener Methods ***********************************/ + + /** + * Called when an adjustment is made. + * @see AWTEventMonitor#addAdjustmentListener + */ + public void adjustmentValueChanged(AdjustmentEvent e) { + if (AWTEventMonitor.adjustmentListener_private != null) { + AWTEventMonitor.adjustmentListener_private.adjustmentValueChanged(e); + } + } + + /* ComponentListener Methods ************************************/ + + /** + * Called when a component is hidden. + * @see AWTEventMonitor#addComponentListener + */ + public void componentHidden(ComponentEvent e) { + if (AWTEventMonitor.componentListener_private != null) { + AWTEventMonitor.componentListener_private.componentHidden(e); + } + } + + /** + * Called when a component is moved. + * @see AWTEventMonitor#addComponentListener + */ + public void componentMoved(ComponentEvent e) { + if (AWTEventMonitor.componentListener_private != null) { + AWTEventMonitor.componentListener_private.componentMoved(e); + } + } + + /** + * Called when a component is resized. + * @see AWTEventMonitor#addComponentListener + */ + public void componentResized(ComponentEvent e) { + if (AWTEventMonitor.componentListener_private != null) { + AWTEventMonitor.componentListener_private.componentResized(e); + } + } + + /** + * Called when a component is shown. + * @see AWTEventMonitor#addComponentListener + */ + public void componentShown(ComponentEvent e) { + if (AWTEventMonitor.componentListener_private != null) { + AWTEventMonitor.componentListener_private.componentShown(e); + } + } + + /* ContainerListener Methods ************************************/ + + /** + * Called when a component is added to a container. + * @see AWTEventMonitor#addContainerListener + */ + public void componentAdded(ContainerEvent e) { + installListeners(e.getChild()); + if (AWTEventMonitor.containerListener_private != null) { + AWTEventMonitor.containerListener_private.componentAdded(e); + } + } + + /** + * Called when a component is removed from a container. + * @see AWTEventMonitor#addContainerListener + */ + public void componentRemoved(ContainerEvent e) { + removeListeners(e.getChild()); + if (AWTEventMonitor.containerListener_private != null) { + AWTEventMonitor.containerListener_private.componentRemoved(e); + } + } + + /* FocusListener Methods ****************************************/ + + /** + * Called when a component gains keyboard focus. + * @see AWTEventMonitor#addFocusListener + */ + public void focusGained(FocusEvent e) { + AWTEventMonitor.componentWithFocus_private = (Component) e.getSource(); + if (AWTEventMonitor.focusListener_private != null) { + AWTEventMonitor.focusListener_private.focusGained(e); + } + } + + /** + * Called when a component loses keyboard focus. + * @see AWTEventMonitor#addFocusListener + */ + public void focusLost(FocusEvent e) { + AWTEventMonitor.componentWithFocus_private = null; + if (AWTEventMonitor.focusListener_private != null) { + AWTEventMonitor.focusListener_private.focusLost(e); + } + } + + /* ItemListener Methods *****************************************/ + + /** + * Called when an item's state changes. + * @see AWTEventMonitor#addItemListener + */ + public void itemStateChanged(ItemEvent e) { + if (AWTEventMonitor.itemListener_private != null) { + AWTEventMonitor.itemListener_private.itemStateChanged(e); + } + } + + /* KeyListener Methods ******************************************/ + + /** + * Called when a key is pressed. + * @see AWTEventMonitor#addKeyListener + */ + public void keyPressed(KeyEvent e) { + if (AWTEventMonitor.keyListener_private != null) { + AWTEventMonitor.keyListener_private.keyPressed(e); + } + } + + /** + * Called when a key is typed. + * @see AWTEventMonitor#addKeyListener + */ + public void keyReleased(KeyEvent e) { + if (AWTEventMonitor.keyListener_private != null) { + AWTEventMonitor.keyListener_private.keyReleased(e); + } + } + + /** + * Called when a key is released. + * @see AWTEventMonitor#addKeyListener + */ + public void keyTyped(KeyEvent e) { + if (AWTEventMonitor.keyListener_private != null) { + AWTEventMonitor.keyListener_private.keyTyped(e); + } + } + + /* MouseListener Methods ****************************************/ + + /** + * Called when the mouse is clicked. + * @see AWTEventMonitor#addMouseListener + */ + public void mouseClicked(MouseEvent e) { + if (AWTEventMonitor.mouseListener_private != null) { + AWTEventMonitor.mouseListener_private.mouseClicked(e); + } + } + + /** + * Called when the mouse enters a component. + * @see AWTEventMonitor#addMouseListener + */ + public void mouseEntered(MouseEvent e) { + if (AWTEventMonitor.mouseListener_private != null) { + AWTEventMonitor.mouseListener_private.mouseEntered(e); + } + } + + /** + * Called when the mouse leaves a component. + * @see AWTEventMonitor#addMouseListener + */ + public void mouseExited(MouseEvent e) { + if (AWTEventMonitor.mouseListener_private != null) { + AWTEventMonitor.mouseListener_private.mouseExited(e); + } + } + + /** + * Called when the mouse is pressed. + * @see AWTEventMonitor#addMouseListener + */ + public void mousePressed(MouseEvent e) { + if (AWTEventMonitor.mouseListener_private != null) { + AWTEventMonitor.mouseListener_private.mousePressed(e); + } + } + + /** + * Called when the mouse is released. + * @see AWTEventMonitor#addMouseListener + */ + public void mouseReleased(MouseEvent e) { + if (AWTEventMonitor.mouseListener_private != null) { + AWTEventMonitor.mouseListener_private.mouseReleased(e); + } + } + + /* MouseMotionListener Methods **********************************/ + + /** + * Called when the mouse is dragged. + * @see AWTEventMonitor#addMouseMotionListener + */ + public void mouseDragged(MouseEvent e) { + if (AWTEventMonitor.mouseMotionListener_private != null) { + AWTEventMonitor.mouseMotionListener_private.mouseDragged(e); + } + } + + /** + * Called when the mouse is moved. + * @see AWTEventMonitor#addMouseMotionListener + */ + public void mouseMoved(MouseEvent e) { + if (AWTEventMonitor.mouseMotionListener_private != null) { + AWTEventMonitor.mouseMotionListener_private.mouseMoved(e); + } + } + + /* TextListener Methods *****************************************/ + + /** + * Called when a component's text value changed. + * @see AWTEventMonitor#addTextListener + */ + public void textValueChanged(TextEvent e) { + if (AWTEventMonitor.textListener_private != null) { + AWTEventMonitor.textListener_private.textValueChanged(e); + } + } + + /* WindowListener Methods ***************************************/ + + /** + * Called when a window is opened. + * @see AWTEventMonitor#addWindowListener + */ + public void windowOpened(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowOpened(e); + } + } + + /** + * Called when a window is in the process of closing. + * @see AWTEventMonitor#addWindowListener + */ + public void windowClosing(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowClosing(e); + } + } + + /** + * Called when a window is closed. + * @see AWTEventMonitor#addWindowListener + */ + public void windowClosed(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowClosed(e); + } + } + + /** + * Called when a window is iconified. + * @see AWTEventMonitor#addWindowListener + */ + public void windowIconified(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowIconified(e); + } + } + + /** + * Called when a window is deiconified. + * @see AWTEventMonitor#addWindowListener + */ + public void windowDeiconified(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowDeiconified(e); + } + } + + /** + * Called when a window is activated. + * @see AWTEventMonitor#addWindowListener + */ + public void windowActivated(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowActivated(e); + } + } + + /** + * Called when a window is deactivated. + * @see AWTEventMonitor#addWindowListener + */ + public void windowDeactivated(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowDeactivated(e); + } + } + } +} --- /dev/null 2015-03-30 10:53:59.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/AccessibilityEventMonitor.java 2015-03-30 10:53:58.127422700 -0500 @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.util.*; +import java.beans.*; +import java.awt.*; +import java.awt.event.*; +import javax.accessibility.*; + +/** + *

{@code AccessibilityEventMonitor} implements a PropertyChange listener + * on every UI object that implements interface {@code Accessible} in the Java + * Virtual Machine. The events captured by these listeners are made available + * through listeners supported by {@code AccessibilityEventMonitor}. + * With this, all the individual events on each of the UI object + * instances are funneled into one set of PropertyChange listeners. + *

This class depends upon {@link EventQueueMonitor}, which provides the base + * level support for capturing the top-level containers as they are created. + * + */ + +@jdk.Exported +public class AccessibilityEventMonitor { + + // listeners + /** + * The current list of registered {@link java.beans.PropertyChangeListener + * PropertyChangeListener} classes. + * + * @see #addPropertyChangeListener + * @see #removePropertyChangeListener + */ + static protected final AccessibilityListenerList listenerList = + new AccessibilityListenerList(); + + + /** + * The actual listener that is installed on the component instances. + * This listener calls the other registered listeners when an event + * occurs. By doing things this way, the actual number of listeners + * installed on a component instance is drastically reduced. + */ + static protected final AccessibilityEventListener accessibilityListener = + new AccessibilityEventListener(); + + /** + * Adds the specified listener to receive all PropertyChange events on + * each UI object instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to UI object instances that support this listener type. + * + * @param l the listener to add + * + * @see #removePropertyChangeListener + */ + static public void addPropertyChangeListener(PropertyChangeListener l) { + if (listenerList.getListenerCount(PropertyChangeListener.class) == 0) { + accessibilityListener.installListeners(); + } + listenerList.add(PropertyChangeListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives PropertyChange + * events when they occur. + * @see #addPropertyChangeListener + * @param l the listener to remove + */ + static public void removePropertyChangeListener(PropertyChangeListener l) { + listenerList.remove(PropertyChangeListener.class, l); + if (listenerList.getListenerCount(PropertyChangeListener.class) == 0) { + accessibilityListener.removeListeners(); + } + } + + + /** + * AccessibilityEventListener is the class that does all the work for + * AccessibilityEventMonitor. It is not intended for use by any other + * class except AccessibilityEventMonitor. + * + */ + + static class AccessibilityEventListener implements TopLevelWindowListener, + PropertyChangeListener { + + /** + * Create a new instance of this class and install it on each component + * instance in the virtual machine that supports any of the currently + * registered listeners in AccessibilityEventMonitor. Also registers + * itself as a TopLevelWindowListener with EventQueueMonitor so it can + * automatically add new listeners to new components. + * @see EventQueueMonitor + * @see AccessibilityEventMonitor + */ + public AccessibilityEventListener() { + EventQueueMonitor.addTopLevelWindowListener(this); + } + + /** + * Installs PropertyChange listeners on all Accessible objects based + * upon the current topLevelWindows cached by EventQueueMonitor. + * @see EventQueueMonitor + * @see AWTEventMonitor + */ + protected void installListeners() { + Window topLevelWindows[] = EventQueueMonitor.getTopLevelWindows(); + if (topLevelWindows != null) { + for (int i = 0; i < topLevelWindows.length; i++) { + if (topLevelWindows[i] instanceof Accessible) { + installListeners((Accessible) topLevelWindows[i]); + } + } + } + } + + /** + * Installs PropertyChange listeners to the Accessible object, and it's + * children (so long as the object isn't of TRANSIENT state). + * @param a the Accessible object to add listeners to + */ + protected void installListeners(Accessible a) { + installListeners(a.getAccessibleContext()); + } + + /** + * Installs PropertyChange listeners to the AccessibleContext object, + * and it's * children (so long as the object isn't of TRANSIENT state). + * @param a the Accessible object to add listeners to + */ + private void installListeners(AccessibleContext ac) { + + if (ac != null) { + AccessibleStateSet states = ac.getAccessibleStateSet(); + if (!states.contains(AccessibleState.TRANSIENT)) { + ac.addPropertyChangeListener(this); + /* + * Don't add listeners to transient children. Components + * with transient children should return an AccessibleStateSet + * containing AccessibleState.MANAGES_DESCENDANTS. Components + * may not explicitly return the MANAGES_DESCENDANTS state. + * In this case, don't add listeners to the children of + * lists, tables and trees. + */ + AccessibleStateSet set = ac.getAccessibleStateSet(); + if (set.contains(_AccessibleState.MANAGES_DESCENDANTS)) { + return; + } + AccessibleRole role = ac.getAccessibleRole(); + if (role == AccessibleRole.LIST || + role == AccessibleRole.TREE) { + return; + } + if (role == AccessibleRole.TABLE) { + // handle Oracle tables containing tables + Accessible child = ac.getAccessibleChild(0); + if (child != null) { + AccessibleContext ac2 = child.getAccessibleContext(); + if (ac2 != null) { + role = ac2.getAccessibleRole(); + if (role != null && role != AccessibleRole.TABLE) { + return; + } + } + } + } + int count = ac.getAccessibleChildrenCount(); + for (int i = 0; i < count; i++) { + Accessible child = ac.getAccessibleChild(i); + if (child != null) { + installListeners(child); + } + } + } + } + } + + /** + * Removes PropertyChange listeners on all Accessible objects based + * upon the topLevelWindows cached by EventQueueMonitor. + * @param eventID the event ID + * @see EventID + */ + protected void removeListeners() { + Window topLevelWindows[] = EventQueueMonitor.getTopLevelWindows(); + if (topLevelWindows != null) { + for (int i = 0; i < topLevelWindows.length; i++) { + if (topLevelWindows[i] instanceof Accessible) { + removeListeners((Accessible) topLevelWindows[i]); + } + } + } + } + + /** + * Removes PropertyChange listeners for the given Accessible object, + * it's children (so long as the object isn't of TRANSIENT state). + * @param a the Accessible object to remove listeners from + */ + protected void removeListeners(Accessible a) { + removeListeners(a.getAccessibleContext()); + } + + /** + * Removes PropertyChange listeners for the given AccessibleContext + * object, it's children (so long as the object isn't of TRANSIENT + * state). + * @param a the Accessible object to remove listeners from + */ + private void removeListeners(AccessibleContext ac) { + + + if (ac != null) { + // Listeners are not added to transient components. + AccessibleStateSet states = ac.getAccessibleStateSet(); + if (!states.contains(AccessibleState.TRANSIENT)) { + ac.removePropertyChangeListener(this); + /* + * Listeners are not added to transient children. Components + * with transient children should return an AccessibleStateSet + * containing AccessibleState.MANAGES_DESCENDANTS. Components + * may not explicitly return the MANAGES_DESCENDANTS state. + * In this case, don't remove listeners from the children of + * lists, tables and trees. + */ + if (states.contains(_AccessibleState.MANAGES_DESCENDANTS)) { + return; + } + AccessibleRole role = ac.getAccessibleRole(); + if (role == AccessibleRole.LIST || + role == AccessibleRole.TABLE || + role == AccessibleRole.TREE) { + return; + } + int count = ac.getAccessibleChildrenCount(); + for (int i = 0; i < count; i++) { + Accessible child = ac.getAccessibleChild(i); + if (child != null) { + removeListeners(child); + } + } + } + } + } + + /********************************************************************/ + /* */ + /* Listener Interface Methods */ + /* */ + /********************************************************************/ + + /* TopLevelWindow Methods ***************************************/ + + /** + * Called when top level window is created. + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + */ + public void topLevelWindowCreated(Window w) { + if (w instanceof Accessible) { + installListeners((Accessible) w); + } + } + + /** + * Called when top level window is destroyed. + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + */ + public void topLevelWindowDestroyed(Window w) { + if (w instanceof Accessible) { + removeListeners((Accessible) w); + } + } + + + /* PropertyChangeListener Methods **************************************/ + + public void propertyChange(PropertyChangeEvent e) { + // propogate the event + Object[] listeners = + AccessibilityEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==PropertyChangeListener.class) { + ((PropertyChangeListener)listeners[i+1]).propertyChange(e); + } + } + + // handle childbirth/death + String name = e.getPropertyName(); + if (name.compareTo(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY) == 0) { + Object oldValue = e.getOldValue(); + Object newValue = e.getNewValue(); + + if ((oldValue == null) ^ (newValue == null)) { // one null, not both + if (oldValue != null) { + // this Accessible is a child that's going away + if (oldValue instanceof Accessible) { + Accessible a = (Accessible) oldValue; + removeListeners(a.getAccessibleContext()); + } else if (oldValue instanceof AccessibleContext) { + removeListeners((AccessibleContext) oldValue); + } + } else if (newValue != null) { + // this Accessible is a child was just born + if (newValue instanceof Accessible) { + Accessible a = (Accessible) newValue; + installListeners(a.getAccessibleContext()); + } else if (newValue instanceof AccessibleContext) { + installListeners((AccessibleContext) newValue); + } + } + } else { + System.out.println("ERROR in usage of PropertyChangeEvents for: " + e.toString()); + } + } + } + } +} + +/* + * workaround for no public AccessibleState constructor + */ +class _AccessibleState extends AccessibleState { + /** + * Indicates this object is responsible for managing its + * subcomponents. This is typically used for trees and tables + * that have a large number of subcomponents and where the + * objects are created only when needed and otherwise remain virtual. + * The application should not manage the subcomponents directly. + */ + public static final _AccessibleState MANAGES_DESCENDANTS + = new _AccessibleState ("managesDescendants"); + + /** + * Creates a new AccessibleState using the given locale independent key. + * This should not be a public method. Instead, it is used to create + * the constants in this file to make it a strongly typed enumeration. + * Subclasses of this class should enforce similar policy. + *

+ * The key String should be a locale independent key for the state. + * It is not intended to be used as the actual String to display + * to the user. To get the localized string, use toDisplayString. + * + * @param key the locale independent name of the state. + * @see AccessibleBundle#toDisplayString + */ + protected _AccessibleState(String key) { + super(key); + } +} --- /dev/null 2015-03-30 10:54:02.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/AccessibilityListenerList.java 2015-03-30 10:54:01.260434500 -0500 @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.util.*; +import java.beans.*; +import java.awt.*; +import java.awt.event.*; +import javax.accessibility.*; + +/** + *

The {@code AccessibilityListenerList} is a copy of the Swing + * {@link javax.swing.event.EventListenerList EventListerList} class. + * + */ + +@jdk.Exported +public class AccessibilityListenerList { + /* A null array to be shared by all empty listener lists */ + private final static Object[] NULL_ARRAY = new Object[0]; + + /** + * The list of listener type, listener pairs + */ + protected transient Object[] listenerList = NULL_ARRAY; + + /** + * Passes back the event listener list as an array of listener type, listener pairs. + * Note that for performance reasons, this implementation passes back the actual + * data structure in which the listener data is stored internally. This method + * is guaranteed to pass back a non-null array, so that no null-checking + * is required in fire methods. A zero-length array of Object is returned if + * there are currently no listeners. + *

+ * Absolutely no modification of the data contained in this array should be + * made. If any such manipulation is necessary, it should be done on a copy + * of the array returned rather than the array itself. + * + * @return an array of listener type, listener pairs. + */ + public Object[] getListenerList() { + return listenerList; + } + + /** + * Returns the total number of listeners for this listener list. + * + * @return the total number of listeners for this listener list. + */ + public int getListenerCount() { + return listenerList.length/2; + } + + /** + * Return the total number of listeners of the supplied type + * for this listener list. + * + * @param t the type of the listener to be counted + * @return the number of listeners found + */ + public int getListenerCount(Class t) { + int count = 0; + Object[] lList = listenerList; + for (int i = 0; i < lList.length; i+=2) { + if (t == (Class)lList[i]) + count++; + } + return count; + } + + /** + * Add the listener as a listener of the specified type. + * + * @param t the type of the listener to be added + * @param l the listener to be added + */ + public synchronized void add(Class t, EventListener l) { + if (!t.isInstance(l)) { + throw new IllegalArgumentException("Listener " + l + + " is not of type " + t); + } + if (l ==null) { + throw new IllegalArgumentException("Listener " + l + + " is null"); + } + if (listenerList == NULL_ARRAY) { + // if this is the first listener added, + // initialize the lists + listenerList = new Object[] { t, l }; + } else { + // Otherwise copy the array and add the new listener + int i = listenerList.length; + Object[] tmp = new Object[i+2]; + System.arraycopy(listenerList, 0, tmp, 0, i); + + tmp[i] = t; + tmp[i+1] = l; + + listenerList = tmp; + } + } + + /** + * Remove the listener as a listener of the specified type. + * + * @param t the type of the listener to be removed + * @param l the listener to be removed + */ + public synchronized void remove(Class t, EventListener l) { + if (!t.isInstance(l)) { + throw new IllegalArgumentException("Listener " + l + + " is not of type " + t); + } + if (l ==null) { + throw new IllegalArgumentException("Listener " + l + + " is null"); + } + + // Is l on the list? + int index = -1; + for (int i = listenerList.length-2; i>=0; i-=2) { + if ((listenerList[i]==t) && (listenerList[i+1] == l)) { + index = i; + break; + } + } + + // If so, remove it + if (index != -1) { + Object[] tmp = new Object[listenerList.length-2]; + // Copy the list up to index + System.arraycopy(listenerList, 0, tmp, 0, index); + // Copy from two past the index, up to + // the end of tmp (which is two elements + // shorter than the old list) + if (index < tmp.length) + System.arraycopy(listenerList, index+2, tmp, index, + tmp.length - index); + // set the listener array to the new array or null + listenerList = (tmp.length == 0) ? NULL_ARRAY : tmp; + } + } + + /** + * Return a string representation of the {@code AccessibilityListenerList}. + * + * @return a string representation of the {@code AccessibilityListenerList}. + */ + public String toString() { + Object[] lList = listenerList; + String s = "EventListenerList: "; + s += lList.length/2 + " listeners: "; + for (int i = 0 ; i <= lList.length-2 ; i+=2) { + s += " type " + ((Class)lList[i]).getName(); + s += " listener " + lList[i+1]; + } + return s; + } +} --- /dev/null 2015-03-30 10:54:05.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/EventID.java 2015-03-30 10:54:04.418447200 -0500 @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +/** + * EventID contains integer constants that map to event support in + * AWT and Swing. They are used by primarily by AWTEventMonitor, + * AWTEventsListener, SwingEventMonitor, and SwingEventListener, but + * can be freely used by any other class. + * + * @see AWTEventMonitor + * @see SwingEventMonitor + * + */ +@jdk.Exported +public class EventID { + + /** + * Maps to AWT Action support (i.e., ActionListener and ActionEvent) + */ + static public final int ACTION = 0; + + /** + * Maps to AWT Adjustment support (i.e., AdjustmentListener + * and AdjustmentEvent) + */ + static public final int ADJUSTMENT = 1; + + /** + * Maps to AWT Component support (i.e., ComponentListener + * and ComponentEvent) + */ + static public final int COMPONENT = 2; + + /** + * Maps to AWT Container support (i.e., ContainerListener + * and ContainerEvent) + */ + static public final int CONTAINER = 3; + + /** + * Maps to AWT Focus support (i.e., FocusListener and FocusEvent) + */ + static public final int FOCUS = 4; + + /** + * Maps to AWT Item support (i.e., ItemListener and ItemEvent) + */ + static public final int ITEM = 5; + + /** + * Maps to AWT Key support (i.e., KeyListener and KeyEvent) + */ + static public final int KEY = 6; + + /** + * Maps to AWT Mouse support (i.e., MouseListener and MouseEvent) + */ + static public final int MOUSE = 7; + + /** + * Maps to AWT MouseMotion support (i.e., MouseMotionListener + * and MouseMotionEvent) + */ + static public final int MOTION = 8; + + /** + * Maps to AWT Text support (i.e., TextListener and TextEvent) + */ + static public final int TEXT = 10; + + /** + * Maps to AWT Window support (i.e., WindowListener and WindowEvent) + */ + static public final int WINDOW = 11; + + /** + * Maps to Swing Ancestor support (i.e., AncestorListener and + * AncestorEvent) + */ + static public final int ANCESTOR = 12; + + /** + * Maps to Swing Text Caret support (i.e., CaretListener and + * CaretEvent) + */ + static public final int CARET = 13; + + /** + * Maps to Swing CellEditor support (i.e., CellEditorListener and + * CellEditorEvent) + */ + static public final int CELLEDITOR = 14; + + /** + * Maps to Swing Change support (i.e., ChangeListener and + * ChangeEvent) + */ + static public final int CHANGE = 15; + + /** + * Maps to Swing TableColumnModel support (i.e., + * TableColumnModelListener and TableColumnModelEvent) + */ + static public final int COLUMNMODEL = 16; + + /** + * Maps to Swing Document support (i.e., DocumentListener and + * DocumentEvent) + */ + static public final int DOCUMENT = 17; + + /** + * Maps to Swing ListData support (i.e., ListDataListener and + * ListDataEvent) + */ + static public final int LISTDATA = 18; + + /** + * Maps to Swing ListSelection support (i.e., ListSelectionListener and + * ListSelectionEvent) + */ + static public final int LISTSELECTION = 19; + + /** + * Maps to Swing Menu support (i.e., MenuListener and + * MenuEvent) + */ + static public final int MENU = 20; + + /** + * Maps to Swing PopupMenu support (i.e., PopupMenuListener and + * PopupMenuEvent) + */ + static public final int POPUPMENU = 21; + + /** + * Maps to Swing TableModel support (i.e., TableModelListener and + * TableModelEvent) + */ + static public final int TABLEMODEL = 22; + + /** + * Maps to Swing TreeExpansion support (i.e., TreeExpansionListener and + * TreeExpansionEvent) + */ + static public final int TREEEXPANSION = 23; + + /** + * Maps to Swing TreeModel support (i.e., TreeModelListener and + * TreeModelEvent) + */ + static public final int TREEMODEL = 24; + + /** + * Maps to Swing TreeSelection support (i.e., TreeSelectionListener and + * TreeSelectionEvent) + */ + static public final int TREESELECTION = 25; + + /** + * Maps to Swing UndoableEdit support (i.e., UndoableEditListener and + * UndoableEditEvent) + */ + static public final int UNDOABLEEDIT = 26; + + /** + * Maps to Beans PropertyChange support (i.e., PropertyChangeListener + * and PropertyChangeEvent) + */ + static public final int PROPERTYCHANGE = 27; + + /** + * Maps to Beans VetoableChange support (i.e., VetoableChangeListener + * and VetoableChangeEvent) + */ + static public final int VETOABLECHANGE = 28; + + /** + * Maps to Swing InternalFrame support (i.e., InternalFrameListener) + */ + static public final int INTERNALFRAME = 29; +} --- /dev/null 2015-03-30 10:54:08.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/EventQueueMonitor.java 2015-03-30 10:54:07.598457800 -0500 @@ -0,0 +1,619 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import javax.accessibility.*; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * The {@code EventQueueMonitor} class provides key core functionality for Assistive + * Technologies (and other system-level technologies that need some of the same + * things that Assistive Technology needs). + * + * @see AWTEventMonitor + * @see SwingEventMonitor + */ +@jdk.Exported +public class EventQueueMonitor + implements AWTEventListener { + + // NOTE: All of the following properties are static. The reason + // for this is that there may be multiple EventQueue instances + // in use in the same VM. By making these properties static, + // we can guarantee we get the information from all of the + // EventQueue instances. + + // The stuff that is cached. + // + static Vector topLevelWindows = new Vector(); + static Window topLevelWindowWithFocus = null; + static Point currentMousePosition = null; + static Component currentMouseComponent = null; + + // Low-level listener interfaces + // + static GUIInitializedListener guiInitializedListener = null; + static TopLevelWindowListener topLevelWindowListener = null; + static MouseMotionListener mouseMotionListener = null; + + /** + * Class variable stating whether the assistive technologies have + * been loaded yet or not. The assistive technologies won't be + * loaded until the first event is posted to the EventQueue. This + * gives the toolkit a chance to do all the necessary initialization + * it needs to do. + */ + + /** + * Class variable stating whether the GUI subsystem has been initialized + * or not. + * + * @see #isGUIInitialized + */ + static boolean guiInitialized = false; + + /** + * Queue that holds events for later processing. + */ + static EventQueueMonitorItem componentEventQueue = null; + + /** + * Class that tells us what the component event dispatch thread is. + */ + static private ComponentEvtDispatchThread cedt = null; + + /** + * Handle the synchronization between the thing that populates the + * component event dispatch thread ({@link #queueComponentEvent}) + * and the thing that processes the events ({@link ComponentEvtDispatchThread}). + */ + static Object componentEventQueueLock = new Object(); + + /** + * Create a new {@code EventQueueMonitor} instance. Normally, this will + * be called only by the AWT Toolkit during initialization time. + * Assistive technologies should not create instances of + * EventQueueMonitor by themselves. Instead, they should either + * refer to it directly via the static methods in this class, e.g., + * {@link #getCurrentMousePosition} or obtain the instance by asking the + * Toolkit, e.g., {@link java.awt.Toolkit#getSystemEventQueue}. + */ + public EventQueueMonitor() { + if (cedt == null) { + cedt = new ComponentEvtDispatchThread("EventQueueMonitor-ComponentEvtDispatch"); + + cedt.setDaemon(true); + cedt.start(); + } + } + + /** + * Queue up a {@link java.awt.event.ComponentEvent ComponentEvent} for later + * processing by the {@link ComponentEvtDispatch} thread. + * + * @param e a {@code ComponentEvent} + */ + static void queueComponentEvent(ComponentEvent e) { + synchronized(componentEventQueueLock) { + EventQueueMonitorItem eqi = new EventQueueMonitorItem(e); + if (componentEventQueue == null) { + componentEventQueue = eqi; + } else { + EventQueueMonitorItem q = componentEventQueue; + while (true) { + if (q.next != null) { + q = q.next; + } else { + break; + } + } + q.next = eqi; + } + componentEventQueueLock.notifyAll(); + } + } + + /** + * Tell the {@code EventQueueMonitor} to start listening for events. + */ + public static void maybeInitialize() { + if (cedt == null) { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + try { + long eventMask = AWTEvent.WINDOW_EVENT_MASK | + AWTEvent.FOCUS_EVENT_MASK | + AWTEvent.MOUSE_MOTION_EVENT_MASK; + + Toolkit.getDefaultToolkit().addAWTEventListener(new EventQueueMonitor(), eventMask); + } catch (Exception e) { + } + return null; + } + } + ); + } + } + + /** + * Handle events as a result of registering a listener + * on the {@link java.awt.EventQueue EventQueue} in {@link #maybeInitialize}. + */ + public void eventDispatched(AWTEvent theEvent) { + processEvent(theEvent); + } + + /** + * Assisitive technologies that have + * registered a {@link GUIInitializedListener} will be notified. + * + * @see #addGUIInitializedListener + */ + static void maybeNotifyAssistiveTechnologies() { + + if (!guiInitialized) { + guiInitialized = true; + if (guiInitializedListener != null) { + guiInitializedListener.guiInitialized(); + } + } + + } + + /********************************************************************/ + /* */ + /* Package Private Methods */ + /* */ + /********************************************************************/ + + /** + * Add a Container to the list of top-level containers + * in the cache. This follows the object's hierarchy up the + * tree until it finds the top most parent. If the parent is + * not already in the list of Containers, it adds it to the list. + * + * @param c the Container + */ + static void addTopLevelWindow(Component c) { + Container parent; + + if (c == null) { + return; + } + + if (!(c instanceof Window)) { + addTopLevelWindow(c.getParent()); + return; + } + + if ((c instanceof Dialog) || (c instanceof Window)) { + parent = (Container) c; + } else { + parent = c.getParent(); + if (parent != null) { + addTopLevelWindow(parent); + return; + } + } + + if (parent == null) { + parent = (Container) c; + } + + // Because this method is static, do not make it synchronized because + // it can lock the whole class. Instead, just lock what needs to be + // locked. + // + synchronized (topLevelWindows) { + if ((parent != null) && !topLevelWindows.contains(parent)) { + topLevelWindows.addElement(parent); + if (topLevelWindowListener != null) { + topLevelWindowListener.topLevelWindowCreated((Window) parent); + } + } + } + } + + /** + * Removes a container from the list of top level containers in the cache. + * + * @param c the top level container to remove + */ + static void removeTopLevelWindow(Window w) { + + // Because this method is static, do not make it synchronized because + // it can lock the whole class. Instead, just lock what needs to be + // locked. + // + synchronized (topLevelWindows) { + if (topLevelWindows.contains(w)) { + topLevelWindows.removeElement(w); + if (topLevelWindowListener != null) { + topLevelWindowListener.topLevelWindowDestroyed(w); + } + } + } + } + + /** + * Update current mouse position. + * + * @param mouseEvent the MouseEvent that holds the new mouse position. + */ + static void updateCurrentMousePosition(MouseEvent mouseEvent) { + Point oldMousePos = currentMousePosition; + // Be careful here. The component in the event might be + // hidden by the time we process the event. + try { + Point eventPoint = mouseEvent.getPoint(); + currentMouseComponent = (Component) (mouseEvent.getSource()); + currentMousePosition = currentMouseComponent.getLocationOnScreen(); + currentMousePosition.translate(eventPoint.x,eventPoint.y); + } catch (Exception e) { + currentMousePosition = oldMousePos; + } + } + + /** + * Process the event. This maintains the event cache in addition + * to calling all the registered listeners. NOTE: The events that + * come through here are from peered Components. + * + * @param theEvent the AWTEvent + */ + static void processEvent(AWTEvent theEvent) { + switch (theEvent.getID()) { + case MouseEvent.MOUSE_MOVED: + case MouseEvent.MOUSE_DRAGGED: + case FocusEvent.FOCUS_GAINED: + case WindowEvent.WINDOW_DEACTIVATED: + queueComponentEvent((ComponentEvent) theEvent); + break; + + case WindowEvent.WINDOW_ACTIVATED: + // Dialogs fire WINDOW_ACTIVATED and FOCUS_GAINED events + // before WINDOW_OPENED so we need to add topLevelListeners + // for the dialog when it is first activated to get a + // focus gained event for the focus component in the dialog. + if (theEvent instanceof ComponentEvent) { + ComponentEvent ce = (ComponentEvent)theEvent; + if (ce.getComponent() instanceof Window) { + EventQueueMonitor.addTopLevelWindow(ce.getComponent()); + EventQueueMonitor.maybeNotifyAssistiveTechnologies(); + } else { + EventQueueMonitor.maybeNotifyAssistiveTechnologies(); + EventQueueMonitor.addTopLevelWindow(ce.getComponent()); + } + } + queueComponentEvent((ComponentEvent) theEvent); + break; + + // handle WINDOW_OPENED and WINDOW_CLOSED events synchronously + case WindowEvent.WINDOW_OPENED: + if (theEvent instanceof ComponentEvent) { + ComponentEvent ce = (ComponentEvent)theEvent; + if (ce.getComponent() instanceof Window) { + EventQueueMonitor.addTopLevelWindow(ce.getComponent()); + EventQueueMonitor.maybeNotifyAssistiveTechnologies(); + } else { + EventQueueMonitor.maybeNotifyAssistiveTechnologies(); + EventQueueMonitor.addTopLevelWindow(ce.getComponent()); + } + } + break; + case WindowEvent.WINDOW_CLOSED: + if (theEvent instanceof ComponentEvent) { + ComponentEvent ce = (ComponentEvent)theEvent; + EventQueueMonitor.removeTopLevelWindow((Window) (ce.getComponent())); + } + break; + + default: + break; + } + } + + /** + * Internal test + */ + static synchronized Component getShowingComponentAt(Container c, int x, int y) { + if (!c.contains(x, y)) { + return null; + } + int ncomponents = c.getComponentCount(); + for (int i = 0 ; i < ncomponents ; i++) { + Component comp = c.getComponent(i); + if (comp != null && comp.isShowing()) { + Point location = comp.getLocation(); + if (comp.contains(x - location.x, y - location.y)) { + return comp; + } + } + } + return c; + } + + /** + * Return the Component at the given Point on the screen in the + * given Container. + * + * @param c the Container to search + * @param p the Point in screen coordinates + * @return the Component at the given Point on the screen in the + * given Container -- can be null if no Component is at that Point + */ + static synchronized Component getComponentAt(Container c, Point p) { + if (!c.isShowing()) { + return null; + } + + Component comp; + Point containerLoc = c.getLocationOnScreen(); + Point containerPoint = new Point(p.x - containerLoc.x, + p.y - containerLoc.y); + + comp = getShowingComponentAt(c, containerPoint.x, containerPoint.y); + + if ((comp != c) && (comp instanceof Container)) { + return getComponentAt((Container)comp,p); + } else { + return comp; + } + } + + /** + * Obtain the {@link javax.accessibility.Accessible Accessible} object at the given point on the Screen. + * The return value may be null if an {@code Accessible} object cannot be + * found at the particular point. + * + * @param p the point to be accessed + * @return the {@code Accessible} at the specified point + */ + static public Accessible getAccessibleAt(Point p) { + Window w = getTopLevelWindowWithFocus(); + Window[] wins = getTopLevelWindows(); + Component c = null; + + // See if the point we're being asked about is the + // currentMousePosition. If so, start with the component + // that we know the currentMousePostion is over + // + if (currentMousePosition == null) { + return null; + } + if (currentMousePosition.equals(p)) { + if (currentMouseComponent instanceof Container) { + c = getComponentAt((Container) currentMouseComponent, p); + } + } + + // Try the window with focus next + // + if (c == null && w != null) { + c = getComponentAt(w,p); + } + + // Try the other windows next. [[[WDW: Stacking order???]]] + if (c == null) { + for (int i = 0; i < wins.length; i++) { + c = getComponentAt(wins[i],p); + if (c != null) { + break; + } + } + } + + if (c instanceof Accessible) { + AccessibleContext ac = ((Accessible) c).getAccessibleContext(); + if (ac != null) { + AccessibleComponent acmp = ac.getAccessibleComponent(); + if ((acmp != null) && (ac.getAccessibleChildrenCount() != 0)) { + Point location = acmp.getLocationOnScreen(); + location.move(p.x - location.x, p.y - location.y); + return acmp.getAccessibleAt(location); + } + } + return (Accessible) c; + } else { + return Translator.getAccessible(c); + } + } + + /********************************************************************/ + /* */ + /* Public Methods */ + /* */ + /********************************************************************/ + + /** + * Says whether the GUI subsystem has been initialized or not. + * If this returns true, the assistive technology can freely + * create GUI component instances. If the return value is false, + * the assistive technology should register a {@link GUIInitializedListener} + * and wait to create GUI component instances until the listener is + * called. + * + * @return true if the GUI subsystem has been initialized + * @see #addGUIInitializedListener + */ + static public boolean isGUIInitialized() { + maybeInitialize(); + return guiInitialized; + } + + /** + * Adds the specified listener to be notified when the GUI subsystem + * is initialized. Assistive technologies should get the results of + * {@link #isGUIInitialized} before calling this method. + * + * @param l the listener to add + * @see #isGUIInitialized + * @see #removeTopLevelWindowListener + */ + static public void addGUIInitializedListener(GUIInitializedListener l) { + maybeInitialize(); + guiInitializedListener = + GUIInitializedMulticaster.add(guiInitializedListener,l); + } + + /** + * Removes the specified listener to be notified when the GUI subsystem + * is initialized. + * + * @param l the listener to remove + * @see #addGUIInitializedListener + */ + static public void removeGUIInitializedListener(GUIInitializedListener l) { + guiInitializedListener = + GUIInitializedMulticaster.remove(guiInitializedListener,l); + } + + /** + * Adds the specified listener to be notified when a top level window + * is created or destroyed. + * + * @param l the listener to add + * @see #removeTopLevelWindowListener + */ + static public void addTopLevelWindowListener(TopLevelWindowListener l) { + topLevelWindowListener = + TopLevelWindowMulticaster.add(topLevelWindowListener,l); + } + + /** + * Removes the specified listener to be notified when a top level window + * is created or destroyed. + * + * @param l the listener to remove + * @see #addTopLevelWindowListener + */ + static public void removeTopLevelWindowListener(TopLevelWindowListener l) { + topLevelWindowListener = + TopLevelWindowMulticaster.remove(topLevelWindowListener,l); + } + + /** + * Return the last recorded position of the mouse in screen coordinates. + * + * @return the last recorded position of the mouse in screen coordinates + */ + static public Point getCurrentMousePosition() { + return currentMousePosition; + } + + /** + * Return the list of top level Windows in use in the Java Virtual Machine. + * + * @return an array of top level {@code Window}s in use in the Java Virtual Machine + */ + static public Window[] getTopLevelWindows() { + + // Because this method is static, do not make it synchronized because + // it can lock the whole class. Instead, just lock what needs to be + // locked. + // + synchronized (topLevelWindows) { + int count = topLevelWindows.size(); + if (count > 0) { + Window[] w = new Window[count]; + for (int i = 0; i < count; i++) { + w[i] = (Window)topLevelWindows.elementAt(i); + } + return w; + } else { + return new Window[0]; + } + } + } + + /** + * Return the top level {@code Window} that currently has keyboard focus. + * + * @return the top level {@code Window} that currently has keyboard focus + */ + static public Window getTopLevelWindowWithFocus() { + return topLevelWindowWithFocus; + } +} + +/** + * Handle all Component events in a separate thread. The reason for this is + * that WindowEvents tend to be used to do lots of processing on the Window + * hierarchy. As a result, it can frequently result in deadlock situations. + */ +class ComponentEvtDispatchThread extends Thread { + public ComponentEvtDispatchThread(String name) { + super(name); + } + public void run() { + ComponentEvent ce = null; + while (true) { + synchronized(EventQueueMonitor.componentEventQueueLock) { + while (EventQueueMonitor.componentEventQueue == null) { + try { + EventQueueMonitor.componentEventQueueLock.wait(); + } catch (InterruptedException e) { + } + } + ce = (ComponentEvent)EventQueueMonitor.componentEventQueue.event; + EventQueueMonitor.componentEventQueue = + EventQueueMonitor.componentEventQueue.next; + } + switch (ce.getID()) { + case MouseEvent.MOUSE_MOVED: + case MouseEvent.MOUSE_DRAGGED: + EventQueueMonitor.updateCurrentMousePosition((MouseEvent) ce); + break; + case WindowEvent.WINDOW_ACTIVATED: + EventQueueMonitor.maybeNotifyAssistiveTechnologies(); + EventQueueMonitor.topLevelWindowWithFocus = ((WindowEvent) ce).getWindow(); + break; + + default: + break; + } + } + } +} + +/** + * EventQueueMonitorItem is the basic type that handles the + * queue for queueComponentEvent and the ComponentEvtDispatchThread. + */ +class EventQueueMonitorItem { + AWTEvent event; + EventQueueMonitorItem next; + + EventQueueMonitorItem(AWTEvent evt) { + event = evt; + next = null; + } +} --- /dev/null 2015-03-30 10:54:11.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/GUIInitializedListener.java 2015-03-30 10:54:10.746472100 -0500 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.awt.*; +import java.util.*; +import javax.accessibility.*; + +/** + * The {@code GUIInitializedListener} interface is used by the {@link EventQueueMonitor} + * class to notify an interested party when the GUI subsystem has been + * initialized. This is necessary because assistive technologies can + * be loaded before the GUI subsystem is initialized. As a result, + * assistive technologies should check the + * {@link EventQueueMonitor#isGUIInitialized isGUIInitialized} method + * of {@code EventQueueMonitor} before creating any GUI components. If the + * return value is true, assistive technologies can create GUI components + * following the same thread restrictions as any other application. If + * the return value is false, the assistive technology should register + * a {@code GUIInitializedListener} with the {@code EventQueueMonitor} to be notified + * when the GUI subsystem is initialized. + * + * @see EventQueueMonitor + * @see EventQueueMonitor#isGUIInitialized + * @see EventQueueMonitor#addGUIInitializedListener + * @see EventQueueMonitor#removeGUIInitializedListener + * + */ +@jdk.Exported +public interface GUIInitializedListener extends EventListener { + + /** + * Invoked when the GUI subsystem is initialized and it's OK for + * the assisitive technology to create instances of GUI objects. + */ + public void guiInitialized(); + +} --- /dev/null 2015-03-30 10:54:14.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/GUIInitializedMulticaster.java 2015-03-30 10:54:13.873483600 -0500 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.awt.*; +import java.util.EventListener; +import javax.accessibility.*; + + +/** + * The GUIInitializedMulticaster class is used to maintain a list of + * GUIInitializedListener classes. It is intended to be used primarily + * for internal support in the EventQueueMonitor class, and is not intended + * to be used by classes outside the Java Accessibility Utility package. + * + * @see EventQueueMonitor + * @see EventQueueMonitor#addGUIInitializedListener + * @see EventQueueMonitor#removeGUIInitializedListener + * + */ +@jdk.Exported(false) +public class GUIInitializedMulticaster + extends AWTEventMulticaster implements GUIInitializedListener +{ + protected GUIInitializedMulticaster(EventListener a, EventListener b) { + super(a, b); + } + + public void guiInitialized() { + ((GUIInitializedListener)a).guiInitialized(); + ((GUIInitializedListener)b).guiInitialized(); + } + + public static GUIInitializedListener add(GUIInitializedListener a, GUIInitializedListener b) { + return (GUIInitializedListener)addInternal(a, b); + } + + public static GUIInitializedListener remove(GUIInitializedListener l, GUIInitializedListener oldl) { + return (GUIInitializedListener)removeInternal(l, oldl); + } + + protected static EventListener addInternal(EventListener a, EventListener b) { + if (a == null) return b; + if (b == null) return a; + return new GUIInitializedMulticaster(a, b); + } + + protected static EventListener removeInternal(EventListener l, EventListener oldl) { + if (l == oldl || l == null) { + return null; + } else if (l instanceof GUIInitializedMulticaster) { + return ((GUIInitializedMulticaster)l).remove(oldl); + } else { + return l; // it's not here + } + } + +} --- /dev/null 2015-03-30 10:54:17.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/SwingEventMonitor.java 2015-03-30 10:54:17.015495900 -0500 @@ -0,0 +1,2542 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.util.*; +import java.beans.*; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.table.*; +import javax.swing.tree.*; +import javax.swing.text.*; +import javax.swing.undo.*; +import javax.accessibility.*; + + +/** + *

{@code SwingEventMonitor} extends {@link AWTEventMonitor} by adding a suite of + * listeners conditionally installed on every Swing component instance + * in the Java Virtual Machine. The events captured by these listeners + * are made available through a unified set of listeners supported by + * {@code SwingEventMonitor}. With this, all the individual events on each of the + * AWT and Swing component instances are funneled into one set of listeners + * broken down by category (see {@link EventID} for the categories). + *

This class depends upon {@link EventQueueMonitor}, which provides the base + * level support for capturing the top-level containers as they are created. + *

Because this class extends {@code AWTEventMonitor}, it is not + * necessary to use this class and {@code AWTEventMonitor} at the same time. + * If you want to monitor both AWT and Swing components, you should + * use just this class. + * + * @see AWTEventMonitor + * + */ +@jdk.Exported +public class SwingEventMonitor extends AWTEventMonitor { + + /** + * The master list of all listeners registered by other classes. + * This can only be publicly modified by calling the add or + * remove listener methods in this class. + */ + static protected final EventListenerList listenerList = new EventListenerList(); + + /** + * The actual listener that is installed on the component instances. + * This listener calls the other registered listeners when an event + * occurs. By doing things this way, the actual number of listeners + * installed on a component instance is drastically reduced. + */ + static protected final SwingEventListener swingListener = new SwingEventListener(); + + /** + * Adds the specified listener to receive all {@link EventID#ANCESTOR ANCESTOR} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeAncestorListener + */ + static public void addAncestorListener(AncestorListener l) { + if (listenerList.getListenerCount(AncestorListener.class) == 0) { + swingListener.installListeners(EventID.ANCESTOR); + } + listenerList.add(AncestorListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#ANCESTOR ANCESTOR} events when they occur. + * + * @param l the listener to remove + * @see #addAncestorListener + */ + static public void removeAncestorListener(AncestorListener l) { + listenerList.remove(AncestorListener.class, l); + if (listenerList.getListenerCount(AncestorListener.class) == 0) { + swingListener.removeListeners(EventID.ANCESTOR); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#CARET CARET} events + * on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeCaretListener + */ + static public void addCaretListener(CaretListener l) { + if (listenerList.getListenerCount(CaretListener.class) == 0) { + swingListener.installListeners(EventID.CARET); + } + listenerList.add(CaretListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#CARET CARET} events when they occur. + * + * @param l the listener to remove + * @see #addCaretListener + */ + static public void removeCaretListener(CaretListener l) { + listenerList.remove(CaretListener.class, l); + if (listenerList.getListenerCount(CaretListener.class) == 0) { + swingListener.removeListeners(EventID.CARET); + } + } + + /** + * Adds the specified listener to receive all + * {@link EventID#CELLEDITOR CELLEDITOR} events on each + * component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeCellEditorListener + */ + static public void addCellEditorListener(CellEditorListener l) { + if (listenerList.getListenerCount(CellEditorListener.class) == 0) { + swingListener.installListeners(EventID.CELLEDITOR); + } + listenerList.add(CellEditorListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#CELLEDITOR CELLEDITOR} events when they occur. + * + * @param l the listener to remove + * @see #addCellEditorListener + */ + static public void removeCellEditorListener(CellEditorListener l) { + listenerList.remove(CellEditorListener.class, l); + if (listenerList.getListenerCount(CellEditorListener.class) == 0) { + swingListener.removeListeners(EventID.CELLEDITOR); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#CHANGE CHANGE} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeChangeListener + */ + static public void addChangeListener(ChangeListener l) { + if (listenerList.getListenerCount(ChangeListener.class) == 0) { + swingListener.installListeners(EventID.CHANGE); + } + listenerList.add(ChangeListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#CHANGE CHANGE} events when they occur. + * + * @param l the listener to remove + * @see #addChangeListener + */ + static public void removeChangeListener(ChangeListener l) { + listenerList.remove(ChangeListener.class, l); + if (listenerList.getListenerCount(ChangeListener.class) == 0) { + swingListener.removeListeners(EventID.CHANGE); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#COLUMNMODEL COLUMNMODEL} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeColumnModelListener + */ + static public void addColumnModelListener(TableColumnModelListener l) { + if (listenerList.getListenerCount(TableColumnModelListener.class) == 0) { + swingListener.installListeners(EventID.COLUMNMODEL); + } + listenerList.add(TableColumnModelListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#COLUMNMODEL COLUMNMODEL} events when they occur. + * + * @param l the listener to remove + * @see #addColumnModelListener + */ + static public void removeColumnModelListener(TableColumnModelListener l) { + listenerList.remove(TableColumnModelListener.class, l); + if (listenerList.getListenerCount(TableColumnModelListener.class) == 0) { + swingListener.removeListeners(EventID.COLUMNMODEL); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#DOCUMENT DOCUMENT} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeDocumentListener + */ + static public void addDocumentListener(DocumentListener l) { + if (listenerList.getListenerCount(DocumentListener.class) == 0) { + swingListener.installListeners(EventID.DOCUMENT); + } + listenerList.add(DocumentListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#DOCUMENT DOCUMENT} events when they occur. + * + * @param l the listener to remove + * @see #addDocumentListener + */ + static public void removeDocumentListener(DocumentListener l) { + listenerList.remove(DocumentListener.class, l); + if (listenerList.getListenerCount(DocumentListener.class) == 0) { + swingListener.removeListeners(EventID.DOCUMENT); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#LISTDATA LISTDATA} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeListDataListener + */ + static public void addListDataListener(ListDataListener l) { + if (listenerList.getListenerCount(ListDataListener.class) == 0) { + swingListener.installListeners(EventID.LISTDATA); + } + listenerList.add(ListDataListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#LISTDATA LISTDATA} events when they occur. + * + * @param l the listener to remove + * @see #addListDataListener + */ + static public void removeListDataListener(ListDataListener l) { + listenerList.remove(ListDataListener.class, l); + if (listenerList.getListenerCount(ListDataListener.class) == 0) { + swingListener.removeListeners(EventID.LISTDATA); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#LISTSELECTION LISTSELECTION} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeListSelectionListener + */ + static public void addListSelectionListener(ListSelectionListener l) { + if (listenerList.getListenerCount(ListSelectionListener.class) == 0) { + swingListener.installListeners(EventID.LISTSELECTION); + } + listenerList.add(ListSelectionListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#LISTSELECTION LISTSELECTION} events when they occur. + * + * @param l the listener to remove + * @see #addListSelectionListener + */ + static public void removeListSelectionListener(ListSelectionListener l) { + listenerList.remove(ListSelectionListener.class, l); + if (listenerList.getListenerCount(ListSelectionListener.class) == 0) { + swingListener.removeListeners(EventID.LISTSELECTION); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#MENU MENU} events + * on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeMenuListener + */ + static public void addMenuListener(MenuListener l) { + if (listenerList.getListenerCount(MenuListener.class) == 0) { + swingListener.installListeners(EventID.MENU); + } + listenerList.add(MenuListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#MENU MENU} events when they occur. + * + * @param l the listener to remove + * @see #addMenuListener + */ + static public void removeMenuListener(MenuListener l) { + listenerList.remove(MenuListener.class, l); + if (listenerList.getListenerCount(MenuListener.class) == 0) { + swingListener.removeListeners(EventID.MENU); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#POPUPMENU POPUPMENU} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removePopupMenuListener + */ + static public void addPopupMenuListener(PopupMenuListener l) { + if (listenerList.getListenerCount(PopupMenuListener.class) == 0) { + swingListener.installListeners(EventID.POPUPMENU); + } + listenerList.add(PopupMenuListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#POPUPMENU POPUPMENU} events when they occur. + * + * @param l the listener to remove + * @see #addPopupMenuListener + */ + static public void removePopupMenuListener(PopupMenuListener l) { + listenerList.remove(PopupMenuListener.class, l); + if (listenerList.getListenerCount(PopupMenuListener.class) == 0) { + swingListener.removeListeners(EventID.POPUPMENU); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#TABLEMODEL TABLEMODEL} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeTableModelListener + */ + static public void addTableModelListener(TableModelListener l) { + if (listenerList.getListenerCount(TableModelListener.class) == 0) { + swingListener.installListeners(EventID.TABLEMODEL); + } + listenerList.add(TableModelListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#TABLEMODEL TABLEMODEL} events when they occur. + * + * @param l the listener to remove + * @see #addTableModelListener + */ + static public void removeTableModelListener(TableModelListener l) { + listenerList.remove(TableModelListener.class, l); + if (listenerList.getListenerCount(TableModelListener.class) == 0) { + swingListener.removeListeners(EventID.TABLEMODEL); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#TREEEXPANSION TREEEXPANSION} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeTreeExpansionListener + */ + static public void addTreeExpansionListener(TreeExpansionListener l) { + if (listenerList.getListenerCount(TreeExpansionListener.class) == 0) { + swingListener.installListeners(EventID.TREEEXPANSION); + } + listenerList.add(TreeExpansionListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#TREEEXPANSION TREEEXPANSION} events when they occur. + * + * @param l the listener to remove + * @see #addTreeExpansionListener + */ + static public void removeTreeExpansionListener(TreeExpansionListener l) { + listenerList.remove(TreeExpansionListener.class, l); + if (listenerList.getListenerCount(TreeExpansionListener.class) == 0) { + swingListener.removeListeners(EventID.TREEEXPANSION); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#TREEMODEL TREEMODEL} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeTreeModelListener + */ + static public void addTreeModelListener(TreeModelListener l) { + if (listenerList.getListenerCount(TreeModelListener.class) == 0) { + swingListener.installListeners(EventID.TREEMODEL); + } + listenerList.add(TreeModelListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#TREEMODEL TREEMODEL} events when they occur. + * + * @param l the listener to remove + * @see #addTreeModelListener + */ + static public void removeTreeModelListener(TreeModelListener l) { + listenerList.remove(TreeModelListener.class, l); + if (listenerList.getListenerCount(TreeModelListener.class) == 0) { + swingListener.removeListeners(EventID.TREEMODEL); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#TREESELECTION TREESELECTION} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeTreeSelectionListener + */ + static public void addTreeSelectionListener(TreeSelectionListener l) { + if (listenerList.getListenerCount(TreeSelectionListener.class) == 0) { + swingListener.installListeners(EventID.TREESELECTION); + } + listenerList.add(TreeSelectionListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#TREESELECTION TREESELECTION} events when they occur. + * @see #addTreeSelectionListener + * @param l the listener to remove + */ + static public void removeTreeSelectionListener(TreeSelectionListener l) { + listenerList.remove(TreeSelectionListener.class, l); + if (listenerList.getListenerCount(TreeSelectionListener.class) == 0) { + swingListener.removeListeners(EventID.TREESELECTION); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#UNDOABLEEDIT UNDOABLEEDIT} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeUndoableEditListener + */ + static public void addUndoableEditListener(UndoableEditListener l) { + if (listenerList.getListenerCount(UndoableEditListener.class) == 0) { + swingListener.installListeners(EventID.UNDOABLEEDIT); + } + listenerList.add(UndoableEditListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#UNDOABLEEDIT UNDOABLEEDIT} events when they occur. + * + * @param l the listener to remove + * @see #addUndoableEditListener + */ + static public void removeUndoableEditListener(UndoableEditListener l) { + listenerList.remove(UndoableEditListener.class, l); + if (listenerList.getListenerCount(UndoableEditListener.class) == 0) { + swingListener.removeListeners(EventID.UNDOABLEEDIT); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#INTERNALFRAME INTERNALFRAME} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeInternalFrameListener + */ + static public void addInternalFrameListener(InternalFrameListener l) { + if (listenerList.getListenerCount(InternalFrameListener.class) == 0) { + swingListener.installListeners(EventID.INTERNALFRAME); + } + listenerList.add(InternalFrameListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#INTERNALFRAME INTERNALFRAME} events when they occur. + * + * @param l the listener to remove + * @see #addInternalFrameListener + */ + static public void removeInternalFrameListener(InternalFrameListener l) { + listenerList.remove(InternalFrameListener.class, l); + if (listenerList.getListenerCount(InternalFrameListener.class) == 0) { + swingListener.removeListeners(EventID.INTERNALFRAME); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#PROPERTYCHANGE PROPERTYCHANGE} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removePropertyChangeListener + */ + static public void addPropertyChangeListener(PropertyChangeListener l) { + if (listenerList.getListenerCount(PropertyChangeListener.class) == 0) { + swingListener.installListeners(EventID.PROPERTYCHANGE); + } + listenerList.add(PropertyChangeListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#PROPERTYCHANGE PROPERTYCHANGE} events when they occur. + * @see #addPropertyChangeListener + * @param l the listener to remove + */ + static public void removePropertyChangeListener(PropertyChangeListener l) { + listenerList.remove(PropertyChangeListener.class, l); + if (listenerList.getListenerCount(PropertyChangeListener.class) == 0) { + swingListener.removeListeners(EventID.PROPERTYCHANGE); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#VETOABLECHANGE VETOABLECHANGE} + * events on each component instance in the Java Virtual Machine as they occur. + *

Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeVetoableChangeListener + */ + static public void addVetoableChangeListener(VetoableChangeListener l) { + if (listenerList.getListenerCount(VetoableChangeListener.class) == 0) { + swingListener.installListeners(EventID.VETOABLECHANGE); + } + listenerList.add(VetoableChangeListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#VETOABLECHANGE VETOABLECHANGE} events when they occur. + * + * @param l the listener to remove + * @see #addVetoableChangeListener + */ + static public void removeVetoableChangeListener(VetoableChangeListener l) { + listenerList.remove(VetoableChangeListener.class, l); + if (listenerList.getListenerCount(VetoableChangeListener.class) == 0) { + swingListener.removeListeners(EventID.VETOABLECHANGE); + } + } + + + /** + * SwingEventListener is the class that does all the work for + * SwingEventMonitor. It is not intended for use by any other class + * except SwingEventMonitor. + * + */ + static class SwingEventListener extends AWTEventsListener + implements AncestorListener, CaretListener, CellEditorListener, + ChangeListener, DocumentListener, ListDataListener, + ListSelectionListener, MenuListener, PopupMenuListener, + TableColumnModelListener, TableModelListener, TreeExpansionListener, + TreeModelListener, TreeSelectionListener, UndoableEditListener, + InternalFrameListener, + PropertyChangeListener, VetoableChangeListener { + + /** + * internal variables for Caret introspection + */ + private java.lang.Class caretListeners[]; + private java.lang.reflect.Method removeCaretMethod; + private java.lang.reflect.Method addCaretMethod; + private java.lang.Object caretArgs[]; + + /** + * internal variables for CellEditor introspection + */ + private java.lang.Class cellEditorListeners[]; + private java.lang.reflect.Method removeCellEditorMethod; + private java.lang.reflect.Method addCellEditorMethod; + private java.lang.Object cellEditorArgs[]; + private java.lang.reflect.Method getCellEditorMethod; + + /** + * internal variables for Change introspection + */ + private java.lang.Class changeListeners[]; + private java.lang.reflect.Method removeChangeMethod; + private java.lang.reflect.Method addChangeMethod; + private java.lang.Object changeArgs[]; + + /** + * internal variable for ColumnModel introspection + */ + private java.lang.reflect.Method getColumnModelMethod; + + /** + * internal variables for Document introspection + */ + private java.lang.Class documentListeners[]; + private java.lang.reflect.Method removeDocumentMethod; + private java.lang.reflect.Method addDocumentMethod; + private java.lang.Object documentArgs[]; + private java.lang.reflect.Method getDocumentMethod; + + /** + * internal variable for ListData, Table, and Tree introspection + */ + private java.lang.reflect.Method getModelMethod; + + /** + * internal variables for ListSelection introspection + */ + private java.lang.Class listSelectionListeners[]; + private java.lang.reflect.Method removeListSelectionMethod; + private java.lang.reflect.Method addListSelectionMethod; + private java.lang.Object listSelectionArgs[]; + private java.lang.reflect.Method getSelectionModelMethod; + + /** + * internal variables for Menu introspection + */ + private java.lang.Class menuListeners[]; + private java.lang.reflect.Method removeMenuMethod; + private java.lang.reflect.Method addMenuMethod; + private java.lang.Object menuArgs[]; + + /** + * internal variables for PopupMenu introspection + */ + private java.lang.Class popupMenuListeners[]; + private java.lang.reflect.Method removePopupMenuMethod; + private java.lang.reflect.Method addPopupMenuMethod; + private java.lang.Object popupMenuArgs[]; + private java.lang.reflect.Method getPopupMenuMethod; + + /** + * internal variables for TreeExpansion introspection + */ + private java.lang.Class treeExpansionListeners[]; + private java.lang.reflect.Method removeTreeExpansionMethod; + private java.lang.reflect.Method addTreeExpansionMethod; + private java.lang.Object treeExpansionArgs[]; + + /** + * internal variables for TreeSelection introspection + */ + private java.lang.Class treeSelectionListeners[]; + private java.lang.reflect.Method removeTreeSelectionMethod; + private java.lang.reflect.Method addTreeSelectionMethod; + private java.lang.Object treeSelectionArgs[]; + + /** + * internal variables for UndoableEdit introspection + */ + private java.lang.Class undoableEditListeners[]; + private java.lang.reflect.Method removeUndoableEditMethod; + private java.lang.reflect.Method addUndoableEditMethod; + private java.lang.Object undoableEditArgs[]; + + /** + * internal variables for InternalFrame introspection + */ + private java.lang.Class internalFrameListeners[]; + private java.lang.reflect.Method removeInternalFrameMethod; + private java.lang.reflect.Method addInternalFrameMethod; + private java.lang.Object internalFrameArgs[]; + + /** + * internal variables for PropertyChange introspection + */ + private java.lang.Class propertyChangeListeners[]; + private java.lang.reflect.Method removePropertyChangeMethod; + private java.lang.reflect.Method addPropertyChangeMethod; + private java.lang.Object propertyChangeArgs[]; + + /** + * internal variables for a variety of change introspections + */ + private java.lang.Class nullClass[]; + private java.lang.Object nullArgs[]; + + /** + * Create a new instance of this class and install it on each component + * instance in the virtual machine that supports any of the currently + * registered listeners in SwingEventMonitor. Also registers itself + * as a TopLevelWindowListener with EventQueueMonitor so it can + * automatically add new listeners to new components. + * @see EventQueueMonitor + * @see SwingEventMonitor + */ + public SwingEventListener() { + initializeIntrospection(); + installListeners(); + EventQueueMonitor.addTopLevelWindowListener(this); + } + + /** + * Set up all of the variables needed for introspection + */ + private boolean initializeIntrospection() { + try { + caretListeners = new java.lang.Class[1]; + caretArgs = new java.lang.Object[1]; + caretListeners[0] = Class.forName("javax.swing.event.CaretListener"); + caretArgs[0] = this; + + cellEditorListeners = new java.lang.Class[1]; + cellEditorArgs = new java.lang.Object[1]; + cellEditorListeners[0] = Class.forName("javax.swing.event.CellEditorListener"); + cellEditorArgs[0] = this; + + changeListeners = new java.lang.Class[1]; + changeArgs = new java.lang.Object[1]; + changeListeners[0] = Class.forName("javax.swing.event.ChangeListener"); + changeArgs[0] = this; + + documentListeners = new java.lang.Class[1]; + documentArgs = new java.lang.Object[1]; + documentListeners[0] = Class.forName("javax.swing.event.DocumentListener"); + documentArgs[0] = this; + + listSelectionListeners = new java.lang.Class[1]; + listSelectionArgs = new java.lang.Object[1]; + listSelectionListeners[0] = Class.forName("javax.swing.event.ListSelectionListener"); + listSelectionArgs[0] = this; + + menuListeners = new java.lang.Class[1]; + menuArgs = new java.lang.Object[1]; + menuListeners[0] = Class.forName("javax.swing.event.MenuListener"); + menuArgs[0] = this; + + popupMenuListeners = new java.lang.Class[1]; + popupMenuArgs = new java.lang.Object[1]; + popupMenuListeners[0] = Class.forName("javax.swing.event.PopupMenuListener"); + popupMenuArgs[0] = this; + + treeExpansionListeners = new java.lang.Class[1]; + treeExpansionArgs = new java.lang.Object[1]; + treeExpansionListeners[0] = Class.forName("javax.swing.event.TreeExpansionListener"); + treeExpansionArgs[0] = this; + + treeSelectionListeners = new java.lang.Class[1]; + treeSelectionArgs = new java.lang.Object[1]; + treeSelectionListeners[0] = Class.forName("javax.swing.event.TreeSelectionListener"); + treeSelectionArgs[0] = this; + + undoableEditListeners = new java.lang.Class[1]; + undoableEditArgs = new java.lang.Object[1]; + undoableEditListeners[0] = Class.forName("javax.swing.event.UndoableEditListener"); + undoableEditArgs[0] = this; + + internalFrameListeners = new java.lang.Class[1]; + internalFrameArgs = new java.lang.Object[1]; + internalFrameListeners[0] = Class.forName("javax.swing.event.InternalFrameListener"); + internalFrameArgs[0] = this; + + nullClass = new java.lang.Class[0]; + nullArgs = new java.lang.Object[0]; + + } catch (ClassNotFoundException e) { + System.out.println("EXCEPTION - Class 'javax.swing.event.*' not in CLASSPATH"); + return false; + } + + try { + propertyChangeListeners = new java.lang.Class[1]; + propertyChangeArgs = new java.lang.Object[1]; + propertyChangeListeners[0] = Class.forName("java.beans.PropertyChangeListener"); + propertyChangeArgs[0] = this; + + } catch (ClassNotFoundException e) { + System.out.println("EXCEPTION - Class 'java.beans.*' not in CLASSPATH"); + return false; + } + + return true; + } + + /** + * Installs all appropriate Swing listeners to just the component. + * Also calls super (AWTEventsListener.installListeners()) to install + * the requested AWT listeners. + * @param c the component to add listeners to + */ + protected void installListeners(Component c) { + + // This SwingEventListener needs to be notified when a new + // Swing component has been added so it can add Swing listeners + // to these components. As a result, we always need a Container + // listener on every Container. + // + installListeners(c,EventID.CONTAINER); + + // conditionally install Swing listeners + // + if (SwingEventMonitor.listenerList.getListenerCount(AncestorListener.class) > 0) { + installListeners(c,EventID.ANCESTOR); + } + if (SwingEventMonitor.listenerList.getListenerCount(CaretListener.class) > 0) { + installListeners(c,EventID.CARET); + } + if (SwingEventMonitor.listenerList.getListenerCount(CellEditorListener.class) > 0) { + installListeners(c,EventID.CELLEDITOR); + } + if (SwingEventMonitor.listenerList.getListenerCount(ChangeListener.class) > 0) { + installListeners(c,EventID.CHANGE); + } + if (SwingEventMonitor.listenerList.getListenerCount(TableColumnModelListener.class) > 0) { + installListeners(c,EventID.COLUMNMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(DocumentListener.class) > 0) { + installListeners(c,EventID.DOCUMENT); + } + if (SwingEventMonitor.listenerList.getListenerCount(ListDataListener.class) > 0) { + installListeners(c,EventID.LISTDATA); + } + if (SwingEventMonitor.listenerList.getListenerCount(ListSelectionListener.class) > 0) { + installListeners(c,EventID.LISTSELECTION); + } + if (SwingEventMonitor.listenerList.getListenerCount(MenuListener.class) > 0) { + installListeners(c,EventID.MENU); + } + if (SwingEventMonitor.listenerList.getListenerCount(PopupMenuListener.class) > 0) { + installListeners(c,EventID.POPUPMENU); + } + if (SwingEventMonitor.listenerList.getListenerCount(TableModelListener.class) > 0) { + installListeners(c,EventID.TABLEMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeExpansionListener.class) > 0) { + installListeners(c,EventID.TREEEXPANSION); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeModelListener.class) > 0) { + installListeners(c,EventID.TREEMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeSelectionListener.class) > 0) { + installListeners(c,EventID.TREESELECTION); + } + if (SwingEventMonitor.listenerList.getListenerCount(UndoableEditListener.class) > 0) { + installListeners(c,EventID.UNDOABLEEDIT); + } + if (SwingEventMonitor.listenerList.getListenerCount(InternalFrameListener.class) > 0) { + installListeners(c,EventID.INTERNALFRAME); + } + + // Conditionally install Beans listeners + // + if (SwingEventMonitor.listenerList.getListenerCount(PropertyChangeListener.class) > 0) { + installListeners(c,EventID.PROPERTYCHANGE); + } + if (SwingEventMonitor.listenerList.getListenerCount(VetoableChangeListener.class) > 0) { + installListeners(c,EventID.VETOABLECHANGE); + } + + // Now install the AWT listeners if needed. + // + super.installListeners(c); + } + + /** + * Installs all appropriate Swing listeners to the component and all its + * children. As a precaution, it always attempts to remove itself as + * a listener first so we're always guaranteed it will installed itself + * just once. + * @param c the component to add listeners to + * @param eventID the eventID to add listeners for + */ + protected void installListeners(Component c, int eventID) { + + // install the appropriate listener hook into this component + // + switch (eventID) { + + case EventID.CONTAINER: + if (c instanceof Container) { + ((Container) c).removeContainerListener(this); + ((Container) c).addContainerListener(this); + } + break; + + case EventID.ANCESTOR: + if (c instanceof JComponent) { + ((JComponent) c).removeAncestorListener(this); + ((JComponent) c).addAncestorListener(this); + } + break; + + case EventID.CARET: + try { + removeCaretMethod = c.getClass().getMethod( + "removeCaretListener", caretListeners); + addCaretMethod = c.getClass().getMethod( + "addCaretListener", caretListeners); + try { + removeCaretMethod.invoke(c, caretArgs); + addCaretMethod.invoke(c, caretArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.CELLEDITOR: + // Look for components which support the getCellEditor method + // (e.g. JTable, JTree) + // + try { + getCellEditorMethod = c.getClass().getMethod( + "getCellEditorMethod", nullClass); + try { + Object o = getCellEditorMethod.invoke(c, nullArgs); + if (o != null && o instanceof CellEditor) { + ((CellEditor) o).removeCellEditorListener(this); + ((CellEditor) o).addCellEditorListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support CellEditor listeners + // (no current example) + // + try { + removeCellEditorMethod = c.getClass().getMethod( + "removeCellEditorListener", cellEditorListeners); + addCellEditorMethod = c.getClass().getMethod( + "addCellEditorListener", cellEditorListeners); + try { + removeCellEditorMethod.invoke(c, cellEditorArgs); + addCellEditorMethod.invoke(c, cellEditorArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.CHANGE: + // [[[FIXME: Need to add support for Style, StyleContext -pk]]] + + // Look for components which support Change listeners + // (e.g. AbstractButton, Caret, JProgressBar, JSlider, + // JTabbedpane, JTextComponent, JViewport) + // + try { + removeChangeMethod = c.getClass().getMethod( + "removeChangeListener", changeListeners); + addChangeMethod = c.getClass().getMethod( + "addChangeListener", changeListeners); + try { + removeChangeMethod.invoke(c, changeArgs); + addChangeMethod.invoke(c, changeArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support the getModel method + // whose model supports Change listeners + // (e.g. BoundedRangeModel, ButtonModel, SingleSelectionModel) + // + try { + getModelMethod = c.getClass().getMethod( + "getModel", nullClass); + try { + Object o = getModelMethod.invoke(c, nullArgs); + if (o != null) { + removeChangeMethod = o.getClass().getMethod( + "removeChangeListener", changeListeners); + addChangeMethod = o.getClass().getMethod( + "addChangeListener", changeListeners); + removeChangeMethod.invoke(o, changeArgs); + addChangeMethod.invoke(o, changeArgs); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + break; + + case EventID.COLUMNMODEL: + try { + getColumnModelMethod = c.getClass().getMethod( + "getTableColumnModel", nullClass); + try { + Object o = getColumnModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof TableColumnModel) { + ((TableColumnModel) o).removeColumnModelListener(this); + ((TableColumnModel) o).addColumnModelListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.DOCUMENT: + // Look for components which support the getDocument method + // (e.g. JTextComponent) + // + try { + getDocumentMethod = c.getClass().getMethod( + "getDocument", nullClass); + try { + Object o = getDocumentMethod.invoke(c, nullArgs); + if (o != null && o instanceof Document) { + ((Document) o).removeDocumentListener(this); + ((Document) o).addDocumentListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support Document listeners + // (no current example) + // + try { + removeDocumentMethod = c.getClass().getMethod( + "removeDocumentListener", documentListeners); + addDocumentMethod = c.getClass().getMethod( + "addDocumentListener", documentListeners); + try { + removeDocumentMethod.invoke(c, documentArgs); + addDocumentMethod.invoke(c, documentArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + // Add the monitor as a PropertyChangeListener for document + // change events from text components. + // + if (c instanceof JTextComponent) { + try { + removePropertyChangeMethod = c.getClass().getMethod( + "removePropertyChangeListener", + propertyChangeListeners); + addPropertyChangeMethod = c.getClass().getMethod( + "addPropertyChangeListener", + propertyChangeListeners); + try { + removePropertyChangeMethod.invoke(c, + propertyChangeArgs); + addPropertyChangeMethod.invoke(c, + propertyChangeArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + } + break; + + case EventID.LISTDATA: + case EventID.TABLEMODEL: + case EventID.TREEMODEL: + try { + getModelMethod = c.getClass().getMethod( + "getModel", nullClass); + try { + Object o = getModelMethod.invoke(c, nullArgs); + if (o != null) { + if (eventID == EventID.LISTDATA && + o instanceof ListModel) { + ((ListModel) o).removeListDataListener(this); + ((ListModel) o).addListDataListener(this); + } else if (eventID == EventID.TABLEMODEL && + o instanceof TableModel) { + ((TableModel) o).removeTableModelListener(this); + ((TableModel) o).addTableModelListener(this); + } else if ( + o instanceof TreeModel) { + ((TreeModel) o).removeTreeModelListener(this); + ((TreeModel) o).addTreeModelListener(this); + } + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.LISTSELECTION: + // Look for components which support ListSelectionListeners + // (e.g. JList) + // + try { + removeListSelectionMethod = c.getClass().getMethod( + "removeListSelectionListener", listSelectionListeners); + addListSelectionMethod = c.getClass().getMethod( + "addListSelectionListener", listSelectionListeners); + try { + removeListSelectionMethod.invoke(c, listSelectionArgs); + addListSelectionMethod.invoke(c, listSelectionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for selection models which support ListSelectionListeners + // (e.g. JTable's selection model) + // + try { + getSelectionModelMethod = c.getClass().getMethod( + "getSelectionModel", nullClass); + try { + Object o = getSelectionModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof ListSelectionModel) { + ((ListSelectionModel) o).removeListSelectionListener(this); + ((ListSelectionModel) o).addListSelectionListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.MENU: + try { + removeMenuMethod = c.getClass().getMethod( + "removeMenuListener", menuListeners); + addMenuMethod = c.getClass().getMethod( + "addMenuListener", menuListeners); + try { + removeMenuMethod.invoke(c, menuArgs); + addMenuMethod.invoke(c, menuArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.POPUPMENU: + // Look for components which support PopupMenuListeners + // (e.g. JPopupMenu) + // + try { + removePopupMenuMethod = c.getClass().getMethod( + "removePopupMenuListener", popupMenuListeners); + addPopupMenuMethod = c.getClass().getMethod( + "addPopupMenuListener", popupMenuListeners); + try { + removePopupMenuMethod.invoke(c, popupMenuArgs); + addPopupMenuMethod.invoke(c, popupMenuArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support getPopupMenu + // (e.g. JMenu) + // + try { + getPopupMenuMethod = c.getClass().getMethod( + "getPopupMenu", nullClass); + try { + Object o = getPopupMenuMethod.invoke(c, nullArgs); + if (o != null) { + removePopupMenuMethod = o.getClass().getMethod( + "removePopupMenuListener", popupMenuListeners); + addPopupMenuMethod = o.getClass().getMethod( + "addPopupMenuListener", popupMenuListeners); + removePopupMenuMethod.invoke(o, popupMenuArgs); + addPopupMenuMethod.invoke(o, popupMenuArgs); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.TREEEXPANSION: + try { + removeTreeExpansionMethod = c.getClass().getMethod( + "removeTreeExpansionListener", treeExpansionListeners); + addTreeExpansionMethod = c.getClass().getMethod( + "addTreeExpansionListener", treeExpansionListeners); + try { + removeTreeExpansionMethod.invoke(c, treeExpansionArgs); + addTreeExpansionMethod.invoke(c, treeExpansionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.TREESELECTION: + try { + removeTreeSelectionMethod = c.getClass().getMethod( + "removeTreeSelectionListener", treeSelectionListeners); + addTreeSelectionMethod = c.getClass().getMethod( + "addTreeSelectionListener", treeSelectionListeners); + try { + removeTreeSelectionMethod.invoke(c, treeSelectionArgs); + addTreeSelectionMethod.invoke(c, treeSelectionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.UNDOABLEEDIT: + // Look for components which support the getDocument method + // (e.g. JTextComponent) + // + try { + getDocumentMethod = c.getClass().getMethod( + "getDocument", nullClass); + try { + Object o = getDocumentMethod.invoke(c, nullArgs); + if (o != null && o instanceof Document) { + ((Document) o).removeUndoableEditListener(this); + ((Document) o).addUndoableEditListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support UndoableEdit listeners + // (no current example) + // + try { + removeUndoableEditMethod = c.getClass().getMethod( + "removeUndoableEditListener", undoableEditListeners); + addUndoableEditMethod = c.getClass().getMethod( + "addUndoableEditListener", undoableEditListeners); + try { + removeUndoableEditMethod.invoke(c, undoableEditArgs); + addUndoableEditMethod.invoke(c, undoableEditArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.INTERNALFRAME: + // Look for components which support InternalFrame listeners + // (e.g. JInternalFrame) + // + try { + removeInternalFrameMethod = c.getClass().getMethod( + "removeInternalFrameListener", internalFrameListeners); + addInternalFrameMethod = c.getClass().getMethod( + "addInternalFrameListener", internalFrameListeners); + try { + removeInternalFrameMethod.invoke(c, internalFrameArgs); + addInternalFrameMethod.invoke(c, internalFrameArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.PROPERTYCHANGE: + // Look for components which support PropertyChange listeners + // (e.g. JComponent) + // + try { + removePropertyChangeMethod = c.getClass().getMethod( + "removePropertyChangeListener", propertyChangeListeners); + addPropertyChangeMethod = c.getClass().getMethod( + "addPropertyChangeListener", propertyChangeListeners); + try { + removePropertyChangeMethod.invoke(c, propertyChangeArgs); + addPropertyChangeMethod.invoke(c, propertyChangeArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support the getSelectionModel method + // (e.g. JTextComponent) + // + try { + getSelectionModelMethod = c.getClass().getMethod( + "getSelectionModel", nullClass); + try { + Object o = getSelectionModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof TreeSelectionModel) { + ((TreeSelectionModel) o).removePropertyChangeListener(this); + ((TreeSelectionModel) o).addPropertyChangeListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.VETOABLECHANGE: + if (c instanceof JComponent) { + ((JComponent) c).removeVetoableChangeListener(this); + ((JComponent) c).addVetoableChangeListener(this); + } + break; + + // Don't bother recursing the children if this isn't going to + // accomplish anything. + // + default: + return; + } + + if (c instanceof Container) { + int count = ((Container) c).getComponentCount(); + for (int i = 0; i < count; i++) { + installListeners(((Container) c).getComponent(i), eventID); + } + } + } + + /** + * Removes all listeners for the given component and all its children. + * @param c the component + */ + protected void removeListeners(Component c) { + + // conditionaly remove the Swing listeners + // + if (SwingEventMonitor.listenerList.getListenerCount(AncestorListener.class) > 0) { + removeListeners(c,EventID.ANCESTOR); + } + if (SwingEventMonitor.listenerList.getListenerCount(CaretListener.class) > 0) { + removeListeners(c,EventID.CARET); + } + if (SwingEventMonitor.listenerList.getListenerCount(CellEditorListener.class) > 0) { + removeListeners(c,EventID.CELLEDITOR); + } + if (SwingEventMonitor.listenerList.getListenerCount(ChangeListener.class) > 0) { + removeListeners(c,EventID.CHANGE); + } + if (SwingEventMonitor.listenerList.getListenerCount(TableColumnModelListener.class) > 0) { + removeListeners(c,EventID.COLUMNMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(DocumentListener.class) > 0) { + removeListeners(c,EventID.DOCUMENT); + } + if (SwingEventMonitor.listenerList.getListenerCount(ListDataListener.class) > 0) { + removeListeners(c,EventID.LISTDATA); + } + if (SwingEventMonitor.listenerList.getListenerCount(ListSelectionListener.class) > 0) { + removeListeners(c,EventID.LISTSELECTION); + } + if (SwingEventMonitor.listenerList.getListenerCount(MenuListener.class) > 0) { + removeListeners(c,EventID.MENU); + } + if (SwingEventMonitor.listenerList.getListenerCount(PopupMenuListener.class) > 0) { + removeListeners(c,EventID.POPUPMENU); + } + if (SwingEventMonitor.listenerList.getListenerCount(TableModelListener.class) > 0) { + removeListeners(c,EventID.TABLEMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeExpansionListener.class) > 0) { + removeListeners(c,EventID.TREEEXPANSION); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeModelListener.class) > 0) { + removeListeners(c,EventID.TREEMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeSelectionListener.class) > 0) { + removeListeners(c,EventID.TREESELECTION); + } + if (SwingEventMonitor.listenerList.getListenerCount(UndoableEditListener.class) > 0) { + removeListeners(c,EventID.UNDOABLEEDIT); + } + if (SwingEventMonitor.listenerList.getListenerCount(InternalFrameListener.class) > 0) { + removeListeners(c,EventID.INTERNALFRAME); + } + + // conditionaly remove the beans listeners + // + if (SwingEventMonitor.listenerList.getListenerCount(PropertyChangeListener.class) > 0) { + removeListeners(c,EventID.PROPERTYCHANGE); + } + if (SwingEventMonitor.listenerList.getListenerCount(VetoableChangeListener.class) > 0) { + removeListeners(c,EventID.VETOABLECHANGE); + } + + // Now remove the AWT listeners if needed. + // + super.removeListeners(c); + } + + /** + * Removes all Swing listeners for the event ID from the component and + * all of its children. + * @param c the component to remove listeners from + */ + protected void removeListeners(Component c, int eventID) { + + // remove the appropriate listener hook into this component + // + switch (eventID) { + + case EventID.CONTAINER: + //Never remove these because we're always interested in them + // for our own use. + break; + + case EventID.ANCESTOR: + if (c instanceof JComponent) { + ((JComponent) c).removeAncestorListener(this); + } + break; + + case EventID.CARET: + try { + removeCaretMethod = c.getClass().getMethod( + "removeCaretListener", caretListeners); + try { + removeCaretMethod.invoke(c, caretArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.CELLEDITOR: + // Look for components which support the getCellEditor method + // (e.g. JTable, JTree) + // + try { + getCellEditorMethod = c.getClass().getMethod( + "getCellEditorMethod", nullClass); + try { + Object o = getCellEditorMethod.invoke(c, nullArgs); + if (o != null && o instanceof CellEditor) { + ((CellEditor) o).removeCellEditorListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support CellEditor listeners + // (no current example) + // + try { + removeCellEditorMethod = c.getClass().getMethod( + "removeCellEditorListener", cellEditorListeners); + try { + removeCellEditorMethod.invoke(c, cellEditorArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.CHANGE: + // [[[FIXME: Need to add support for Style, StyleContext -pk ]]] + + // Look for components which support Change listeners + // (e.g. AbstractButton, Caret, JProgressBar, JSlider, + // JTabbedpane, JTextComponent, JViewport) + // + try { + removeChangeMethod = c.getClass().getMethod( + "removeChangeListener", changeListeners); + try { + removeChangeMethod.invoke(c, changeArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support the getModel method + // whose model supports Change listeners + // (e.g. BoundedRangeModel, ButtonModel, SingleSelectionModel) + // + try { + getModelMethod = c.getClass().getMethod( + "getModel", nullClass); + try { + Object o = getModelMethod.invoke(c, nullArgs); + if (o != null) { + removeChangeMethod = o.getClass().getMethod( + "removeChangeListener", changeListeners); + removeChangeMethod.invoke(o, changeArgs); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.COLUMNMODEL: + try { + getColumnModelMethod = c.getClass().getMethod( + "getTableColumnModel", nullClass); + try { + Object o = getColumnModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof TableColumnModel) { + ((TableColumnModel) o).removeColumnModelListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.DOCUMENT: + // Look for components which support the getDocument method + // (e.g. JTextComponent) + // + try { + getDocumentMethod = c.getClass().getMethod( + "getDocument", nullClass); + try { + Object o = getDocumentMethod.invoke(c, nullArgs); + if (o != null && o instanceof Document) { + ((Document) o).removeDocumentListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support Document listeners + // (no current example) + // + try { + removeDocumentMethod = c.getClass().getMethod( + "removeDocumentListener", documentListeners); + try { + removeDocumentMethod.invoke(c, documentArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.LISTDATA: + case EventID.TABLEMODEL: + case EventID.TREEMODEL: + try { + getModelMethod = c.getClass().getMethod( + "getModel", nullClass); + try { + Object o = getModelMethod.invoke(c, nullArgs); + if (o != null) { + if (eventID == EventID.LISTDATA && + o instanceof ListModel) { + ((ListModel) o).removeListDataListener(this); + } else if (eventID == EventID.TABLEMODEL && + o instanceof TableModel) { + ((TableModel) o).removeTableModelListener(this); + } else if ( + o instanceof TreeModel) { + ((TreeModel) o).removeTreeModelListener(this); + } + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.LISTSELECTION: + // Look for components which support ListSelectionListeners + // (e.g. JList) + // + try { + removeListSelectionMethod = c.getClass().getMethod( + "removeListSelectionListener", listSelectionListeners); + try { + removeListSelectionMethod.invoke(c, listSelectionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for selection models which support + // ListSelectionListeners (e.g. JTable's selection model) + // + try { + getSelectionModelMethod = c.getClass().getMethod( + "getSelectionModel", nullClass); + try { + Object o = getSelectionModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof ListSelectionModel) { + ((ListSelectionModel) o).removeListSelectionListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.MENU: + try { + removeMenuMethod = c.getClass().getMethod( + "removeMenuListener", menuListeners); + try { + removeMenuMethod.invoke(c, menuArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.POPUPMENU: + // Look for components which support PopupMenuListeners + // (e.g. JPopupMenu) + // + try { + removePopupMenuMethod = c.getClass().getMethod( + "removePopupMenuListener", popupMenuListeners); + try { + removePopupMenuMethod.invoke(c, popupMenuArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support getPopupMenu + // (e.g. JMenu) + // + try { + getPopupMenuMethod = c.getClass().getMethod( + "getPopupMenu", nullClass); + try { + Object o = getPopupMenuMethod.invoke(c, nullArgs); + if (o != null) { + removePopupMenuMethod = o.getClass().getMethod( + "removePopupMenuListener", popupMenuListeners); + removePopupMenuMethod.invoke(o, popupMenuArgs); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.TREEEXPANSION: + try { + removeTreeExpansionMethod = c.getClass().getMethod( + "removeTreeExpansionListener", treeExpansionListeners); + try { + removeTreeExpansionMethod.invoke(c, treeExpansionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.TREESELECTION: + try { + removeTreeSelectionMethod = c.getClass().getMethod( + "removeTreeSelectionListener", treeSelectionListeners); + try { + removeTreeSelectionMethod.invoke(c, treeSelectionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.UNDOABLEEDIT: + // Look for components which support the getDocument method + // (e.g. JTextComponent) + // + try { + getDocumentMethod = c.getClass().getMethod( + "getDocument", nullClass); + try { + Object o = getDocumentMethod.invoke(c, nullArgs); + if (o != null && o instanceof Document) { + ((Document) o).removeUndoableEditListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support UndoableEdit listeners + // (no current example) + // + try { + removeUndoableEditMethod = c.getClass().getMethod( + "removeUndoableEditListener", undoableEditListeners); + try { + removeUndoableEditMethod.invoke(c, undoableEditArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.INTERNALFRAME: + try { + removeInternalFrameMethod = c.getClass().getMethod( + "removeInternalFrameListener", internalFrameListeners); + try { + removeInternalFrameMethod.invoke(c, internalFrameArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.PROPERTYCHANGE: + // Look for components which support PropertyChange listeners + // (e.g. JComponent) + // + try { + removePropertyChangeMethod = c.getClass().getMethod( + "removePropertyChangeListener", propertyChangeListeners); + try { + removePropertyChangeMethod.invoke(c, propertyChangeArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support the getSelectionModel + // method (e.g. JTextComponent) + // + try { + getSelectionModelMethod = c.getClass().getMethod( + "getSelectionModel", nullClass); + try { + Object o = getSelectionModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof TreeSelectionModel) { + ((TreeSelectionModel) o).removePropertyChangeListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.VETOABLECHANGE: + if (c instanceof JComponent) { + ((JComponent) c).removeVetoableChangeListener(this); + } + break; + + default: + return; + } + + if (c instanceof Container) { + int count = ((Container) c).getComponentCount(); + for (int i = 0; i < count; i++) { + removeListeners(((Container) c).getComponent(i), eventID); + } + } + } + + /********************************************************************/ + /* */ + /* Listener Interface Methods */ + /* */ + /********************************************************************/ + + /* ContainerListener Methods ************************************/ + + public void componentAdded(ContainerEvent e) { + installListeners(e.getChild()); + } + public void componentRemoved(ContainerEvent e) { + removeListeners(e.getChild()); + } + + /* AncestorListener Methods ******************************************/ + + public void ancestorAdded(AncestorEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==AncestorListener.class) { + ((AncestorListener)listeners[i+1]).ancestorAdded(e); + } + } + } + + public void ancestorRemoved(AncestorEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==AncestorListener.class) { + ((AncestorListener)listeners[i+1]).ancestorRemoved(e); + } + } + } + + public void ancestorMoved(AncestorEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==AncestorListener.class) { + ((AncestorListener)listeners[i+1]).ancestorMoved(e); + } + } + } + + /* CaretListener Methods ******************************************/ + + public void caretUpdate(CaretEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==CaretListener.class) { + ((CaretListener)listeners[i+1]).caretUpdate(e); + } + } + } + + /* CellEditorListener Methods *****************************************/ + + public void editingStopped(ChangeEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==CellEditorListener.class) { + ((CellEditorListener)listeners[i+1]).editingStopped(e); + } + } + } + + public void editingCanceled(ChangeEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==CellEditorListener.class) { + ((CellEditorListener)listeners[i+1]).editingCanceled(e); + } + } + } + + /* ChangeListener Methods *****************************************/ + + public void stateChanged(ChangeEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==ChangeListener.class) { + ((ChangeListener)listeners[i+1]).stateChanged(e); + } + } + } + + /* TableColumnModelListener Methods *******************************/ + + public void columnAdded(TableColumnModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableColumnModelListener.class) { + ((TableColumnModelListener)listeners[i+1]).columnAdded(e); + } + } + } + public void columnMarginChanged(ChangeEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableColumnModelListener.class) { + ((TableColumnModelListener)listeners[i+1]).columnMarginChanged(e); + } + } + } + public void columnMoved(TableColumnModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableColumnModelListener.class) { + ((TableColumnModelListener)listeners[i+1]).columnMoved(e); + } + } + } + public void columnRemoved(TableColumnModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableColumnModelListener.class) { + ((TableColumnModelListener)listeners[i+1]).columnRemoved(e); + } + } + } + public void columnSelectionChanged(ListSelectionEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableColumnModelListener.class) { + ((TableColumnModelListener)listeners[i+1]).columnSelectionChanged(e); + } + } + } + + /* DocumentListener Methods **************************************/ + + public void changedUpdate(DocumentEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==DocumentListener.class) { + ((DocumentListener)listeners[i+1]).changedUpdate(e); + } + } + } + public void insertUpdate(DocumentEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==DocumentListener.class) { + ((DocumentListener)listeners[i+1]).insertUpdate(e); + } + } + } + public void removeUpdate(DocumentEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==DocumentListener.class) { + ((DocumentListener)listeners[i+1]).removeUpdate(e); + } + } + } + + /* ListDataListener Methods *****************************************/ + + public void contentsChanged(ListDataEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==ListDataListener.class) { + ((ListDataListener)listeners[i+1]).contentsChanged(e); + } + } + } + public void intervalAdded(ListDataEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==ListDataListener.class) { + ((ListDataListener)listeners[i+1]).intervalAdded(e); + } + } + } + public void intervalRemoved(ListDataEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==ListDataListener.class) { + ((ListDataListener)listeners[i+1]).intervalRemoved(e); + } + } + } + + /* ListSelectionListener Methods ***********************************/ + + public void valueChanged(ListSelectionEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==ListSelectionListener.class) { + ((ListSelectionListener)listeners[i+1]).valueChanged(e); + } + } + } + + /* MenuListener Methods *****************************************/ + + public void menuCanceled(MenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==MenuListener.class) { + ((MenuListener)listeners[i+1]).menuCanceled(e); + } + } + } + public void menuDeselected(MenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==MenuListener.class) { + ((MenuListener)listeners[i+1]).menuDeselected(e); + } + } + } + public void menuSelected(MenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==MenuListener.class) { + ((MenuListener)listeners[i+1]).menuSelected(e); + } + } + } + + /* PopupMenuListener Methods **************************************/ + + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==PopupMenuListener.class) { + ((PopupMenuListener)listeners[i+1]).popupMenuWillBecomeVisible(e); + } + } + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==PopupMenuListener.class) { + ((PopupMenuListener)listeners[i+1]).popupMenuWillBecomeInvisible(e); + } + } + } + + public void popupMenuCanceled(PopupMenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==PopupMenuListener.class) { + ((PopupMenuListener)listeners[i+1]).popupMenuCanceled(e); + } + } + } + + /* TableModelListener Methods **************************************/ + + public void tableChanged(TableModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableModelListener.class) { + ((TableModelListener)listeners[i+1]).tableChanged(e); + } + } + } + + /* TreeExpansionListener Methods **********************************/ + + public void treeCollapsed(TreeExpansionEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeExpansionListener.class) { + ((TreeExpansionListener)listeners[i+1]).treeCollapsed(e); + } + } + } + public void treeExpanded(TreeExpansionEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeExpansionListener.class) { + ((TreeExpansionListener)listeners[i+1]).treeExpanded(e); + } + } + } + + /* TreeModelListener Methods **********************************/ + + public void treeNodesChanged(TreeModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + ((TreeModelListener)listeners[i+1]).treeNodesChanged(e); + } + } + } + public void treeNodesInserted(TreeModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + ((TreeModelListener)listeners[i+1]).treeNodesInserted(e); + } + } + } + public void treeNodesRemoved(TreeModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e); + } + } + } + public void treeStructureChanged(TreeModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + ((TreeModelListener)listeners[i+1]).treeStructureChanged(e); + } + } + } + + /* TreeSelectionListener Methods ***********************************/ + + public void valueChanged(TreeSelectionEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeSelectionListener.class) { + ((TreeSelectionListener)listeners[i+1]).valueChanged(e); + } + } + } + + /* UndoableEditListener Methods **************************************/ + + public void undoableEditHappened(UndoableEditEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==UndoableEditListener.class) { + ((UndoableEditListener)listeners[i+1]).undoableEditHappened(e); + } + } + } + + /* InternalFrame Methods **********************************/ + + public void internalFrameOpened(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameOpened(e); + } + } + } + + public void internalFrameActivated(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameActivated(e); + } + } + } + + public void internalFrameDeactivated(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameDeactivated(e); + } + } + } + + public void internalFrameIconified(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameIconified(e); + } + } + } + + public void internalFrameDeiconified(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameDeiconified(e); + } + } + } + + public void internalFrameClosing(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameClosing(e); + } + } + } + + public void internalFrameClosed(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameClosed(e); + } + } + } + + /* PropertyChangeListener Methods **********************************/ + + public void propertyChange(PropertyChangeEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==PropertyChangeListener.class) { + ((PropertyChangeListener)listeners[i+1]).propertyChange(e); + } + } + // Re-add the monitor as a DocumentChangeListener if + // the document changed in the text component. + if (e.getSource() instanceof JTextComponent) { + Document c = ((JTextComponent)e.getSource()).getDocument(); + if (c == null) { + return; + } + try { + removeDocumentMethod = c.getClass().getMethod( + "removeDocumentListener", documentListeners); + addDocumentMethod = c.getClass().getMethod( + "addDocumentListener", documentListeners); + try { + removeDocumentMethod.invoke(c, documentArgs); + addDocumentMethod.invoke(c, documentArgs); + } catch (java.lang.reflect.InvocationTargetException e2) { + System.out.println("Exception: " + e2.toString()); + } catch (IllegalAccessException e2) { + System.out.println("Exception: " + e2.toString()); + } + } catch (NoSuchMethodException e2) { + // System.out.println("Exception: " + e2.toString()); + } catch (SecurityException e2) { + System.out.println("Exception: " + e2.toString()); + } + } + + } + + /* VetoableChangeListener Methods **********************************/ + + public void vetoableChange(PropertyChangeEvent e) + throws PropertyVetoException { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==VetoableChangeListener.class) { + ((VetoableChangeListener)listeners[i+1]).vetoableChange(e); + } + } + } + } +} --- /dev/null 2015-03-30 10:54:21.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/TopLevelWindowListener.java 2015-03-30 10:54:20.219506800 -0500 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.awt.*; +import java.util.*; +import javax.accessibility.*; + +/** + * The {@code TopLevelWindowListener} interface is used by the {@link EventQueueMonitor} + * class to notify an interested party when a top level window is created + * or destroyed in the Java Virtual Machine. Classes wishing to express + * an interest in top level window events should implement this interface + * and register themselves with the {@code EventQueueMonitor} by calling the + * {@link EventQueueMonitor#addTopLevelWindowListener EventQueueMonitor.addTopLevelWindowListener} + * class method. + * + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + * @see EventQueueMonitor#removeTopLevelWindowListener + * + */ +@jdk.Exported +public interface TopLevelWindowListener extends EventListener { + + /** + * Invoked when a new top level window has been created. + * + * @param w the Window that was created + */ + public void topLevelWindowCreated(Window w); + + /** + * Invoked when a top level window has been destroyed. + * + * @param w the Window that was destroyed + */ + public void topLevelWindowDestroyed(Window w); +} --- /dev/null 2015-03-30 10:54:24.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/TopLevelWindowMulticaster.java 2015-03-30 10:54:23.333514700 -0500 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.awt.*; +import java.util.EventListener; +import javax.accessibility.*; + + +/** + * The TopLevelWindowMulticaster class is used to maintain a list of + * TopLevelWindowListener classes. It is intended to be used primarily + * for internal support in the EventQueueMonitor class, and is not intended + * to be used by classes outside the Java Accessibility Utility package. + * + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + * @see EventQueueMonitor#removeTopLevelWindowListener + * + */ +@jdk.Exported(false) +public class TopLevelWindowMulticaster + extends AWTEventMulticaster implements TopLevelWindowListener +{ + protected TopLevelWindowMulticaster(EventListener a, EventListener b) { + super(a, b); + } + + public void topLevelWindowCreated(Window w) { + ((TopLevelWindowListener)a).topLevelWindowCreated(w); + ((TopLevelWindowListener)b).topLevelWindowCreated(w); + } + + public void topLevelWindowDestroyed(Window w) { + ((TopLevelWindowListener)a).topLevelWindowDestroyed(w); + ((TopLevelWindowListener)b).topLevelWindowDestroyed(w); + } + + public static TopLevelWindowListener add(TopLevelWindowListener a, TopLevelWindowListener b) { + return (TopLevelWindowListener)addInternal(a, b); + } + + public static TopLevelWindowListener remove(TopLevelWindowListener l, TopLevelWindowListener oldl) { + return (TopLevelWindowListener)removeInternal(l, oldl); + } + + protected static EventListener addInternal(EventListener a, EventListener b) { + if (a == null) return b; + if (b == null) return a; + return new TopLevelWindowMulticaster(a, b); + } + + protected static EventListener removeInternal(EventListener l, EventListener oldl) { + if (l == oldl || l == null) { + return null; + } else if (l instanceof TopLevelWindowMulticaster) { + return ((TopLevelWindowMulticaster)l).remove(oldl); + } else { + return l; // it's not here + } + } + +} --- /dev/null 2015-03-30 10:54:27.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/Translator.java 2015-03-30 10:54:26.464525800 -0500 @@ -0,0 +1,730 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package com.sun.java.accessibility.util; + +import java.lang.*; +import java.beans.*; +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.image.*; +// Do not import Swing classes. This module is intended to work +// with both Swing and AWT. +// import javax.swing.*; +import javax.accessibility.*; + +/** + *

The {@code Translator} class provides a translation to interface + * {@link javax.accessibility.Accessible Accessible} + * for objects that do not implement interface {@code Accessible}. Assistive + * technologies can use the {@link #getAccessible getAccessible} class method of + * {@code Translator} to obtain an object that implements interface {@code Accessible}. + * If the object passed in already implements interface {@code Accessible}, + * {@code getAccessible} merely returns the object. + * + *

An example of how an assistive technology might use the {@code Translator} + * class is as follows: + * + *

+ *    Accessible accessible = Translator.getAccessible(someObj);
+ *    // obtain information from the 'accessible' object.
+ * 
+ * + *

Note: This implementation is missing many things and is not a recommended way + * to implement accessibility features for a toolkit. Instead of relying upon this + * code, a toolkit's components should implement interface {@code Accessible} directly. + */ +@jdk.Exported +public class Translator extends AccessibleContext + implements Accessible, AccessibleComponent { + + /** The source object needing translating. */ + protected Object source; + + /** + * Find a translator for this class. If one doesn't exist for this + * class explicitly, try its superclass and so on. + * + * @param c a Class + * @return the {@code Translator} Class for the Class passed in + */ + protected static Class getTranslatorClass(Class c) { + Class t = null; + if (c == null) { + return null; + } + try { + t = Class.forName("com.sun.java.accessibility.util." + + c.getName() + + "Translator"); + return t; + } catch (Exception e) { + return getTranslatorClass(c.getSuperclass()); + } + } + + /** + * Obtain an object that implements interface {@code Accessible}. If the object + * passed in already implements interface {@code Accessible}, {@code getAccessible} + * merely returns the object. + * + * @param o an Object; if a null is passed in a null is returned + * @return an {@code Object}, possibly the {@code Object} passed in, that + * implements the {@code Accessible} interface for the {@code Object} + * which was passed in + */ + public static Accessible getAccessible(Object o) { + Accessible a = null; + + if (o == null) { + return null; + } + if (o instanceof Accessible) { + a = (Accessible)o; + } else { + Class translatorClass = getTranslatorClass(o.getClass()); + if (translatorClass != null) { + try { + Translator t = (Translator)translatorClass.newInstance(); + t.setSource(o); + a = t; + } catch (Exception e) { + } + } + } + if (a == null) { + a = new Translator(o); + } + return a; + } + + /** + * Create a new {@code Translator}. You must call the {@link #setSource setSource} + * method to set the object to be translated after calling this constructor. + */ + public Translator() { + } + + /** + * Create a new {@code Translator} with the source object o. + * + * @param o the Component that does not implement interface + * {@link javax.accessibility.Accessible Accessible} + */ + public Translator(Object o) { + source = o; + } + + /** + * Get the source {@code Object} of the {@code Translator}. + * + * @return the source {@code Object} of the {@code Translator} + */ + public Object getSource() { + return source; + } + + /** + * Set the source object of the {@code Translator}. + * + * @param o the Component that does not implement interface Accessible + */ + public void setSource(Object o) { + source = o; + } + + /** + * Returns true if this object is the same as the one passed in. + * + * @param o the {@code Object} to check against + * @return true if this is the same object + */ + public boolean equals(Object o) { + return source.equals(o); + } + + +// Accessible methods + + /** + * Returns this object. + */ + public AccessibleContext getAccessibleContext() { + return this; + } + +// AccessibleContext methods + + /** + * Get the accessible name of this object. + * + * @return the localized name of the object; can be null if this object + * does not have a name + */ + public String getAccessibleName() { + if (source instanceof MenuItem) { + return ((MenuItem) source).getLabel(); + } else if (source instanceof Component) { + return ((Component) source).getName(); + } else { + return null; + } + } + + /** + * Set the name of this object. + */ + public void setAccessibleName(String s) { + if (source instanceof MenuItem) { + ((MenuItem) source).setLabel(s); + } else if (source instanceof Component) { + ((Component) source).setName(s); + } + } + + /** + * Get the accessible description of this object. + * + * @return the description of the object; can be null if this object does + * not have a description + */ + public String getAccessibleDescription() { + return null; + } + + /** + * Set the accessible description of this object. + * + * @param s the new localized description of the object + */ + public void setAccessibleDescription(String s) { + } + + /** + * Get the role of this object. + * + * @return an instance of AccessibleRole describing the role of the object + */ + public AccessibleRole getAccessibleRole() { + return AccessibleRole.UNKNOWN; + } + + + /** + * Get the state of this object, given an already populated state. + * This method is intended for use by subclasses so they don't have + * to check for everything. + * + * @return an instance of {@code AccessibleStateSet} + * containing the current state of the object + */ + public AccessibleStateSet getAccessibleStateSet() { + AccessibleStateSet states = new AccessibleStateSet(); + if (source instanceof Component) { + Component c = (Component) source; + for (Container p = c.getParent(); p != null; p = p.getParent()) { + if (p instanceof Window) { + if (((Window)p).getFocusOwner() == c) { + states.add(AccessibleState.FOCUSED); + } + } + } + } + if (isEnabled()) { + states.add(AccessibleState.ENABLED); + } + if (isFocusTraversable()) { + states.add(AccessibleState.FOCUSABLE); + } + if (source instanceof MenuItem) { + states.add(AccessibleState.FOCUSABLE); + } + return states; + } + + /** + * Get the accessible parent of this object. + * + * @return the accessible parent of this object; can be null if this + * object does not have an accessible parent + */ + public Accessible getAccessibleParent() { + if (accessibleParent != null) { + return accessibleParent; + } else if (source instanceof Component) { + return getAccessible(((Component) source).getParent()); + } else { + return null; + } + } + + /** + * Get the index of this object in its accessible parent. + * + * @return -1 of this object does not have an accessible parent; otherwise, + * the index of the child in its accessible parent + */ + public int getAccessibleIndexInParent() { + if (source instanceof Component) { + Container parent = ((Component) source).getParent(); + if (parent != null) { + Component ca[] = parent.getComponents(); + for (int i = 0; i < ca.length; i++) { + if (source.equals(ca[i])) { + return i; + } + } + } + } + return -1; + } + + /** + * Returns the number of accessible children in the object. + * + * @return the number of accessible children in the object + */ + public int getAccessibleChildrenCount() { + if (source instanceof Container) { + Component[] children = ((Container) source).getComponents(); + int count = 0; + for (int i = 0; i < children.length; i++) { + Accessible a = getAccessible(children[i]); + if (a != null) { + count++; + } + } + return count; + } else { + return 0; + } + } + + /** + * Return the nth accessible child of the object. + * + * @param i zero-based index of child + * @return the nth accessible child of the object + */ + public Accessible getAccessibleChild(int i) { + if (source instanceof Container) { + Component[] children = ((Container) source).getComponents(); + int count = 0; + + for (int j = 0; j < children.length; j++) { + Accessible a = getAccessible(children[j]); + if (a != null) { + if (count == i) { + AccessibleContext ac = a.getAccessibleContext(); + if (ac != null) { + ac.setAccessibleParent(this); + } + return a; + } else { + count++; + } + } + } + } + return null; + } + + /** + * Gets the {@code Locale} of the component. If the component does not have a + * locale, the locale of its parent is returned. + * + * @return the {@code Locale} of the object + */ + public Locale getLocale() throws IllegalComponentStateException { + if (source instanceof Component) { + return ((Component) source).getLocale(); + } else { + return null; + } + } + + /** + * Add a {@code PropertyChangeListener} to the listener list. The listener + * is registered for all properties. + */ + public void addPropertyChangeListener(PropertyChangeListener l) { + } + + /** + * Remove the {@code PropertyChangeListener} from the listener list. + */ + public void removePropertyChangeListener(PropertyChangeListener l) { + } + +// AccessibleComponent methods + + /** + * Get the background {@code Color} of this object. + * + * @return if supported, the background {@code Color} of the object; + * otherwise, null + * + */ + public Color getBackground() { + if (source instanceof Component) { // MenuComponent doesn't do background + return ((Component) source).getBackground(); + } else { + return null; + } + } + + /** + * Set the background {@code Color} of this object. + * + * @param c the new {@code Color} for the background + */ + public void setBackground(Color c) { + if (source instanceof Component) { // MenuComponent doesn't do background + ((Component) source).setBackground(c); + } + } + + /** + * Get the foreground {@code Color} of this object. + * + * @return if supported, the foreground {@code Color} of the object; otherwise, null + */ + public Color getForeground() { + if (source instanceof Component) { // MenuComponent doesn't do foreground + return ((Component) source).getForeground(); + } else { + return null; + } + } + + /** + * Set the foreground {@code Color} of this object. + * + * @param c the new {@code Color} for the foreground + */ + public void setForeground(Color c) { + if (source instanceof Component) { // MenuComponent doesn't do foreground + ((Component) source).setForeground(c); + } + } + + /** + * Get the {@code Cursor} of this object. + * + * @return if supported, the Cursor of the object; otherwise, null + */ + public Cursor getCursor() { + if (source instanceof Component) { // MenuComponent doesn't do cursor + return ((Component) source).getCursor(); + } else { + return null; + } + } + + /** + * Set the {@code Cursor} of this object. + * @param c the new {@code Cursor} for the object + */ + public void setCursor(Cursor c) { + if (source instanceof Component) { // MenuComponent doesn't do cursor + ((Component) source).setCursor(c); + } + } + + /** + * Get the {@code Font} of this object. + * + * @return if supported, the {@code Font} for the object; otherwise, null + */ + public Font getFont() { + if (source instanceof Component) { + return ((Component) source).getFont(); + } else if (source instanceof MenuComponent) { + return ((MenuComponent) source).getFont(); + } else { + return null; + } + } + + /** + * Set the {@code Font} of this object. + * + * @param f the new {@code Font} for the object + */ + public void setFont(Font f) { + if (source instanceof Component) { + ((Component) source).setFont(f); + } else if (source instanceof MenuComponent) { + ((MenuComponent) source).setFont(f); + } + } + + /** + * Get the {@code FontMetrics} of this object. + * + * @param f the {@code Font} + * @return if supported, the {@code FontMetrics} the object; otherwise, null + * @see #getFont + */ + public FontMetrics getFontMetrics(Font f) { + if (source instanceof Component) { + return ((Component) source).getFontMetrics(f); + } else { + return null; + } + } + + /** + * Determine if the object is enabled. + * + * @return true if object is enabled; otherwise, false + */ + public boolean isEnabled() { + if (source instanceof Component) { + return ((Component) source).isEnabled(); + } else if (source instanceof MenuItem) { + return ((MenuItem) source).isEnabled(); + } else { + return true; + } + } + + /** + * Set the enabled state of the object. + * + * @param b if true, enables this object; otherwise, disables it + */ + public void setEnabled(boolean b) { + if (source instanceof Component) { + ((Component) source).setEnabled(b); + } else if (source instanceof MenuItem) { + ((MenuItem) source).setEnabled(b); + } + } + + /** + * Determine if the object is visible. + * + * @return true if object is visible; otherwise, false + */ + public boolean isVisible() { + if (source instanceof Component) { + return ((Component) source).isVisible(); + } else { + return false; + } + } + + /** + * Set the visible state of the object. + * + * @param b if true, shows this object; otherwise, hides it + */ + public void setVisible(boolean b) { + if (source instanceof Component) { + ((Component) source).setVisible(b); + } + } + + /** + * Determine if the object is showing. This is determined by checking + * the visibility of the object and ancestors of the object. + * + * @return true if object is showing; otherwise, false + */ + public boolean isShowing() { + if (source instanceof Component) { + return ((Component) source).isShowing(); + } else { + return false; + } + } + + /** + * Checks whether the specified {@code Point} is within this + * object's bounds, where the {@code Point} is relative to the coordinate + * system of the object. + * + * @param p the {@code Point} relative to the coordinate system of the object + * @return true if object contains {@code Point}; otherwise false + */ + public boolean contains(Point p) { + if (source instanceof Component) { + return ((Component) source).contains(p); + } else { + return false; + } + } + + /** + * Returns the location of the object on the screen. + * + * @return location of object on screen; can be null if this object + * is not on the screen + */ + public Point getLocationOnScreen() { + if (source instanceof Component) { + return ((Component) source).getLocationOnScreen(); + } else { + return null; + } + } + + /** + * Returns the location of the object relative to parent. + * + * @return location of object relative to parent; can be null if + * this object or its parent are not on the screen + */ + public Point getLocation() { + if (source instanceof Component) { + return ((Component) source).getLocation(); + } else { + return null; + } + } + + /** + * Sets the location of the object relative to parent. + */ + public void setLocation(Point p) { + if (source instanceof Component) { + ((Component) source).setLocation(p); + } + } + + /** + * Returns the current bounds of this object. + * + * @return current bounds of object; can be null if this object + * is not on the screen + */ + public Rectangle getBounds() { + if (source instanceof Component) { + return ((Component) source).getBounds(); + } else { + return null; + } + } + + /** + * Sets the current bounds of this object. + */ + public void setBounds(Rectangle r) { + if (source instanceof Component) { + ((Component) source).setBounds(r); + } + } + + /** + * Returns the current size of this object. + * + * @return current size of object; can be null if this object is + * not on the screen + */ + public Dimension getSize() { + if (source instanceof Component) { + return ((Component) source).getSize(); + } else { + return null; + } + } + + /** + * Sets the current size of this object. + */ + public void setSize(Dimension d) { + if (source instanceof Component) { + ((Component) source).setSize(d); + } + } + + /** + * Returns the accessible child contained at the local coordinate + * Point, if one exists. + * + * @return the Accessible at the specified location, if it exists + */ + public Accessible getAccessibleAt(Point p) { + if (source instanceof Component) { + Component c = ((Component) source).getComponentAt(p); + if (c != null) { + return (getAccessible(c)); + } + } + return null; + } + + /** + * Returns whether this object can accept focus or not. + * + * @return true if object can accept focus; otherwise false + */ + public boolean isFocusTraversable() { + if (source instanceof Component) { + return ((Component) source).isFocusTraversable(); + } else { + return false; + } + } + + /** + * Requests focus for this object. + */ + public void requestFocus() { + if (source instanceof Component) { + ((Component) source).requestFocus(); + } + } + + /** + * Adds the specified {@code FocusListener} to receive focus events from + * this component. + * + * @param l the focus listener + */ + public synchronized void addFocusListener(FocusListener l) { + if (source instanceof Component) { + ((Component) source).addFocusListener(l); + } + } + + /** + * Removes the specified focus listener so it no longer receives focus + * events from this component. + * + * @param l the focus listener; this method performs no function, nor does it + * throw an exception if the listener specified was not previously added + * to this component; if listener is null, no exception is thrown and no + * action is performed. + */ + public synchronized void removeFocusListener(FocusListener l) { + if (source instanceof Component) { + ((Component) source).removeFocusListener(l); + } + } +} --- /dev/null 2015-03-30 10:54:30.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/java/awt/ButtonTranslator.java 2015-03-30 10:54:29.581537800 -0500 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util.java.awt; + +import java.lang.*; +import java.util.*; +import java.awt.*; +import java.awt.image.*; +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; + +/** + *

The Translator class provides a translation to interface Accessible + * for objects that do not implement interface Accessible. Assistive + * technologies can use the 'getAccessible' class method of Translator to + * obtain an object that implements interface Accessible. If the object + * passed in already implements interface Accessible, getAccessible merely + * returns the object. + * + *

An example of how an assistive technology might use the Translator + * class is as follows: + * + *

+ *    Accessible accessible = Translator.getAccessible(someObj);
+ *    // obtain information from the 'accessible' object.
+ * 
+ * + *

This class extends the Translator class to provide specific support + * for the Button class. Translator.getAccessible() will automatically + * load this class when an assistive technology asks for an accessible + * translator for Button. + * + */ +public class ButtonTranslator extends Translator { + + /** + * Get the name of this object. + * @return the name of the object -- can be null if this object does + * not have a name + */ + public String getAccessibleName() { + return ((Button) source).getLabel(); + } + + /** + * Set the name of this object. + */ + public void setAccessibleName(String s) { + ((Button) source).setLabel(s); + } + + public AccessibleRole getAccessibleRole() { + return AccessibleRole.PUSH_BUTTON; + } +} --- /dev/null 2015-03-30 10:54:33.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/java/awt/CheckboxTranslator.java 2015-03-30 10:54:32.760547200 -0500 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util.java.awt; + +import java.lang.*; +import java.util.*; +import java.awt.*; +import java.awt.image.*; +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; + +/** + *

The Translator class provides a translation to interface Accessible + * for objects that do not implement interface Accessible. Assistive + * technologies can use the 'getAccessible' class method of Translator to + * obtain an object that implements interface Accessible. If the object + * passed in already implements interface Accessible, getAccessible merely + * returns the object. + * + *

An example of how an assistive technology might use the Translator + * class is as follows: + * + *

+ *    Accessible accessible = Translator.getAccessible(someObj);
+ *    // obtain information from the 'accessible' object.
+ * 
+ * + *

This class extends the Translator class to provide specific support + * for the Checkbox class. Translator.getAccessible() will automatically + * load this class when an assistive technology asks for an accessible + * translator for Checkbox. + * + */ +public class CheckboxTranslator extends Translator { + + /** + * Get the state of this object. + * @return an instance of AccessibleState containing the current state of the object + * @see AccessibleState + */ + public AccessibleStateSet getAccessibleStateSet() { + AccessibleStateSet states = super.getAccessibleStateSet(); + if (((Checkbox) source).getState()) { + states.add(AccessibleState.CHECKED); + } + return states; + } + + /** + * Get the name of this object. + * @return the name of the object -- can be null if this object does + * not have a name + */ + public String getAccessibleName() { + return ((Checkbox) source).getLabel(); + } + + /** + * Set the name of this object. + */ + public void setAccessibleName(String s) { + ((Checkbox) source).setLabel(s); + } + + public AccessibleRole getAccessibleRole() { + return AccessibleRole.CHECK_BOX; + } +} --- /dev/null 2015-03-30 10:54:36.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/java/awt/ChoiceTranslator.java 2015-03-30 10:54:35.864556800 -0500 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +package com.sun.java.accessibility.util.java.awt; + +import java.lang.*; +import java.util.*; +import java.awt.*; +import java.awt.image.*; +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; + +/** + *

The Translator class provides a translation to interface Accessible + * for objects that do not implement interface Accessible. Assistive + * technologies can use the 'getAccessible' class method of Translator to + * obtain an object that implements interface Accessible. If the object + * passed in already implements interface Accessible, getAccessible merely + * returns the object. + * + *

An example of how an assistive technology might use the Translator + * class is as follows: + * + *

+ *    Accessible accessible = Translator.getAccessible(someObj);
+ *    // obtain information from the 'accessible' object.
+ * 
+ * + *

This class extends the Translator class to provide specific support + * for the Choice class. Translator.getAccessible() will automatically + * load this class when an assistive technology asks for an accessible + * translator for Choice. + * + */ +public class ChoiceTranslator extends Translator { + + /** + * Get the state of this object. + * @return an instance of AccessibleState containing the current state of the object + * @see AccessibleState + */ + public AccessibleStateSet getAccessibleStateSet() { + AccessibleStateSet states = super.getAccessibleStateSet(); + states.add(AccessibleState.SELECTED); + return states; + } + + public AccessibleRole getAccessibleRole() { + return AccessibleRole.CHOICE; + } +} --- /dev/null 2015-03-30 10:54:39.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/java/awt/LabelTranslator.java 2015-03-30 10:54:38.986566300 -0500 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util.java.awt; + +import java.lang.*; +import java.util.*; +import java.awt.*; +import java.awt.image.*; +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; + +/** + *

The Translator class provides a translation to interface Accessible + * for objects that do not implement interface Accessible. Assistive + * technologies can use the 'getAccessible' class method of Translator to + * obtain an object that implements interface Accessible. If the object + * passed in already implements interface Accessible, getAccessible merely + * returns the object. + * + *

An example of how an assistive technology might use the Translator + * class is as follows: + * + *

+ *    Accessible accessible = Translator.getAccessible(someObj);
+ *    // obtain information from the 'accessible' object.
+ * 
+ * + *

This class extends the Translator class to provide specific support + * for the Label class. Translator.getAccessible() will automatically + * load this class when an assistive technology asks for an accessible + * translator for Label. + * + */ +public class LabelTranslator extends Translator { + + public String getAccessibleName() { + return ((Label) source).getText(); + } + + /** + * Set the name of this object. + */ + public void setAccessibleName(String s) { + ((Label) source).setText(s); + } + + public AccessibleRole getAccessibleRole() { + return AccessibleRole.LABEL; + } +} --- /dev/null 2015-03-30 10:54:43.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/java/awt/ListTranslator.java 2015-03-30 10:54:42.112577200 -0500 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util.java.awt; + +import java.lang.*; +import java.util.*; +import java.awt.*; +import java.awt.image.*; +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; + +/** + *

The Translator class provides a translation to interface Accessible + * for objects that do not implement interface Accessible. Assistive + * technologies can use the 'getAccessible' class method of Translator to + * obtain an object that implements interface Accessible. If the object + * passed in already implements interface Accessible, getAccessible merely + * returns the object. + * + *

An example of how an assistive technology might use the Translator + * class is as follows: + * + *

+ *    Accessible accessible = Translator.getAccessible(someObj);
+ *    // obtain information from the 'accessible' object.
+ * 
+ * + *

This class extends the Translator class to provide specific support + * for the List class. Translator.getAccessible() will automatically + * load this class when an assistive technology asks for an accessible + * translator for List. + * + */ +public class ListTranslator extends Translator { + + /** + * Get the state of this object. + * @return an instance of AccessibleState containing the current state of the object + * @see AccessibleState + */ + public AccessibleStateSet getAccessibleStateSet() { + AccessibleStateSet states = super.getAccessibleStateSet(); + if (((java.awt.List) source).isMultipleMode()) { + states.add(AccessibleState.MULTISELECTABLE); + } + if (((java.awt.List) source).getSelectedItems().length > 0) { + states.add(AccessibleState.SELECTED); + } + return states; + } + + public AccessibleRole getAccessibleRole() { + return AccessibleRole.LIST; + } +} --- /dev/null 2015-03-30 10:54:46.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/java/awt/TextComponentTranslator.java 2015-03-30 10:54:45.280592100 -0500 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util.java.awt; + +import java.lang.*; +import java.util.*; +import java.awt.*; +import java.awt.image.*; +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; + +/** + *

The Translator class provides a translation to interface Accessible + * for objects that do not implement interface Accessible. Assistive + * technologies can use the 'getAccessible' class method of Translator to + * obtain an object that implements interface Accessible. If the object + * passed in already implements interface Accessible, getAccessible merely + * returns the object. + * + *

An example of how an assistive technology might use the Translator + * class is as follows: + * + *

+ *    Accessible accessible = Translator.getAccessible(someObj);
+ *    // obtain information from the 'accessible' object.
+ * 
+ * + *

This class extends the Translator class to provide specific support + * for the TextComponent class. Translator.getAccessible() will automatically + * load this class when an assistive technology asks for an accessible + * translator for TextComponent. + * + */ +public class TextComponentTranslator extends Translator { + + public AccessibleRole getAccessibleRole() { + return AccessibleRole.TEXT; + } +} --- /dev/null 2015-03-30 10:54:49.000000000 -0500 +++ new/jdk/src/windows/classes/com/sun/java/accessibility/util/package-info.java 2015-03-30 10:54:48.395602900 -0500 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Provides a collection of interfaces and classes that compose the Java Accessibility + * Utilities. The classes are used by Assistive Technologies, such as the screen + * readers which are used by those who are blind, and help provide access to GUI + * toolkits that implement the Java Accessibility API. An overview of the important + * classes follows. + * + *

The class {@code AccessibilityEventMonitor} implements a PropertyChange + * listener on every UI object that implements interface {@code Accessible} in the Java + * Virtual Machine. + * + *

The class {@code AWTEventMonitor} implements a suite of listeners that are + * conditionally installed on every AWT component instance in the Java Virtual Machine. + * + *

The class {@code EventQueueMonitor} provides key core functionality for + * Assistive Technologies (and other system-level technologies that need some of + * the same things that Assistive Technology needs). + * + *

The class {@code GUIInitializedMulticaster} is used to maintain a list of + * {@code GUIInitializedListener} classes which are used by the {@code EventQueueMonitor} + * class to notify an interested party when the GUI subsystem has been initialized. + * Note that this class is intended to be used primarily for internal support in + * the {@code EventQueueMonitor} class, and is not intended to be used by classes + * outside the Java Accessibility Utility package. + * + *

The class {@code SwingEventMonitor} extends {@code AWTEventMonitor} by adding + * a suite of listeners conditionally installed on every Swing component instance + * in the Java Virtual Machine. + * + *

The class {@code TopLevelWindowMulticaster} is used to maintain a list of + * {@code TopLevelWindowListener} classes which are used by the {@code EventQueueMonitor} + * class to notify an interested party when a top level window is created or destroyed + * in the Java Virtual Machine Note that this class is intended to be used primarily + * for internal support in the {@code EventQueueMonitor} class, and is not intended + * to be used by classes outside the Java Accessibility Utility package. + * + *

The class {@code Translator} provides a translation to interface {@code Accessible} + * for objects that do not implement interface {@code Accessible}. + * + * @since JDK1.7 + */ +package com.sun.java.accessibility.util; --- /dev/null 2015-03-30 10:54:52.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp 2015-03-30 10:54:51.502611000 -0500 @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to track key AT instance info from the JavaAccessBridge + */ + +#include "AccessBridgeDebug.h" +#include "AccessBridgeATInstance.h" +#include "AccessBridgeMessages.h" + +#include +#include + + +/** + * AccessBridgeATInstance constructor + */ +AccessBridgeATInstance::AccessBridgeATInstance(HWND ourABWindow, HWND winABWindow, + char *memoryFilename, + AccessBridgeATInstance *next) { + ourAccessBridgeWindow = ourABWindow; + winAccessBridgeWindow = winABWindow; + nextATInstance = next; + javaEventMask = 0; + accessibilityEventMask = 0; + strncpy(memoryMappedFileName, memoryFilename, cMemoryMappedNameSize); +} + +/** + * AccessBridgeATInstance descructor + */ +AccessBridgeATInstance::~AccessBridgeATInstance() { + PrintDebugString("\r\nin AccessBridgeATInstance::~AccessBridgeATInstance"); + + // if IPC memory mapped file view is valid, unmap it + if (memoryMappedView != (char *) 0) { + PrintDebugString(" unmapping memoryMappedView; view = %p", memoryMappedView); + UnmapViewOfFile(memoryMappedView); + memoryMappedView = (char *) 0; + } + // if IPC memory mapped file handle map is open, close it + if (memoryMappedFileMapHandle != (HANDLE) 0) { + PrintDebugString(" closing memoryMappedFileMapHandle; handle = %p", memoryMappedFileMapHandle); + CloseHandle(memoryMappedFileMapHandle); + memoryMappedFileMapHandle = (HANDLE) 0; + } +} + +/** + * Sets up the memory-mapped file to do IPC messaging + * 1 files is created: to handle requests for information + * initiated from Windows AT. The package is placed into + * the memory-mapped file (char *memoryMappedView), + * and then a special SendMessage() is sent. When the + * JavaDLL returns from SendMessage() processing, the + * data will be in memoryMappedView. The SendMessage() + * return value tells us if all is right with the world. + * + * The set-up proces involves creating the memory-mapped + * file, and writing a special string to it so that the + * WindowsDLL so it knows about it as well. + */ +LRESULT +AccessBridgeATInstance::initiateIPC() { + DWORD errorCode; + + PrintDebugString("\r\nin AccessBridgeATInstance::initiateIPC()"); + + // open Windows-initiated IPC filemap & map it to a ptr + + memoryMappedFileMapHandle = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, + FALSE, memoryMappedFileName); + if (memoryMappedFileMapHandle == NULL) { + errorCode = GetLastError(); + PrintDebugString(" Failed to CreateFileMapping for %s, error: %X", memoryMappedFileName, errorCode); + return errorCode; + } else { + PrintDebugString(" CreateFileMapping worked - filename: %s", memoryMappedFileName); + } + + memoryMappedView = (char *) MapViewOfFile(memoryMappedFileMapHandle, + FILE_MAP_READ | FILE_MAP_WRITE, + 0, 0, 0); + if (memoryMappedView == NULL) { + errorCode = GetLastError(); + PrintDebugString(" Failed to MapViewOfFile for %s, error: %X", memoryMappedFileName, errorCode); + return errorCode; + } else { + PrintDebugString(" MapViewOfFile worked - view: %p", memoryMappedView); + } + + + // look for the JavaDLL's answer to see if it could read the file + if (strcmp(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_QUERY) != 0) { + PrintDebugString(" JavaVM failed to write to memory mapped file %s", + memoryMappedFileName); + return -1; + } else { + PrintDebugString(" JavaVM successfully wrote to file!"); + } + + + // write some data to the memory mapped file for WindowsDLL to verify + strcpy(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_ANSWER); + + + return 0; +} + + +typedef struct EVENT_STRUCT +{ + char *buffer; + int bufsize; + ABHWND64 winAccessBridgeWindow; + ABHWND64 ourAccessBridgeWindow; +}EVENT_STRUCT; + + +#include +#define THREAD_PROC unsigned int __stdcall +typedef unsigned int (__stdcall *THREAD_ROUTINE)(LPVOID lpThreadParameter); + +static HANDLE BeginThread(THREAD_ROUTINE thread_func,DWORD *id,DWORD param) +{ + HANDLE ret; + ret = (HANDLE) _beginthreadex(NULL,0,thread_func,(void *)param,0,(unsigned int *)id); + if(ret == INVALID_HANDLE_VALUE) + ret = NULL; + return(ret); +} + +DWORD JavaBridgeThreadId = 0; + +static THREAD_PROC JavaBridgeThread(LPVOID param1) +{ + MSG msg; + DWORD rc = 0; + while (GetMessage(&msg, // message structure + NULL, // handle of window receiving the message + 0, // lowest message to examine + 0)) // highest message to examine + { + if(msg.message == WM_USER) + { + EVENT_STRUCT *event_struct = (EVENT_STRUCT *)msg.wParam; + COPYDATASTRUCT toCopy; + toCopy.dwData = 0; // 32-bits we could use for something... + toCopy.cbData = event_struct->bufsize; + toCopy.lpData = event_struct->buffer; + + LRESULT ret = SendMessage((HWND)ABLongToHandle(event_struct->winAccessBridgeWindow), WM_COPYDATA, + (WPARAM)event_struct->ourAccessBridgeWindow, (LPARAM) &toCopy); + delete event_struct->buffer; + delete event_struct; + } + if(msg.message == (WM_USER+1)) + PostQuitMessage(0); + } + JavaBridgeThreadId = 0; + return(0); +} + +/* + * Handles one event + */ +static void do_event(char *buffer, int bufsize,HWND ourAccessBridgeWindow,HWND winAccessBridgeWindow) +{ + EVENT_STRUCT *event_struct = new EVENT_STRUCT; + event_struct->bufsize = bufsize; + event_struct->buffer = new char[bufsize]; + memcpy(event_struct->buffer,buffer,bufsize); + event_struct->ourAccessBridgeWindow = ABHandleToLong(ourAccessBridgeWindow); + event_struct->winAccessBridgeWindow = ABHandleToLong(winAccessBridgeWindow); + if(!JavaBridgeThreadId) + { + HANDLE JavaBridgeThreadHandle = BeginThread(JavaBridgeThread,&JavaBridgeThreadId,(DWORD)event_struct); + CloseHandle(JavaBridgeThreadHandle); + } + PostThreadMessage(JavaBridgeThreadId,WM_USER,(WPARAM)event_struct,0); +} + + +/** + * sendJavaEventPackage - uses SendMessage(WM_COPYDATA) to do + * IPC messaging with the Java AccessBridge DLL + * to propogate events to those ATs that want 'em + * + */ +LRESULT +AccessBridgeATInstance::sendJavaEventPackage(char *buffer, int bufsize, long eventID) { + + PrintDebugString("AccessBridgeATInstance::sendJavaEventPackage() eventID = %X", eventID); + PrintDebugString("AccessBridgeATInstance::sendJavaEventPackage() (using PostMessage) eventID = %X", eventID); + + if (eventID & javaEventMask) { + do_event(buffer,bufsize,ourAccessBridgeWindow,winAccessBridgeWindow); + return(0); + } else { + return -1; + } +} + + +/** + * uses SendMessage(WM_COPYDATA) to do + * IPC messaging with the Java AccessBridge DLL + * to propogate events to those ATs that want 'em + * + */ +LRESULT +AccessBridgeATInstance::sendAccessibilityEventPackage(char *buffer, int bufsize, long eventID) { + + PrintDebugString("AccessBridgeATInstance::sendAccessibilityEventPackage() eventID = %X", eventID); + + if (eventID & accessibilityEventMask) { + do_event(buffer,bufsize,ourAccessBridgeWindow,winAccessBridgeWindow); + return(0); + } else { + return -1; + } +} + + +/** + * findABATInstanceFromATHWND - walk through linked list from + * where we are. Return the + * AccessBridgeATInstance + * of the ABATInstance that + * matches the passed in vmID; + * no match: return 0 + */ +AccessBridgeATInstance * +AccessBridgeATInstance::findABATInstanceFromATHWND(HWND window) { + // no need to recurse really + if (winAccessBridgeWindow == window) { + return this; + } else { + AccessBridgeATInstance *current = nextATInstance; + while (current != (AccessBridgeATInstance *) 0) { + if (current->winAccessBridgeWindow == window) { + return current; + } + current = current->nextATInstance; + } + } + return (AccessBridgeATInstance *) 0; +} --- /dev/null 2015-03-30 10:54:55.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeATInstance.h 2015-03-30 10:54:54.601618100 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to track key AT instance info from the JavaAccessBridge + */ + +#include +#include "AccessBridgePackages.h" + +#ifndef __AccessBridgeATInstance_H__ +#define __AccessBridgeATInstance_H__ + + +/** + * The AccessBridgeATInstance class. + */ +class AccessBridgeATInstance { + friend class JavaAccessBridge; + + AccessBridgeATInstance *nextATInstance; + HWND ourAccessBridgeWindow; + HWND winAccessBridgeWindow; + long javaEventMask; + long accessibilityEventMask; + + // IPC variables + HANDLE memoryMappedFileMapHandle; // handle to file map + char *memoryMappedView; // ptr to shared memory + char memoryMappedFileName[cMemoryMappedNameSize]; + +public: + AccessBridgeATInstance(HWND ourABWindow, HWND winABWindow, + char *memoryFilename, + AccessBridgeATInstance *next); + ~AccessBridgeATInstance(); + LRESULT initiateIPC(); + LRESULT sendJavaEventPackage(char *buffer, int bufsize, long eventID); + LRESULT sendAccessibilityEventPackage(char *buffer, int bufsize, long eventID); + AccessBridgeATInstance *findABATInstanceFromATHWND(HWND window); +}; + +#endif --- /dev/null 2015-03-30 10:54:58.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeCallbacks.h 2015-03-30 10:54:57.711630200 -0500 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * AccessBridgeCallbacks.h 1.17 05/03/21 + */ + +/* + * Header file defining callback typedefs for Windows routines + * which are called from Java (responding to events, etc.). + */ + +#ifndef __AccessBridgeCallbacks_H__ +#define __AccessBridgeCallbacks_H__ + +#include +#include "AccessBridgePackages.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*AccessBridge_PropertyChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *property, wchar_t *oldValue, wchar_t *newValue); + +typedef void (*AccessBridge_JavaShutdownFP) (long vmID); +typedef void (*AccessBridge_JavaShutdownFP) (long vmID); + +typedef void (*AccessBridge_FocusGainedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_FocusLostFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_CaretUpdateFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_MouseClickedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseEnteredFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseExitedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MousePressedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseReleasedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_MenuCanceledFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MenuDeselectedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MenuSelectedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuCanceledFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuWillBecomeInvisibleFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuWillBecomeVisibleFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_PropertyNameChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldName, wchar_t *newName); +typedef void (*AccessBridge_PropertyDescriptionChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldDescription, wchar_t *newDescription); +typedef void (*AccessBridge_PropertyStateChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldState, wchar_t *newState); +typedef void (*AccessBridge_PropertyValueChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldValue, wchar_t *newValue); +typedef void (*AccessBridge_PropertySelectionChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyTextChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyCaretChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + int oldPosition, int newPosition); +typedef void (*AccessBridge_PropertyVisibleDataChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyChildChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + JOBJECT64 oldChild, JOBJECT64 newChild); +typedef void (*AccessBridge_PropertyActiveDescendentChangeFP) (long vmID, JOBJECT64 event, + JOBJECT64 source, + JOBJECT64 oldActiveDescendent, + JOBJECT64 newActiveDescendent); + +typedef void (*AccessBridge_PropertyTableModelChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 src, + wchar_t *oldValue, wchar_t *newValue); + +#ifdef __cplusplus +} +#endif + +#endif --- /dev/null 2015-03-30 10:55:01.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeCalls.c 2015-03-30 10:55:00.820639500 -0500 @@ -0,0 +1,1131 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @(#)AccessBridgeCalls.c 1.25 05/08/22 + */ + +/* + * Wrapper functions around calls to the AccessBridge DLL + */ + + +#include +#include + + +//#define ACCESSBRIDGE_32 +//#define ACCESSBRIDGE_64 + +#include "AccessBridgeCalls.h" +#include "AccessBridgeDebug.h" + +#ifdef __cplusplus +extern "C" { +#endif + + HINSTANCE theAccessBridgeInstance; + AccessBridgeFPs theAccessBridge; + + BOOL theAccessBridgeInitializedFlag = FALSE; + +#define LOAD_FP(result, type, name) \ + PrintDebugString("LOAD_FP loading: %s ...", name); \ + if ((theAccessBridge.result = \ + (type) GetProcAddress(theAccessBridgeInstance, name)) == (type) 0) { \ + PrintDebugString("LOAD_FP failed: %s", name); \ + return FALSE; \ + } + + BOOL initializeAccessBridge() { + +#ifdef ACCESSBRIDGE_ARCH_32 // For 32bit AT new bridge + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE-32"); +#else +#ifdef ACCESSBRIDGE_ARCH_64 // For 64bit AT new bridge + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE-64"); +#else // legacy + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE"); +#endif +#endif + if (theAccessBridgeInstance != 0) { + LOAD_FP(Windows_run, Windows_runFP, "Windows_run"); + + LOAD_FP(SetJavaShutdown, SetJavaShutdownFP, "setJavaShutdownFP"); + LOAD_FP(SetFocusGained, SetFocusGainedFP, "setFocusGainedFP"); + LOAD_FP(SetFocusLost, SetFocusLostFP, "setFocusLostFP"); + + LOAD_FP(SetCaretUpdate, SetCaretUpdateFP, "setCaretUpdateFP"); + + LOAD_FP(SetMouseClicked, SetMouseClickedFP, "setMouseClickedFP"); + LOAD_FP(SetMouseEntered, SetMouseEnteredFP, "setMouseEnteredFP"); + LOAD_FP(SetMouseExited, SetMouseExitedFP, "setMouseExitedFP"); + LOAD_FP(SetMousePressed, SetMousePressedFP, "setMousePressedFP"); + LOAD_FP(SetMouseReleased, SetMouseReleasedFP, "setMouseReleasedFP"); + + LOAD_FP(SetMenuCanceled, SetMenuCanceledFP, "setMenuCanceledFP"); + LOAD_FP(SetMenuDeselected, SetMenuDeselectedFP, "setMenuDeselectedFP"); + LOAD_FP(SetMenuSelected, SetMenuSelectedFP, "setMenuSelectedFP"); + LOAD_FP(SetPopupMenuCanceled, SetPopupMenuCanceledFP, "setPopupMenuCanceledFP"); + LOAD_FP(SetPopupMenuWillBecomeInvisible, SetPopupMenuWillBecomeInvisibleFP, "setPopupMenuWillBecomeInvisibleFP"); + LOAD_FP(SetPopupMenuWillBecomeVisible, SetPopupMenuWillBecomeVisibleFP, "setPopupMenuWillBecomeVisibleFP"); + + LOAD_FP(SetPropertyNameChange, SetPropertyNameChangeFP, "setPropertyNameChangeFP"); + LOAD_FP(SetPropertyDescriptionChange, SetPropertyDescriptionChangeFP, "setPropertyDescriptionChangeFP"); + LOAD_FP(SetPropertyStateChange, SetPropertyStateChangeFP, "setPropertyStateChangeFP"); + LOAD_FP(SetPropertyValueChange, SetPropertyValueChangeFP, "setPropertyValueChangeFP"); + LOAD_FP(SetPropertySelectionChange, SetPropertySelectionChangeFP, "setPropertySelectionChangeFP"); + LOAD_FP(SetPropertyTextChange, SetPropertyTextChangeFP, "setPropertyTextChangeFP"); + LOAD_FP(SetPropertyCaretChange, SetPropertyCaretChangeFP, "setPropertyCaretChangeFP"); + LOAD_FP(SetPropertyVisibleDataChange, SetPropertyVisibleDataChangeFP, "setPropertyVisibleDataChangeFP"); + LOAD_FP(SetPropertyChildChange, SetPropertyChildChangeFP, "setPropertyChildChangeFP"); + LOAD_FP(SetPropertyActiveDescendentChange, SetPropertyActiveDescendentChangeFP, "setPropertyActiveDescendentChangeFP"); + + LOAD_FP(SetPropertyTableModelChange, SetPropertyTableModelChangeFP, "setPropertyTableModelChangeFP"); + + LOAD_FP(ReleaseJavaObject, ReleaseJavaObjectFP, "releaseJavaObject"); + LOAD_FP(GetVersionInfo, GetVersionInfoFP, "getVersionInfo"); + + LOAD_FP(IsJavaWindow, IsJavaWindowFP, "isJavaWindow"); + LOAD_FP(IsSameObject, IsSameObjectFP, "isSameObject"); + LOAD_FP(GetAccessibleContextFromHWND, GetAccessibleContextFromHWNDFP, "getAccessibleContextFromHWND"); + LOAD_FP(getHWNDFromAccessibleContext, getHWNDFromAccessibleContextFP, "getHWNDFromAccessibleContext"); + + LOAD_FP(GetAccessibleContextAt, GetAccessibleContextAtFP, "getAccessibleContextAt"); + LOAD_FP(GetAccessibleContextWithFocus, GetAccessibleContextWithFocusFP, "getAccessibleContextWithFocus"); + LOAD_FP(GetAccessibleContextInfo, GetAccessibleContextInfoFP, "getAccessibleContextInfo"); + LOAD_FP(GetAccessibleChildFromContext, GetAccessibleChildFromContextFP, "getAccessibleChildFromContext"); + LOAD_FP(GetAccessibleParentFromContext, GetAccessibleParentFromContextFP, "getAccessibleParentFromContext"); + + /* begin AccessibleTable */ + LOAD_FP(getAccessibleTableInfo, getAccessibleTableInfoFP, "getAccessibleTableInfo"); + LOAD_FP(getAccessibleTableCellInfo, getAccessibleTableCellInfoFP, "getAccessibleTableCellInfo"); + + LOAD_FP(getAccessibleTableRowHeader, getAccessibleTableRowHeaderFP, "getAccessibleTableRowHeader"); + LOAD_FP(getAccessibleTableColumnHeader, getAccessibleTableColumnHeaderFP, "getAccessibleTableColumnHeader"); + + LOAD_FP(getAccessibleTableRowDescription, getAccessibleTableRowDescriptionFP, "getAccessibleTableRowDescription"); + LOAD_FP(getAccessibleTableColumnDescription, getAccessibleTableColumnDescriptionFP, "getAccessibleTableColumnDescription"); + + LOAD_FP(getAccessibleTableRowSelectionCount, getAccessibleTableRowSelectionCountFP, + "getAccessibleTableRowSelectionCount"); + LOAD_FP(isAccessibleTableRowSelected, isAccessibleTableRowSelectedFP, + "isAccessibleTableRowSelected"); + LOAD_FP(getAccessibleTableRowSelections, getAccessibleTableRowSelectionsFP, + "getAccessibleTableRowSelections"); + + LOAD_FP(getAccessibleTableColumnSelectionCount, getAccessibleTableColumnSelectionCountFP, + "getAccessibleTableColumnSelectionCount"); + LOAD_FP(isAccessibleTableColumnSelected, isAccessibleTableColumnSelectedFP, + "isAccessibleTableColumnSelected"); + LOAD_FP(getAccessibleTableColumnSelections, getAccessibleTableColumnSelectionsFP, + "getAccessibleTableColumnSelections"); + + LOAD_FP(getAccessibleTableRow, getAccessibleTableRowFP, + "getAccessibleTableRow"); + LOAD_FP(getAccessibleTableColumn, getAccessibleTableColumnFP, + "getAccessibleTableColumn"); + LOAD_FP(getAccessibleTableIndex, getAccessibleTableIndexFP, + "getAccessibleTableIndex"); + + /* end AccessibleTable */ + + /* AccessibleRelationSet */ + LOAD_FP(getAccessibleRelationSet, getAccessibleRelationSetFP, "getAccessibleRelationSet"); + + /* AccessibleHypertext */ + LOAD_FP(getAccessibleHypertext, getAccessibleHypertextFP, "getAccessibleHypertext"); + LOAD_FP(activateAccessibleHyperlink, activateAccessibleHyperlinkFP, "activateAccessibleHyperlink"); + LOAD_FP(getAccessibleHyperlinkCount, getAccessibleHyperlinkCountFP, "getAccessibleHyperlinkCount"); + LOAD_FP(getAccessibleHypertextExt, getAccessibleHypertextExtFP, "getAccessibleHypertextExt"); + LOAD_FP(getAccessibleHypertextLinkIndex, getAccessibleHypertextLinkIndexFP, "getAccessibleHypertextLinkIndex"); + LOAD_FP(getAccessibleHyperlink, getAccessibleHyperlinkFP, "getAccessibleHyperlink"); + + /* Accessible KeyBinding, Icon and Action */ + LOAD_FP(getAccessibleKeyBindings, getAccessibleKeyBindingsFP, "getAccessibleKeyBindings"); + LOAD_FP(getAccessibleIcons, getAccessibleIconsFP, "getAccessibleIcons"); + LOAD_FP(getAccessibleActions, getAccessibleActionsFP, "getAccessibleActions"); + LOAD_FP(doAccessibleActions, doAccessibleActionsFP, "doAccessibleActions"); + + /* AccessibleText */ + LOAD_FP(GetAccessibleTextInfo, GetAccessibleTextInfoFP, "getAccessibleTextInfo"); + LOAD_FP(GetAccessibleTextItems, GetAccessibleTextItemsFP, "getAccessibleTextItems"); + LOAD_FP(GetAccessibleTextSelectionInfo, GetAccessibleTextSelectionInfoFP, "getAccessibleTextSelectionInfo"); + LOAD_FP(GetAccessibleTextAttributes, GetAccessibleTextAttributesFP, "getAccessibleTextAttributes"); + LOAD_FP(GetAccessibleTextRect, GetAccessibleTextRectFP, "getAccessibleTextRect"); + LOAD_FP(GetAccessibleTextLineBounds, GetAccessibleTextLineBoundsFP, "getAccessibleTextLineBounds"); + LOAD_FP(GetAccessibleTextRange, GetAccessibleTextRangeFP, "getAccessibleTextRange"); + + LOAD_FP(GetCurrentAccessibleValueFromContext, GetCurrentAccessibleValueFromContextFP, "getCurrentAccessibleValueFromContext"); + LOAD_FP(GetMaximumAccessibleValueFromContext, GetMaximumAccessibleValueFromContextFP, "getMaximumAccessibleValueFromContext"); + LOAD_FP(GetMinimumAccessibleValueFromContext, GetMinimumAccessibleValueFromContextFP, "getMinimumAccessibleValueFromContext"); + + LOAD_FP(AddAccessibleSelectionFromContext, AddAccessibleSelectionFromContextFP, "addAccessibleSelectionFromContext"); + LOAD_FP(ClearAccessibleSelectionFromContext, ClearAccessibleSelectionFromContextFP, "clearAccessibleSelectionFromContext"); + LOAD_FP(GetAccessibleSelectionFromContext, GetAccessibleSelectionFromContextFP, "getAccessibleSelectionFromContext"); + LOAD_FP(GetAccessibleSelectionCountFromContext, GetAccessibleSelectionCountFromContextFP, "getAccessibleSelectionCountFromContext"); + LOAD_FP(IsAccessibleChildSelectedFromContext, IsAccessibleChildSelectedFromContextFP, "isAccessibleChildSelectedFromContext"); + LOAD_FP(RemoveAccessibleSelectionFromContext, RemoveAccessibleSelectionFromContextFP, "removeAccessibleSelectionFromContext"); + LOAD_FP(SelectAllAccessibleSelectionFromContext, SelectAllAccessibleSelectionFromContextFP, "selectAllAccessibleSelectionFromContext"); + + LOAD_FP(setTextContents, setTextContentsFP, "setTextContents"); + LOAD_FP(getParentWithRole, getParentWithRoleFP, "getParentWithRole"); + LOAD_FP(getTopLevelObject, getTopLevelObjectFP, "getTopLevelObject"); + LOAD_FP(getParentWithRoleElseRoot, getParentWithRoleElseRootFP, "getParentWithRoleElseRoot"); + LOAD_FP(getObjectDepth, getObjectDepthFP, "getObjectDepth"); + LOAD_FP(getActiveDescendent, getActiveDescendentFP, "getActiveDescendent"); + + // additional methods for Teton + LOAD_FP(getVirtualAccessibleName, getVirtualAccessibleNameFP, "getVirtualAccessibleName"); + LOAD_FP(requestFocus, requestFocusFP, "requestFocus"); + LOAD_FP(selectTextRange, selectTextRangeFP, "selectTextRange"); + LOAD_FP(getTextAttributesInRange, getTextAttributesInRangeFP, "getTextAttributesInRange"); + LOAD_FP(getVisibleChildrenCount, getVisibleChildrenCountFP, "getVisibleChildrenCount"); + LOAD_FP(getVisibleChildren, getVisibleChildrenFP, "getVisibleChildren"); + LOAD_FP(setCaretPosition, setCaretPositionFP, "setCaretPosition"); + LOAD_FP(getCaretLocation, getCaretLocationFP, "getCaretLocation"); + + LOAD_FP(getEventsWaiting, getEventsWaitingFP, "getEventsWaiting"); + + theAccessBridge.Windows_run(); + + theAccessBridgeInitializedFlag = TRUE; + PrintDebugString("theAccessBridgeInitializedFlag = TRUE"); + return TRUE; + } else { + return FALSE; + } + } + + + BOOL shutdownAccessBridge() { + BOOL result; + DWORD error; + theAccessBridgeInitializedFlag = FALSE; + if (theAccessBridgeInstance != (HANDLE) 0) { + result = FreeLibrary(theAccessBridgeInstance); + if (result != TRUE) { + error = GetLastError(); + } + return TRUE; + } + return FALSE; + } + + + void SetJavaShutdown(AccessBridge_JavaShutdownFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetJavaShutdown(fp); + } + } + + void SetFocusGained(AccessBridge_FocusGainedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetFocusGained(fp); + } + } + + void SetFocusLost(AccessBridge_FocusLostFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetFocusLost(fp); + } + } + + + void SetCaretUpdate(AccessBridge_CaretUpdateFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetCaretUpdate(fp); + } + } + + + void SetMouseClicked(AccessBridge_MouseClickedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseClicked(fp); + } + } + + void SetMouseEntered(AccessBridge_MouseEnteredFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseEntered(fp); + } + } + + void SetMouseExited(AccessBridge_MouseExitedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseExited(fp); + } + } + + void SetMousePressed(AccessBridge_MousePressedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMousePressed(fp); + } + } + + void SetMouseReleased(AccessBridge_MouseReleasedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseReleased(fp); + } + } + + + void SetMenuCanceled(AccessBridge_MenuCanceledFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuCanceled(fp); + } + } + + void SetMenuDeselected(AccessBridge_MenuDeselectedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuDeselected(fp); + } + } + + void SetMenuSelected(AccessBridge_MenuSelectedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuSelected(fp); + } + } + + void SetPopupMenuCanceled(AccessBridge_PopupMenuCanceledFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuCanceled(fp); + } + } + + void SetPopupMenuWillBecomeInvisible(AccessBridge_PopupMenuWillBecomeInvisibleFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuWillBecomeInvisible(fp); + } + } + + void SetPopupMenuWillBecomeVisible(AccessBridge_PopupMenuWillBecomeVisibleFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuWillBecomeVisible(fp); + } + } + + + void SetPropertyNameChange(AccessBridge_PropertyNameChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyNameChange(fp); + } + } + + void SetPropertyDescriptionChange(AccessBridge_PropertyDescriptionChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyDescriptionChange(fp); + } + } + + void SetPropertyStateChange(AccessBridge_PropertyStateChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyStateChange(fp); + } + } + + void SetPropertyValueChange(AccessBridge_PropertyValueChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyValueChange(fp); + } + } + + void SetPropertySelectionChange(AccessBridge_PropertySelectionChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertySelectionChange(fp); + } + } + + void SetPropertyTextChange(AccessBridge_PropertyTextChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyTextChange(fp); + } + } + + void SetPropertyCaretChange(AccessBridge_PropertyCaretChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyCaretChange(fp); + } + } + + void SetPropertyVisibleDataChange(AccessBridge_PropertyVisibleDataChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyVisibleDataChange(fp); + } + } + + void SetPropertyChildChange(AccessBridge_PropertyChildChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyChildChange(fp); + } + } + + void SetPropertyActiveDescendentChange(AccessBridge_PropertyActiveDescendentChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyActiveDescendentChange(fp); + } + } + + void SetPropertyTableModelChange(AccessBridge_PropertyTableModelChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyTableModelChange(fp); + } + } + + /** + * General routines + */ + void ReleaseJavaObject(long vmID, Java_Object object) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.ReleaseJavaObject(vmID, object); + } + } + + BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetVersionInfo(vmID, info); + } + return FALSE; + } + + + /** + * Window routines + */ + BOOL IsJavaWindow(HWND window) { + if (theAccessBridgeInitializedFlag == TRUE) { + BOOL ret ; + ret = theAccessBridge.IsJavaWindow(window); + return ret ; + + } + return FALSE; + } + + + /** + * Returns the virtual machine ID and AccessibleContext for a top-level window + */ + BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextFromHWND(target, vmID, ac); + } + return FALSE; + } + + /** + * Returns the HWND from the AccessibleContext of a top-level window. Returns 0 + * on error or if the AccessibleContext does not refer to a top-level window. + */ + HWND getHWNDFromAccessibleContext(long vmID, JOBJECT64 accesibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getHWNDFromAccessibleContext(vmID, accesibleContext); + } + return (HWND)0; + } + + /** + * returns whether two objects are the same + */ + BOOL IsSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.IsSameObject(vmID, obj1, obj2); + } + return FALSE; + } + + /** + * Sets editable text contents. The AccessibleContext must implement AccessibleEditableText and + * be editable. The maximum text length is MAX_STRING_SIZE - 1. + * Returns whether successful + */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.setTextContents(vmID, accessibleContext, text); + } + return FALSE; + } + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h + * If there is no ancestor object that has the specified role, + * returns (AccessibleContext)0. + */ + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getParentWithRole(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h. If an object with the specified + * role does not exist, returns the top level object for the Java Window. + * Returns (AccessibleContext)0 on error. + */ + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getParentWithRoleElseRoot(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getTopLevelObject(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getObjectDepth(vmID, accessibleContext); + } + return -1; + } + + /** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * This method assumes the ActiveDescendent is the component that is currently + * selected in a container object. + * Returns (AccessibleContext)0 on error or if there is no selection. + */ + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getActiveDescendent(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + + /** + * Accessible Context routines + */ + BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextAt(vmID, acParent, x, y, ac); + } + return FALSE; + } + + BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextWithFocus(window, vmID, ac); + } + return FALSE; + } + + BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextInfo(vmID, ac, info); + } + return FALSE; + } + + AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleChildFromContext(vmID, ac, index); + } + return (AccessibleContext) 0; + } + + AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleParentFromContext(vmID, ac); + } + return (AccessibleContext) 0; + } + + /* begin AccessibleTable routines */ + + /* + * get information about an AccessibleTable + */ + BOOL getAccessibleTableInfo(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableInfo(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable cell + */ + BOOL getAccessibleTableCellInfo(long vmID, AccessibleTable accessibleTable, + jint row, jint column, AccessibleTableCellInfo *tableCellInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableCellInfo(vmID, accessibleTable, row, column, tableCellInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable row header + */ + BOOL getAccessibleTableRowHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowHeader(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable column header + */ + BOOL getAccessibleTableColumnHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnHeader(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * return a description of an AccessibleTable row header + */ + AccessibleContext getAccessibleTableRowDescription(long vmID, AccessibleContext acParent, jint row) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowDescription(vmID, acParent, row); + } + return (AccessibleContext)0; + } + + /* + * return a description of an AccessibleTable column header + */ + AccessibleContext getAccessibleTableColumnDescription(long vmID, AccessibleContext acParent, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnDescription(vmID, acParent, column); + } + return (AccessibleContext)0; + } + + /* + * return the number of rows selected in an AccessibleTable + */ + jint getAccessibleTableRowSelectionCount(long vmID, AccessibleTable table) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowSelectionCount(vmID, table); + } + return -1; + } + + /* + * return whether a row is selected in an AccessibleTable + */ + BOOL isAccessibleTableRowSelected(long vmID, AccessibleTable table, jint row) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.isAccessibleTableRowSelected(vmID, table, row); + } + return FALSE; + } + + /* + * get an array of selected rows in an AccessibleTable + */ + BOOL getAccessibleTableRowSelections(long vmID, AccessibleTable table, jint count, jint *selections) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowSelections(vmID, table, count, selections); + } + return FALSE; + } + + /* + * return the number of columns selected in an AccessibleTable + */ + jint getAccessibleTableColumnSelectionCount(long vmID, AccessibleTable table) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnSelectionCount(vmID, table); + } + return -1; + } + + /* + * return whether a column is selected in an AccessibleTable + */ + BOOL isAccessibleTableColumnSelected(long vmID, AccessibleTable table, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.isAccessibleTableColumnSelected(vmID, table, column); + } + return FALSE; + } + + /* + * get an array of columns selected in an AccessibleTable + */ + BOOL getAccessibleTableColumnSelections(long vmID, AccessibleTable table, jint count, jint *selections) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnSelections(vmID, table, count, selections); + } + return FALSE; + } + + /* + * return the row number for a cell at a given index + */ + jint + getAccessibleTableRow(long vmID, AccessibleTable table, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRow(vmID, table, index); + } + return -1; + } + + /* + * return the column number for a cell at a given index + */ + jint + getAccessibleTableColumn(long vmID, AccessibleTable table, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumn(vmID, table, index); + } + return -1; + } + + /* + * return the index of a cell at a given row and column + */ + jint + getAccessibleTableIndex(long vmID, AccessibleTable table, jint row, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableIndex(vmID, table, row, column); + } + return -1; + } + + /* end AccessibleTable routines */ + + + /** + * Accessible Text routines + */ + BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextInfo(vmID, at, textInfo, x, y); + } + return FALSE; + } + + BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextItems(vmID, at, textItems, index); + } + return FALSE; + } + + BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextSelectionInfo(vmID, at, textSelection); + } + return FALSE; + } + + BOOL GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextAttributes(vmID, at, index, attributes); + } + return FALSE; + } + + BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextRect(vmID, at, rectInfo, index); + } + return FALSE; + } + + BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextLineBounds(vmID, at, index, startIndex, endIndex); + } + return FALSE; + } + + BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextRange(vmID, at, start, end, text, len); + } + return FALSE; + } + + /** + * AccessibleRelationSet routines + */ + BOOL getAccessibleRelationSet(long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleRelationSet(vmID, accessibleContext, relationSetInfo); + } + return FALSE; + } + + /** + * AccessibleHypertext routines + */ + + // Gets AccessibleHypertext for an AccessibleContext + BOOL getAccessibleHypertext(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertext(vmID, accessibleContext, hypertextInfo); + } + return FALSE; + } + + // Activates an AccessibleHyperlink for an AccessibleContext + BOOL activateAccessibleHyperlink(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.activateAccessibleHyperlink(vmID, accessibleContext, accessibleHyperlink); + } + return FALSE; + } + + /* + * Returns the number of hyperlinks in a component + * Maps to AccessibleHypertext.getLinkCount. + * Returns -1 on error. + */ + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHyperlinkCount(vmID, accessibleContext); + } + return -1; + } + + /* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * returns FALSE on error. + */ + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertextExt(vmID, + accessibleContext, + nStartIndex, + hypertextInfo); + } + return FALSE; + } + + /* + * Returns the index into an array of hyperlinks that is associated with + * a character index in document; + * Maps to AccessibleHypertext.getLinkIndex. + * Returns -1 on error. + */ + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertextLinkIndex(vmID, + hypertext, + nIndex); + } + return -1; + } + + /* + * Returns the nth hyperlink in a document. + * Maps to AccessibleHypertext.getLink. + * Returns -1 on error + */ + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHyperlink(vmID, + hypertext, + nIndex, + hyperlinkInfo); + } + return FALSE; + } + + + /* Accessible KeyBindings, Icons and Actions */ + BOOL getAccessibleKeyBindings(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleKeyBindings(vmID, accessibleContext, keyBindings); + } + return FALSE; + } + + BOOL getAccessibleIcons(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleIcons(vmID, accessibleContext, icons); + } + return FALSE; + } + + BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleActions(vmID, accessibleContext, actions); + } + return FALSE; + } + + BOOL doAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.doAccessibleActions(vmID, accessibleContext, actionsToDo, failure); + } + return FALSE; + } + + /** + * Accessible Value routines + */ + BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetCurrentAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetMaximumAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetMinimumAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + + /** + * Accessible Selection routines + */ + void addAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.AddAccessibleSelectionFromContext(vmID, as, i); + } + } + + void clearAccessibleSelectionFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.ClearAccessibleSelectionFromContext(vmID, as); + } + } + + JOBJECT64 GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleSelectionFromContext(vmID, as, i); + } + return (JOBJECT64) 0; + } + + int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleSelectionCountFromContext(vmID, as); + } + return -1; + } + + BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.IsAccessibleChildSelectedFromContext(vmID, as, i); + } + return FALSE; + } + + void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.RemoveAccessibleSelectionFromContext(vmID, as, i); + } + } + + void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SelectAllAccessibleSelectionFromContext(vmID, as); + } + } + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVirtualAccessibleName(vmID, accessibleContext, name, len); + } + return FALSE; + } + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(const long vmID, const AccessibleContext accessibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.requestFocus(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.selectTextRange(vmID, accessibleContext, startIndex, endIndex); + } + return FALSE; + } + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getTextAttributesInRange(vmID, accessibleContext, startIndex, + endIndex, attributes, len); + } + return FALSE; + } + + /** + * Returns the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVisibleChildrenCount(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, VisibleChildrenInfo *visibleChildrenInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVisibleChildren(vmID, accessibleContext, startIndex, + visibleChildrenInfo); + } + return FALSE; + } + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const long vmID, const AccessibleContext accessibleContext, + const int position) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.setCaretPosition(vmID, accessibleContext, position); + } + return FALSE; + } + + /** + * Gets the text caret location + */ + BOOL getCaretLocation(long vmID, AccessibleContext ac, AccessibleTextRectInfo *rectInfo, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getCaretLocation(vmID, ac, rectInfo, index); + } + return FALSE; + } + + /** + * Gets the number of events waiting to fire + */ + int getEventsWaiting() { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getEventsWaiting(); + } + return FALSE; + } + +#ifdef __cplusplus +} +#endif --- /dev/null 2015-03-30 10:55:04.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeCalls.h 2015-03-30 10:55:03.972651300 -0500 @@ -0,0 +1,706 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Wrapper functions around calls to the AccessBridge DLL + */ + +#include +#include +#include "AccessBridgeCallbacks.h" +#include "AccessBridgePackages.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define null NULL + + typedef JOBJECT64 AccessibleContext; + typedef JOBJECT64 AccessibleText; + typedef JOBJECT64 AccessibleValue; + typedef JOBJECT64 AccessibleSelection; + typedef JOBJECT64 Java_Object; + typedef JOBJECT64 PropertyChangeEvent; + typedef JOBJECT64 FocusEvent; + typedef JOBJECT64 CaretEvent; + typedef JOBJECT64 MouseEvent; + typedef JOBJECT64 MenuEvent; + typedef JOBJECT64 AccessibleTable; + typedef JOBJECT64 AccessibleHyperlink; + typedef JOBJECT64 AccessibleHypertext; + + + typedef void (*Windows_runFP) (); + + typedef void (*SetPropertyChangeFP) (AccessBridge_PropertyChangeFP fp); + + typedef void (*SetJavaShutdownFP) (AccessBridge_JavaShutdownFP fp); + typedef void (*SetFocusGainedFP) (AccessBridge_FocusGainedFP fp); + typedef void (*SetFocusLostFP) (AccessBridge_FocusLostFP fp); + + typedef void (*SetCaretUpdateFP) (AccessBridge_CaretUpdateFP fp); + + typedef void (*SetMouseClickedFP) (AccessBridge_MouseClickedFP fp); + typedef void (*SetMouseEnteredFP) (AccessBridge_MouseEnteredFP fp); + typedef void (*SetMouseExitedFP) (AccessBridge_MouseExitedFP fp); + typedef void (*SetMousePressedFP) (AccessBridge_MousePressedFP fp); + typedef void (*SetMouseReleasedFP) (AccessBridge_MouseReleasedFP fp); + + typedef void (*SetMenuCanceledFP) (AccessBridge_MenuCanceledFP fp); + typedef void (*SetMenuDeselectedFP) (AccessBridge_MenuDeselectedFP fp); + typedef void (*SetMenuSelectedFP) (AccessBridge_MenuSelectedFP fp); + typedef void (*SetPopupMenuCanceledFP) (AccessBridge_PopupMenuCanceledFP fp); + typedef void (*SetPopupMenuWillBecomeInvisibleFP) (AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + typedef void (*SetPopupMenuWillBecomeVisibleFP) (AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + typedef void (*SetPropertyNameChangeFP) (AccessBridge_PropertyNameChangeFP fp); + typedef void (*SetPropertyDescriptionChangeFP) (AccessBridge_PropertyDescriptionChangeFP fp); + typedef void (*SetPropertyStateChangeFP) (AccessBridge_PropertyStateChangeFP fp); + typedef void (*SetPropertyValueChangeFP) (AccessBridge_PropertyValueChangeFP fp); + typedef void (*SetPropertySelectionChangeFP) (AccessBridge_PropertySelectionChangeFP fp); + typedef void (*SetPropertyTextChangeFP) (AccessBridge_PropertyTextChangeFP fp); + typedef void (*SetPropertyCaretChangeFP) (AccessBridge_PropertyCaretChangeFP fp); + typedef void (*SetPropertyVisibleDataChangeFP) (AccessBridge_PropertyVisibleDataChangeFP fp); + typedef void (*SetPropertyChildChangeFP) (AccessBridge_PropertyChildChangeFP fp); + typedef void (*SetPropertyActiveDescendentChangeFP) (AccessBridge_PropertyActiveDescendentChangeFP fp); + + typedef void (*SetPropertyTableModelChangeFP) (AccessBridge_PropertyTableModelChangeFP fp); + + typedef void (*ReleaseJavaObjectFP) (long vmID, Java_Object object); + + typedef BOOL (*GetVersionInfoFP) (long vmID, AccessBridgeVersionInfo *info); + + typedef BOOL (*IsJavaWindowFP) (HWND window); + typedef BOOL (*IsSameObjectFP) (long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + typedef BOOL (*GetAccessibleContextFromHWNDFP) (HWND window, long *vmID, AccessibleContext *ac); + typedef HWND (*getHWNDFromAccessibleContextFP) (long vmID, AccessibleContext ac); + + typedef BOOL (*GetAccessibleContextAtFP) (long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac); + typedef BOOL (*GetAccessibleContextWithFocusFP) (HWND window, long *vmID, AccessibleContext *ac); + typedef BOOL (*GetAccessibleContextInfoFP) (long vmID, AccessibleContext ac, AccessibleContextInfo *info); + typedef AccessibleContext (*GetAccessibleChildFromContextFP) (long vmID, AccessibleContext ac, jint i); + typedef AccessibleContext (*GetAccessibleParentFromContextFP) (long vmID, AccessibleContext ac); + + /* begin AccessibleTable */ + typedef BOOL (*getAccessibleTableInfoFP) (long vmID, AccessibleContext ac, AccessibleTableInfo *tableInfo); + typedef BOOL (*getAccessibleTableCellInfoFP) (long vmID, AccessibleTable accessibleTable, + jint row, jint column, AccessibleTableCellInfo *tableCellInfo); + + typedef BOOL (*getAccessibleTableRowHeaderFP) (long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + typedef BOOL (*getAccessibleTableColumnHeaderFP) (long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + typedef AccessibleContext (*getAccessibleTableRowDescriptionFP) (long vmID, AccessibleContext acParent, jint row); + typedef AccessibleContext (*getAccessibleTableColumnDescriptionFP) (long vmID, AccessibleContext acParent, jint column); + + typedef jint (*getAccessibleTableRowSelectionCountFP) (long vmID, AccessibleTable table); + typedef BOOL (*isAccessibleTableRowSelectedFP) (long vmID, AccessibleTable table, jint row); + typedef BOOL (*getAccessibleTableRowSelectionsFP) (long vmID, AccessibleTable table, jint count, + jint *selections); + + typedef jint (*getAccessibleTableColumnSelectionCountFP) (long vmID, AccessibleTable table); + typedef BOOL (*isAccessibleTableColumnSelectedFP) (long vmID, AccessibleTable table, jint column); + typedef BOOL (*getAccessibleTableColumnSelectionsFP) (long vmID, AccessibleTable table, jint count, + jint *selections); + + typedef jint (*getAccessibleTableRowFP) (long vmID, AccessibleTable table, jint index); + typedef jint (*getAccessibleTableColumnFP) (long vmID, AccessibleTable table, jint index); + typedef jint (*getAccessibleTableIndexFP) (long vmID, AccessibleTable table, jint row, jint column); + /* end AccessibleTable */ + + /* AccessibleRelationSet */ + typedef BOOL (*getAccessibleRelationSetFP) (long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo); + + /* AccessibleHypertext */ + typedef BOOL (*getAccessibleHypertextFP)(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo); + + typedef BOOL (*activateAccessibleHyperlinkFP)(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink); + + typedef jint (*getAccessibleHyperlinkCountFP)(const long vmID, + const AccessibleContext accessibleContext); + + typedef BOOL (*getAccessibleHypertextExtFP) (const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + AccessibleHypertextInfo *hypertextInfo); + + typedef jint (*getAccessibleHypertextLinkIndexFP)(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + typedef BOOL (*getAccessibleHyperlinkFP)(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + AccessibleHyperlinkInfo *hyperlinkInfo); + + + /* Accessible KeyBindings, Icons and Actions */ + typedef BOOL (*getAccessibleKeyBindingsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings); + + typedef BOOL (*getAccessibleIconsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons); + + typedef BOOL (*getAccessibleActionsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions); + + typedef BOOL (*doAccessibleActionsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + + /* AccessibleText */ + + typedef BOOL (*GetAccessibleTextInfoFP) (long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y); + typedef BOOL (*GetAccessibleTextItemsFP) (long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index); + typedef BOOL (*GetAccessibleTextSelectionInfoFP) (long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection); + typedef BOOL (*GetAccessibleTextAttributesFP) (long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes); + typedef BOOL (*GetAccessibleTextRectFP) (long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index); + typedef BOOL (*GetAccessibleTextLineBoundsFP) (long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex); + typedef BOOL (*GetAccessibleTextRangeFP) (long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len); + + typedef BOOL (*GetCurrentAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + typedef BOOL (*GetMaximumAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + typedef BOOL (*GetMinimumAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + + typedef void (*AddAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*ClearAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as); + typedef JOBJECT64 (*GetAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef int (*GetAccessibleSelectionCountFromContextFP) (long vmID, AccessibleSelection as); + typedef BOOL (*IsAccessibleChildSelectedFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*RemoveAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*SelectAllAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as); + + /* Utility methods */ + + typedef BOOL (*setTextContentsFP) (const long vmID, const AccessibleContext ac, const wchar_t *text); + typedef AccessibleContext (*getParentWithRoleFP) (const long vmID, const AccessibleContext ac, const wchar_t *role); + typedef AccessibleContext (*getParentWithRoleElseRootFP) (const long vmID, const AccessibleContext ac, const wchar_t *role); + typedef AccessibleContext (*getTopLevelObjectFP) (const long vmID, const AccessibleContext ac); + typedef int (*getObjectDepthFP) (const long vmID, const AccessibleContext ac); + typedef AccessibleContext (*getActiveDescendentFP) (const long vmID, const AccessibleContext ac); + + + typedef BOOL (*getVirtualAccessibleNameFP) (const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len); + + typedef BOOL (*requestFocusFP) (const long vmID, const AccessibleContext accessibleContext); + + typedef BOOL (*selectTextRangeFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex); + + typedef BOOL (*getTextAttributesInRangeFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + typedef int (*getVisibleChildrenCountFP) (const long vmID, const AccessibleContext accessibleContext); + + typedef BOOL (*getVisibleChildrenFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, VisibleChildrenInfo *children); + + typedef BOOL (*setCaretPositionFP) (const long vmID, const AccessibleContext accessibleContext, const int position); + + typedef BOOL (*getCaretLocationFP) (long vmID, AccessibleContext ac, AccessibleTextRectInfo *rectInfo, jint index); + + typedef int (*getEventsWaitingFP) (); + + typedef struct AccessBridgeFPsTag { + Windows_runFP Windows_run; + + SetPropertyChangeFP SetPropertyChange; + + SetJavaShutdownFP SetJavaShutdown; + SetFocusGainedFP SetFocusGained; + SetFocusLostFP SetFocusLost; + + SetCaretUpdateFP SetCaretUpdate; + + SetMouseClickedFP SetMouseClicked; + SetMouseEnteredFP SetMouseEntered; + SetMouseExitedFP SetMouseExited; + SetMousePressedFP SetMousePressed; + SetMouseReleasedFP SetMouseReleased; + + SetMenuCanceledFP SetMenuCanceled; + SetMenuDeselectedFP SetMenuDeselected; + SetMenuSelectedFP SetMenuSelected; + SetPopupMenuCanceledFP SetPopupMenuCanceled; + SetPopupMenuWillBecomeInvisibleFP SetPopupMenuWillBecomeInvisible; + SetPopupMenuWillBecomeVisibleFP SetPopupMenuWillBecomeVisible; + + SetPropertyNameChangeFP SetPropertyNameChange; + SetPropertyDescriptionChangeFP SetPropertyDescriptionChange; + SetPropertyStateChangeFP SetPropertyStateChange; + SetPropertyValueChangeFP SetPropertyValueChange; + SetPropertySelectionChangeFP SetPropertySelectionChange; + SetPropertyTextChangeFP SetPropertyTextChange; + SetPropertyCaretChangeFP SetPropertyCaretChange; + SetPropertyVisibleDataChangeFP SetPropertyVisibleDataChange; + SetPropertyChildChangeFP SetPropertyChildChange; + SetPropertyActiveDescendentChangeFP SetPropertyActiveDescendentChange; + + SetPropertyTableModelChangeFP SetPropertyTableModelChange; + + ReleaseJavaObjectFP ReleaseJavaObject; + GetVersionInfoFP GetVersionInfo; + + IsJavaWindowFP IsJavaWindow; + IsSameObjectFP IsSameObject; + GetAccessibleContextFromHWNDFP GetAccessibleContextFromHWND; + getHWNDFromAccessibleContextFP getHWNDFromAccessibleContext; + + GetAccessibleContextAtFP GetAccessibleContextAt; + GetAccessibleContextWithFocusFP GetAccessibleContextWithFocus; + GetAccessibleContextInfoFP GetAccessibleContextInfo; + GetAccessibleChildFromContextFP GetAccessibleChildFromContext; + GetAccessibleParentFromContextFP GetAccessibleParentFromContext; + + getAccessibleTableInfoFP getAccessibleTableInfo; + getAccessibleTableCellInfoFP getAccessibleTableCellInfo; + + getAccessibleTableRowHeaderFP getAccessibleTableRowHeader; + getAccessibleTableColumnHeaderFP getAccessibleTableColumnHeader; + + getAccessibleTableRowDescriptionFP getAccessibleTableRowDescription; + getAccessibleTableColumnDescriptionFP getAccessibleTableColumnDescription; + + getAccessibleTableRowSelectionCountFP getAccessibleTableRowSelectionCount; + isAccessibleTableRowSelectedFP isAccessibleTableRowSelected; + getAccessibleTableRowSelectionsFP getAccessibleTableRowSelections; + + getAccessibleTableColumnSelectionCountFP getAccessibleTableColumnSelectionCount; + isAccessibleTableColumnSelectedFP isAccessibleTableColumnSelected; + getAccessibleTableColumnSelectionsFP getAccessibleTableColumnSelections; + + getAccessibleTableRowFP getAccessibleTableRow; + getAccessibleTableColumnFP getAccessibleTableColumn; + getAccessibleTableIndexFP getAccessibleTableIndex; + + getAccessibleRelationSetFP getAccessibleRelationSet; + + getAccessibleHypertextFP getAccessibleHypertext; + activateAccessibleHyperlinkFP activateAccessibleHyperlink; + getAccessibleHyperlinkCountFP getAccessibleHyperlinkCount; + getAccessibleHypertextExtFP getAccessibleHypertextExt; + getAccessibleHypertextLinkIndexFP getAccessibleHypertextLinkIndex; + getAccessibleHyperlinkFP getAccessibleHyperlink; + + getAccessibleKeyBindingsFP getAccessibleKeyBindings; + getAccessibleIconsFP getAccessibleIcons; + getAccessibleActionsFP getAccessibleActions; + doAccessibleActionsFP doAccessibleActions; + + GetAccessibleTextInfoFP GetAccessibleTextInfo; + GetAccessibleTextItemsFP GetAccessibleTextItems; + GetAccessibleTextSelectionInfoFP GetAccessibleTextSelectionInfo; + GetAccessibleTextAttributesFP GetAccessibleTextAttributes; + GetAccessibleTextRectFP GetAccessibleTextRect; + GetAccessibleTextLineBoundsFP GetAccessibleTextLineBounds; + GetAccessibleTextRangeFP GetAccessibleTextRange; + + GetCurrentAccessibleValueFromContextFP GetCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextFP GetMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextFP GetMinimumAccessibleValueFromContext; + + AddAccessibleSelectionFromContextFP AddAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextFP ClearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextFP GetAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextFP GetAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextFP IsAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextFP RemoveAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextFP SelectAllAccessibleSelectionFromContext; + + setTextContentsFP setTextContents; + getParentWithRoleFP getParentWithRole; + getTopLevelObjectFP getTopLevelObject; + getParentWithRoleElseRootFP getParentWithRoleElseRoot; + getObjectDepthFP getObjectDepth; + getActiveDescendentFP getActiveDescendent; + + getVirtualAccessibleNameFP getVirtualAccessibleName; + requestFocusFP requestFocus; + selectTextRangeFP selectTextRange; + getTextAttributesInRangeFP getTextAttributesInRange; + getVisibleChildrenCountFP getVisibleChildrenCount; + getVisibleChildrenFP getVisibleChildren; + setCaretPositionFP setCaretPosition; + getCaretLocationFP getCaretLocation; + + getEventsWaitingFP getEventsWaiting; + + } AccessBridgeFPs; + + + /** + * Initialize the world + */ + BOOL initializeAccessBridge(); + BOOL shutdownAccessBridge(); + + /** + * Window routines + */ + BOOL IsJavaWindow(HWND window); + + // Returns the virtual machine ID and AccessibleContext for a top-level window + BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac); + + // Returns the HWND from the AccessibleContext of a top-level window + HWND getHWNDFromAccessibleContext(long vmID, AccessibleContext ac); + + + /** + * Event handling routines + */ + void SetJavaShutdown(AccessBridge_JavaShutdownFP fp); + void SetFocusGained(AccessBridge_FocusGainedFP fp); + void SetFocusLost(AccessBridge_FocusLostFP fp); + + void SetCaretUpdate(AccessBridge_CaretUpdateFP fp); + + void SetMouseClicked(AccessBridge_MouseClickedFP fp); + void SetMouseEntered(AccessBridge_MouseEnteredFP fp); + void SetMouseExited(AccessBridge_MouseExitedFP fp); + void SetMousePressed(AccessBridge_MousePressedFP fp); + void SetMouseReleased(AccessBridge_MouseReleasedFP fp); + + void SetMenuCanceled(AccessBridge_MenuCanceledFP fp); + void SetMenuDeselected(AccessBridge_MenuDeselectedFP fp); + void SetMenuSelected(AccessBridge_MenuSelectedFP fp); + void SetPopupMenuCanceled(AccessBridge_PopupMenuCanceledFP fp); + void SetPopupMenuWillBecomeInvisible(AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + void SetPopupMenuWillBecomeVisible(AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + void SetPropertyNameChange(AccessBridge_PropertyNameChangeFP fp); + void SetPropertyDescriptionChange(AccessBridge_PropertyDescriptionChangeFP fp); + void SetPropertyStateChange(AccessBridge_PropertyStateChangeFP fp); + void SetPropertyValueChange(AccessBridge_PropertyValueChangeFP fp); + void SetPropertySelectionChange(AccessBridge_PropertySelectionChangeFP fp); + void SetPropertyTextChange(AccessBridge_PropertyTextChangeFP fp); + void SetPropertyCaretChange(AccessBridge_PropertyCaretChangeFP fp); + void SetPropertyVisibleDataChange(AccessBridge_PropertyVisibleDataChangeFP fp); + void SetPropertyChildChange(AccessBridge_PropertyChildChangeFP fp); + void SetPropertyActiveDescendentChange(AccessBridge_PropertyActiveDescendentChangeFP fp); + + void SetPropertyTableModelChange(AccessBridge_PropertyTableModelChangeFP fp); + + + /** + * General routines + */ + void ReleaseJavaObject(long vmID, Java_Object object); + BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info); + HWND GetHWNDFromAccessibleContext(long vmID, JOBJECT64 accesibleContext); + + /** + * Accessible Context routines + */ + BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac); + BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac); + BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info); + AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index); + AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac); + + /** + * Accessible Text routines + */ + BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y); + BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index); + BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection); + BOOL GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes); + BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index); + BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex); + BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len); + + /* begin AccessibleTable routines */ + BOOL getAccessibleTableInfo(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + BOOL getAccessibleTableCellInfo(long vmID, AccessibleTable accessibleTable, jint row, jint column, + AccessibleTableCellInfo *tableCellInfo); + + BOOL getAccessibleTableRowHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableColumnHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + AccessibleContext getAccessibleTableRowDescription(long vmID, AccessibleContext acParent, jint row); + AccessibleContext getAccessibleTableColumnDescription(long vmID, AccessibleContext acParent, jint column); + + jint getAccessibleTableRowSelectionCount(long vmID, AccessibleTable table); + BOOL isAccessibleTableRowSelected(long vmID, AccessibleTable table, jint row); + BOOL getAccessibleTableRowSelections(long vmID, AccessibleTable table, jint count, jint *selections); + + jint getAccessibleTableColumnSelectionCount(long vmID, AccessibleTable table); + BOOL isAccessibleTableColumnSelected(long vmID, AccessibleTable table, jint column); + BOOL getAccessibleTableColumnSelections(long vmID, AccessibleTable table, jint count, jint *selections); + + jint getAccessibleTableRow(long vmID, AccessibleTable table, jint index); + jint getAccessibleTableColumn(long vmID, AccessibleTable table, jint index); + jint getAccessibleTableIndex(long vmID, AccessibleTable table, jint row, jint column); + /* end AccessibleTable */ + + /* ----- AccessibleRelationSet routines */ + BOOL getAccessibleRelationSet(long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo); + + /* ----- AccessibleHypertext routines */ + + /* + * Returns hypertext information associated with a component. + */ + BOOL getAccessibleHypertext(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo); + + /* + * Requests that a hyperlink be activated. + */ + BOOL activateAccessibleHyperlink(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink); + + /* + * Returns the number of hyperlinks in a component + * Maps to AccessibleHypertext.getLinkCount. + * Returns -1 on error. + */ + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleHypertext hypertext); + + /* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * Returns FALSE on error. + */ + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo); + + /* + * Returns the index into an array of hyperlinks that is associated with + * a character index in document; maps to AccessibleHypertext.getLinkIndex + * Returns -1 on error. + */ + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + /* + * Returns the nth hyperlink in a document + * Maps to AccessibleHypertext.getLink. + * Returns FALSE on error + */ + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + /* Accessible KeyBindings, Icons and Actions */ + + /* + * Returns a list of key bindings associated with a component. + */ + BOOL getAccessibleKeyBindings(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings); + + /* + * Returns a list of icons associate with a component. + */ + BOOL getAccessibleIcons(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons); + + /* + * Returns a list of actions that a component can perform. + */ + BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions); + + /* + * Request that a list of AccessibleActions be performed by a component. + * Returns TRUE if all actions are performed. Returns FALSE + * when the first requested action fails in which case "failure" + * contains the index of the action that failed. + */ + BOOL doAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + + + /* Additional utility methods */ + + /* + * Returns whether two object references refer to the same object. + */ + BOOL IsSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + + /** + * Sets editable text contents. The AccessibleContext must implement AccessibleEditableText and + * be editable. The maximum text length that can be set is MAX_STRING_SIZE - 1. + * Returns whether successful + */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text); + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h + * If there is no ancestor object that has the specified role, + * returns (AccessibleContext)0. + */ + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h. If an object with the specified + * role does not exist, returns the top level object for the Java Window. + * Returns (AccessibleContext)0 on error. + */ + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext); + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext); + + /** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * This method assumes the ActiveDescendent is the component that is currently + * selected in a container object. + * Returns (AccessibleContext)0 on error or if there is no selection. + */ + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext); + + /** + /** + * Accessible Value routines + */ + BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + + /** + * Accessible Selection routines + */ + void AddAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + void ClearAccessibleSelectionFromContext(long vmID, AccessibleSelection as); + JOBJECT64 GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as); + BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i); + void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as); + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len); + + /** + * Request focus for a component. Returns whether successful. + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(const long vmID, const AccessibleContext accessibleContext); + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful. + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(const long vmID, const AccessibleContext accessibleContext, const int startIndex, + const int endIndex); + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + /** + * Returns the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext); + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, + VisibleChildrenInfo *visibleChildrenInfo); + + /** + * Set the caret to a text position. Returns whether successful. + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const long vmID, const AccessibleContext accessibleContext, + const int position); + + /** + * Gets the text caret location + */ + BOOL getCaretLocation(long vmID, AccessibleContext ac, + AccessibleTextRectInfo *rectInfo, jint index); + + /** + * Gets the number of events waiting to fire + */ + int getEventsWaiting(); + +#ifdef __cplusplus +} +#endif --- /dev/null 2015-03-30 10:55:08.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeDebug.cpp 2015-03-30 10:55:07.161658500 -0500 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage AccessBridge debugging + */ + +#include "AccessBridgeDebug.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * print a GetLastError message + */ +char *printError(char *msg) { + LPVOID lpMsgBuf = NULL; + static char retbuf[256]; + + if (msg != NULL) { + strncpy((char *)retbuf, msg, sizeof(retbuf)); + } + if (!FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL )) + { + PrintDebugString(" %s: FormatMessage failed", msg); + } else { + PrintDebugString(" %s: %s", msg, (char *)lpMsgBuf); + } + if (lpMsgBuf != NULL) { + strncat((char *)retbuf, ": ", sizeof(retbuf) - strlen(retbuf) - 1); + strncat((char *)retbuf, (char *)lpMsgBuf, sizeof(retbuf) - strlen(retbuf) - 1); + } + return (char *)retbuf; +} + + + /** + * Send debugging info to the appropriate place + */ + void PrintDebugString(char *msg, ...) { +#ifdef DEBUGGING_ON + char buf[1024]; + va_list argprt; + + va_start(argprt, msg); // set up argptr + vsprintf(buf, msg, argprt); +#ifdef SEND_TO_OUTPUT_DEBUG_STRING + OutputDebugString(buf); +#endif +#ifdef SEND_TO_CONSOLE + printf(buf); + printf("\r\n"); +#endif +#endif + } + + /** + * Send Java debugging info to the appropriate place + */ + void PrintJavaDebugString2(char *msg, ...) { +#ifdef JAVA_DEBUGGING_ON + char buf[1024]; + va_list argprt; + + va_start(argprt, msg); // set up argptr + vsprintf(buf, msg, argprt); +#ifdef SEND_TO_OUTPUT_DEBUG_STRING + OutputDebugString(buf); +#endif +#ifdef SEND_TO_CONSOLE + printf(buf); + printf("\r\n"); +#endif +#endif + } + /** + * Wide version of the method to send debugging info to the appropriate place + */ + void wPrintDebugString(wchar_t *msg, ...) { +#ifdef DEBUGGING_ON + char buf[1024]; + char charmsg[256]; + va_list argprt; + + va_start(argprt, msg); // set up argptr + sprintf(charmsg, "%ls", msg); // convert format string to multi-byte + vsprintf(buf, charmsg, argprt); +#ifdef SEND_TO_OUTPUT_DEBUG_STRING + OutputDebugString(buf); +#endif +#ifdef SEND_TO_CONSOLE + printf(buf); + printf("\r\n"); +#endif +#endif + } + + /** + * Wide version of the method to send Java debugging info to the appropriate place + */ + void wPrintJavaDebugString(wchar_t *msg, ...) { +#ifdef JAVA_DEBUGGING_ON + char buf[1024]; + char charmsg[256]; + va_list argprt; + + va_start(argprt, msg); // set up argptr + sprintf(charmsg, "%ls", msg); // convert format string to multi-byte + vsprintf(buf, charmsg, argprt); +#ifdef SEND_TO_OUTPUT_DEBUG_STRING + OutputDebugString(buf); +#endif +#ifdef SEND_TO_CONSOLE + printf(buf); + printf("\r\n"); +#endif +#endif + } +#ifdef __cplusplus +} +#endif --- /dev/null 2015-03-30 10:55:11.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeDebug.h 2015-03-30 10:55:10.319666700 -0500 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage AccessBridge debugging + */ + +#ifndef __AccessBridgeDebug_H__ +#define __AccessBridgeDebug_H__ + +#include +#include + +#ifdef DEBUG +#define DEBUGGING_ON +#define SEND_TO_OUTPUT_DEBUG_STRING +//#define JAVA_DEBUGGING_ON +#endif + +#ifdef DEBUGGING_ON +#define DEBUG_CODE(x) x +#else +#define DEBUG_CODE(x) /* */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + char *printError(char *msg); + void PrintDebugString(char *msg, ...); + void PrintJavaDebugString(char *msg, ...); + void wPrintJavaDebugString(wchar_t *msg, ...); + void wPrintDebugString(wchar_t *msg, ...); + +#ifdef __cplusplus +} +#endif + + +#endif --- /dev/null 2015-03-30 10:55:14.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp 2015-03-30 10:55:13.450677300 -0500 @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage firing Accessibility events to Windows AT + */ + +#include "AccessBridgeDebug.h" +#include "AccessBridgeEventHandler.h" +#include "AccessBridgePackages.h" +#include "WinAccessBridge.h" + +DEBUG_CODE(extern HWND theDialogWindow); +extern "C" { +DEBUG_CODE(void AppendToCallInfo(char *s)); +} + + +// ----------------------------- + +/** + * Initialization. Set all callbacks to null + */ +AccessBridgeEventHandler::AccessBridgeEventHandler() { + javaEventMask = 0; + accessibilityEventMask = 0; + + propertyChangeFP = (AccessBridge_PropertyChangeFP) NULL; + javaShutdownFP = (AccessBridge_JavaShutdownFP) NULL; + focusGainedFP = (AccessBridge_FocusGainedFP) NULL; + focusLostFP = (AccessBridge_FocusLostFP) NULL; + caretUpdateFP = (AccessBridge_CaretUpdateFP) NULL; + mouseClickedFP = (AccessBridge_MouseClickedFP) NULL; + mouseEnteredFP = (AccessBridge_MouseEnteredFP) NULL; + mouseExitedFP = (AccessBridge_MouseExitedFP) NULL; + mousePressedFP = (AccessBridge_MousePressedFP) NULL; + mouseReleasedFP = (AccessBridge_MouseReleasedFP) NULL; + menuCanceledFP = (AccessBridge_MenuCanceledFP) NULL; + menuDeselectedFP = (AccessBridge_MenuDeselectedFP) NULL; + menuSelectedFP = (AccessBridge_MenuSelectedFP) NULL; + popupMenuCanceledFP = (AccessBridge_PopupMenuCanceledFP) NULL; + popupMenuWillBecomeInvisibleFP = (AccessBridge_PopupMenuWillBecomeInvisibleFP) NULL; + popupMenuWillBecomeVisibleFP = (AccessBridge_PopupMenuWillBecomeVisibleFP) NULL; + + propertyNameChangeFP = (AccessBridge_PropertyNameChangeFP) NULL; + propertyDescriptionChangeFP = (AccessBridge_PropertyDescriptionChangeFP) NULL; + propertyStateChangeFP = (AccessBridge_PropertyStateChangeFP) NULL; + propertyValueChangeFP = (AccessBridge_PropertyValueChangeFP) NULL; + propertySelectionChangeFP = (AccessBridge_PropertySelectionChangeFP) NULL; + propertyTextChangeFP = (AccessBridge_PropertyTextChangeFP) NULL; + propertyCaretChangeFP = (AccessBridge_PropertyCaretChangeFP) NULL; + propertyVisibleDataChangeFP = (AccessBridge_PropertyVisibleDataChangeFP) NULL; + propertyChildChangeFP = (AccessBridge_PropertyChildChangeFP) NULL; + propertyActiveDescendentChangeFP = (AccessBridge_PropertyActiveDescendentChangeFP) NULL; + + propertyTableModelChangeFP = (AccessBridge_PropertyTableModelChangeFP) NULL; + +} + +/** + * Destruction. + */ +AccessBridgeEventHandler::~AccessBridgeEventHandler() { +} + + +// ------------ Event handling methods + +#define SET_JAVA_EVENT_FP(function, eventFP, callbackFP, eventConstant) \ + void AccessBridgeEventHandler::function(eventFP fp, WinAccessBridge *wab) { \ + callbackFP = fp; \ + if (fp != (eventFP) 0) { \ + javaEventMask |= eventConstant; \ + wab->addJavaEventNotification(eventConstant); \ + } else { \ + javaEventMask &= (0xFFFFFFFF - eventConstant); \ + wab->removeJavaEventNotification(eventConstant); \ + } \ + } + +SET_JAVA_EVENT_FP(setPropertyChangeFP, AccessBridge_PropertyChangeFP, propertyChangeFP, cPropertyChangeEvent) +SET_JAVA_EVENT_FP(setJavaShutdownFP, AccessBridge_JavaShutdownFP, javaShutdownFP, cJavaShutdownEvent) +SET_JAVA_EVENT_FP(setFocusGainedFP, AccessBridge_FocusGainedFP, focusGainedFP, cFocusGainedEvent) +SET_JAVA_EVENT_FP(setFocusLostFP, AccessBridge_FocusLostFP, focusLostFP, cFocusLostEvent) +SET_JAVA_EVENT_FP(setCaretUpdateFP, AccessBridge_CaretUpdateFP, caretUpdateFP, cCaretUpdateEvent) +SET_JAVA_EVENT_FP(setMouseClickedFP, AccessBridge_MouseClickedFP, mouseClickedFP, cMouseClickedEvent) +SET_JAVA_EVENT_FP(setMouseEnteredFP, AccessBridge_MouseEnteredFP, mouseEnteredFP, cMouseEnteredEvent) +SET_JAVA_EVENT_FP(setMouseExitedFP, AccessBridge_MouseExitedFP, mouseExitedFP, cMouseExitedEvent) +SET_JAVA_EVENT_FP(setMousePressedFP, AccessBridge_MousePressedFP, mousePressedFP, cMousePressedEvent) +SET_JAVA_EVENT_FP(setMouseReleasedFP, AccessBridge_MouseReleasedFP, mouseReleasedFP, cMouseReleasedEvent) +SET_JAVA_EVENT_FP(setMenuCanceledFP, AccessBridge_MenuCanceledFP, menuCanceledFP, cMenuCanceledEvent) +SET_JAVA_EVENT_FP(setMenuDeselectedFP, AccessBridge_MenuDeselectedFP, menuDeselectedFP, cMenuDeselectedEvent) +SET_JAVA_EVENT_FP(setMenuSelectedFP, AccessBridge_MenuSelectedFP, menuSelectedFP, cMenuSelectedEvent) +SET_JAVA_EVENT_FP(setPopupMenuCanceledFP, AccessBridge_PopupMenuCanceledFP, popupMenuCanceledFP, cPopupMenuCanceledEvent) +SET_JAVA_EVENT_FP(setPopupMenuWillBecomeInvisibleFP, AccessBridge_PopupMenuWillBecomeInvisibleFP, popupMenuWillBecomeInvisibleFP, cPopupMenuWillBecomeInvisibleEvent) +SET_JAVA_EVENT_FP(setPopupMenuWillBecomeVisibleFP, AccessBridge_PopupMenuWillBecomeVisibleFP, popupMenuWillBecomeVisibleFP, cPopupMenuWillBecomeVisibleEvent) + +#define SET_ACCESSIBILITY_EVENT_FP(function, eventFP, callbackFP, eventConstant) \ + void AccessBridgeEventHandler::function(eventFP fp, WinAccessBridge *wab) { \ + callbackFP = fp; \ + if (fp != (eventFP) 0) { \ + accessibilityEventMask |= eventConstant; \ + wab->addAccessibilityEventNotification(eventConstant); \ + } else { \ + accessibilityEventMask &= (0xFFFFFFFF - eventConstant); \ + wab->removeAccessibilityEventNotification(eventConstant); \ + } \ + } + + +SET_ACCESSIBILITY_EVENT_FP(setPropertyNameChangeFP, AccessBridge_PropertyNameChangeFP, propertyNameChangeFP, cPropertyNameChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyDescriptionChangeFP, AccessBridge_PropertyDescriptionChangeFP, propertyDescriptionChangeFP, cPropertyDescriptionChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyStateChangeFP, AccessBridge_PropertyStateChangeFP, propertyStateChangeFP, cPropertyStateChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyValueChangeFP, AccessBridge_PropertyValueChangeFP, propertyValueChangeFP, cPropertyValueChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertySelectionChangeFP, AccessBridge_PropertySelectionChangeFP, propertySelectionChangeFP, cPropertySelectionChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyTextChangeFP, AccessBridge_PropertyTextChangeFP, propertyTextChangeFP, cPropertyTextChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyCaretChangeFP, AccessBridge_PropertyCaretChangeFP, propertyCaretChangeFP, cPropertyCaretChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyVisibleDataChangeFP, AccessBridge_PropertyVisibleDataChangeFP, propertyVisibleDataChangeFP, cPropertyVisibleDataChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyChildChangeFP, AccessBridge_PropertyChildChangeFP, propertyChildChangeFP, cPropertyChildChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyActiveDescendentChangeFP, AccessBridge_PropertyActiveDescendentChangeFP, propertyActiveDescendentChangeFP, cPropertyActiveDescendentChangeEvent) + +SET_ACCESSIBILITY_EVENT_FP(setPropertyTableModelChangeFP, AccessBridge_PropertyTableModelChangeFP, propertyTableModelChangeFP, cPropertyTableModelChangeEvent) + + +/** + * propertyChange - extends the Java method call to Windows: + * propertyChange(PropertyChangeEvent e, ) + * + * Note: PropertyChangeEvent object passed in is a globalReference; + * It is critical that releaseJavaObject() be called + * on the PropertyChangeEvent once it is no longer needed, + * otherwise the JavaVM/JNI will suffer memory leaks + * + */ +void +AccessBridgeEventHandler::firePropertyChange(long vmID, + JOBJECT64 event, JOBJECT64 source, + wchar_t *property, wchar_t *oldName, + wchar_t *newName) { + DEBUG_CODE(char debugBuf[255]); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + DEBUG_CODE(sprintf(debugBuf, "\r\nCalling firePropertyChange(%p, %p):\r\n", event, source)); +#else // JOBJECT64 is jlong (64 bit) + DEBUG_CODE(sprintf(debugBuf, "\r\nCalling firePropertyChange(%016I64X, %016I64X):\r\n", event, source)); +#endif + DEBUG_CODE(AppendToCallInfo(debugBuf)); + + if (propertyChangeFP != (AccessBridge_PropertyChangeFP) 0) { + propertyChangeFP(vmID, event, source, property, oldName, newName); + } else { + DEBUG_CODE(AppendToCallInfo(" Error! propertyChangeFP == 0\r\n")); + } +} + + +/** + * FIRE_EVENT - macro for all fireXXX methods (which + * all are basically identical to one another...) + * + * Note: the event and source objects passed in are globalReferences; + * It is critical that releaseJavaObject() be called + * on them once they are no longer needed, otherwise + * the JavaVM/JNI will suffer memory leaks + * + */ +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +const char fireEventDebugString[] = "\r\nIn AccessBridgeEventHandler::%s(%p, %p); vmID = %X\r\n"; +#else // JOBJECT64 is jlong (64 bit) +const char fireEventDebugString[] = "\r\nIn AccessBridgeEventHandler::%s(%016I64X, %016I64X); vmID = %X\r\n"; +#endif + +#define FIRE_EVENT(method, FPprototype, eventFP) \ + void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source) { \ + DEBUG_CODE(char debugBuf[255]); \ + DEBUG_CODE(sprintf(debugBuf, fireEventDebugString, #method, event, source, vmID)); \ + DEBUG_CODE(AppendToCallInfo(debugBuf)); \ + if (eventFP != (FPprototype) 0) { \ + eventFP(vmID, event, source); \ + } else { \ + DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + } \ + } + + void AccessBridgeEventHandler::fireJavaShutdown(long vmID) { + DEBUG_CODE(char debugBuf[255]); + DEBUG_CODE(sprintf(debugBuf, "\r\nCalling fireJavaShutdown; vmID = %X\r\n", vmID)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + if (javaShutdownFP != (AccessBridge_JavaShutdownFP) 0) { + javaShutdownFP(vmID); + } else { + DEBUG_CODE(AppendToCallInfo(" Error! javaShutdownFP == 0\r\n")); + } + } + +FIRE_EVENT(fireFocusGained, AccessBridge_FocusGainedFP, focusGainedFP) +FIRE_EVENT(fireFocusLost, AccessBridge_FocusLostFP, focusLostFP) +FIRE_EVENT(fireCaretUpdate, AccessBridge_CaretUpdateFP, caretUpdateFP) +FIRE_EVENT(fireMouseClicked, AccessBridge_MouseClickedFP, mouseClickedFP) +FIRE_EVENT(fireMouseEntered, AccessBridge_MouseEnteredFP, mouseEnteredFP) +FIRE_EVENT(fireMouseExited, AccessBridge_MouseExitedFP, mouseExitedFP) +FIRE_EVENT(fireMousePressed, AccessBridge_MousePressedFP, mousePressedFP) +FIRE_EVENT(fireMouseReleased, AccessBridge_MouseReleasedFP, mouseReleasedFP) +FIRE_EVENT(fireMenuCanceled, AccessBridge_MenuCanceledFP, menuCanceledFP) +FIRE_EVENT(fireMenuDeselected, AccessBridge_MenuDeselectedFP, menuDeselectedFP) +FIRE_EVENT(fireMenuSelected, AccessBridge_MenuSelectedFP, menuSelectedFP) +FIRE_EVENT(firePopupMenuCanceled, AccessBridge_PopupMenuCanceledFP, popupMenuCanceledFP) +FIRE_EVENT(firePopupMenuWillBecomeInvisible, AccessBridge_PopupMenuWillBecomeInvisibleFP, popupMenuWillBecomeInvisibleFP) +FIRE_EVENT(firePopupMenuWillBecomeVisible, AccessBridge_PopupMenuWillBecomeVisibleFP, popupMenuWillBecomeVisibleFP) + + +/** + * FIRE_PROPERTY_CHANGE - macro for all fireXXX methods (which + * all are basically identical to one another... + * + * Note: the event and source objects passed in are globalReferences; + * It is critical that releaseJavaObject() be called + * on them once they are no longer needed, otherwise + * the JavaVM/JNI will suffer memory leaks + * + */ +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +const char firePropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a no-param property change (%p, %p):\r\n"; +#else // JOBJECT64 is jlong (64 bit) +const char firePropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a no-param property change (%016I64X, %016I64X):\r\n"; +#endif + +#define FIRE_PROPERTY_CHANGE(method, FPprototype, eventFP) \ + void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source) { \ + DEBUG_CODE(char debugBuf[255]); \ + DEBUG_CODE(sprintf(debugBuf, firePropertyChangeDebugString, #method, event, source)); \ + DEBUG_CODE(AppendToCallInfo(debugBuf)); \ + if (eventFP != (FPprototype) 0) { \ + eventFP(vmID, event, source); \ + } else { \ + DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + } \ + } + +/** + * FIRE_STRING_PROPERTY_CHANGE - macro for all firePropertyXXXChange methods + * that have strings as the old/new values + + * Note: the event and source objects passed in are globalReferences; + * It is critical that releaseJavaObject() be called + * on them once they are no longer needed, otherwise + * the JavaVM/JNI will suffer memory leaks + * + */ +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +const char fireStringPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a string property change (%p, %p, %ls, %ls):\r\n"; +#else // JOBJECT64 is jlong (64 bit) +const char fireStringPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a string property change (%016I64X, %016I64X, %ls, %ls):\r\n"; +#endif + +#define FIRE_STRING_PROPERTY_CHANGE(method, FPprototype, eventFP, oldValue, newValue) \ + void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source, \ + wchar_t *oldValue, wchar_t *newValue) { \ + DEBUG_CODE(char debugBuf[255]); \ + DEBUG_CODE(sprintf(debugBuf, fireStringPropertyChangeDebugString, #method, event, source, oldValue, newValue)); \ + DEBUG_CODE(AppendToCallInfo(debugBuf)); \ + if (eventFP != (FPprototype) 0) { \ + eventFP(vmID, event, source, oldValue, newValue); \ + } else { \ + DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + } \ + } + +/** + * FIRE_INT_PROPERTY_CHANGE - macro for all firePropertyXXXChange methods + * that have ints as the old/new values + * + * Note: the event and source objects passed in are globalReferences; + * It is critical that releaseJavaObject() be called + * on them once they are no longer needed, otherwise + * the JavaVM/JNI will suffer memory leaks + * + */ +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +const char fireIntPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an int property change (%p, %p, %d, %d):\r\n"; +#else // JOBJECT64 is jlong (64 bit) +const char fireIntPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an int property change (%016I64X, %016I64X, %d, %d):\r\n"; +#endif + +#define FIRE_INT_PROPERTY_CHANGE(method, FPprototype, eventFP) \ + void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source, \ + int oldValue, int newValue) { \ + DEBUG_CODE(char debugBuf[255]); \ + DEBUG_CODE(sprintf(debugBuf, fireIntPropertyChangeDebugString, #method, event, source, oldValue, newValue)); \ + DEBUG_CODE(AppendToCallInfo(debugBuf)); \ + if (eventFP != (FPprototype) 0) { \ + eventFP(vmID, event, source, oldValue, newValue); \ + } else { \ + DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + } \ + } + +/** + * FIRE_AC_PROPERTY_CHANGE - macro for all firePropertyXXXChange methods + * that have jobjects (AccessibleContexts) as the old/new values + * + * Note: the event and source objects passed in are globalReferences; + * It is critical that releaseJavaObject() be called + * on them once they are no longer needed, otherwise + * the JavaVM/JNI will suffer memory leaks + * + */ +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +const char fireACPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an AC property change (%p, %p, %p, %p):\r\n"; +#else // JOBJECT64 is jlong (64 bit) +const char fireACPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an AC property change (%016I64X, %016I64X, %016I64X, %016I64X):\r\n"; +#endif + +#define FIRE_AC_PROPERTY_CHANGE(method, FPprototype, eventFP) \ + void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source, \ + JOBJECT64 oldValue, JOBJECT64 newValue) { \ + DEBUG_CODE(char debugBuf[255]); \ + DEBUG_CODE(sprintf(debugBuf, fireACPropertyChangeDebugString, #method, event, source, oldValue, newValue)); \ + DEBUG_CODE(AppendToCallInfo(debugBuf)); \ + if (eventFP != (FPprototype) 0) { \ + eventFP(vmID, event, source, oldValue, newValue); \ + } else { \ + DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + } \ + } + +FIRE_STRING_PROPERTY_CHANGE(firePropertyNameChange, + AccessBridge_PropertyNameChangeFP, + propertyNameChangeFP, oldName, newName) +FIRE_STRING_PROPERTY_CHANGE(firePropertyDescriptionChange, + AccessBridge_PropertyDescriptionChangeFP, + propertyDescriptionChangeFP, + oldDescription, newDescription) +FIRE_STRING_PROPERTY_CHANGE(firePropertyStateChange, + AccessBridge_PropertyStateChangeFP, + propertyStateChangeFP, oldState, newState) +FIRE_STRING_PROPERTY_CHANGE(firePropertyValueChange, + AccessBridge_PropertyValueChangeFP, + propertyValueChangeFP, oldValue, newValue) +FIRE_PROPERTY_CHANGE(firePropertySelectionChange, + AccessBridge_PropertySelectionChangeFP, + propertySelectionChangeFP) +FIRE_PROPERTY_CHANGE(firePropertyTextChange, + AccessBridge_PropertyTextChangeFP, + propertyTextChangeFP); +FIRE_INT_PROPERTY_CHANGE(firePropertyCaretChange, + AccessBridge_PropertyCaretChangeFP, + propertyCaretChangeFP) +FIRE_PROPERTY_CHANGE(firePropertyVisibleDataChange, + AccessBridge_PropertyVisibleDataChangeFP, + propertyVisibleDataChangeFP) +FIRE_AC_PROPERTY_CHANGE(firePropertyChildChange, + AccessBridge_PropertyChildChangeFP, + propertyChildChangeFP) +FIRE_AC_PROPERTY_CHANGE(firePropertyActiveDescendentChange, + AccessBridge_PropertyActiveDescendentChangeFP, + propertyActiveDescendentChangeFP) + +FIRE_STRING_PROPERTY_CHANGE(firePropertyTableModelChange, + AccessBridge_PropertyTableModelChangeFP, + propertyTableModelChangeFP, oldValue, newValue) --- /dev/null 2015-03-30 10:55:17.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeEventHandler.h 2015-03-30 10:55:16.579688900 -0500 @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage firing Accessibility events to Windows AT + */ + +#ifndef __AccessBridgeEventHandler_H__ +#define __AccessBridgeEventHandler_H__ + +#include "AccessBridgeCallbacks.h" +#include "AccessBridgePackages.h" + +class WinAccessBridge; + +class AccessBridgeEventHandler { + long javaEventMask; + long accessibilityEventMask; + + AccessBridge_PropertyChangeFP propertyChangeFP; + AccessBridge_JavaShutdownFP javaShutdownFP; + AccessBridge_FocusGainedFP focusGainedFP; + AccessBridge_FocusLostFP focusLostFP; + AccessBridge_CaretUpdateFP caretUpdateFP; + AccessBridge_MouseClickedFP mouseClickedFP; + AccessBridge_MouseEnteredFP mouseEnteredFP; + AccessBridge_MouseExitedFP mouseExitedFP; + AccessBridge_MousePressedFP mousePressedFP; + AccessBridge_MouseReleasedFP mouseReleasedFP; + AccessBridge_MenuCanceledFP menuCanceledFP; + AccessBridge_MenuDeselectedFP menuDeselectedFP; + AccessBridge_MenuSelectedFP menuSelectedFP; + AccessBridge_PopupMenuCanceledFP popupMenuCanceledFP; + AccessBridge_PopupMenuWillBecomeInvisibleFP popupMenuWillBecomeInvisibleFP; + AccessBridge_PopupMenuWillBecomeVisibleFP popupMenuWillBecomeVisibleFP; + + AccessBridge_PropertyNameChangeFP propertyNameChangeFP; + AccessBridge_PropertyDescriptionChangeFP propertyDescriptionChangeFP; + AccessBridge_PropertyStateChangeFP propertyStateChangeFP; + AccessBridge_PropertyValueChangeFP propertyValueChangeFP; + AccessBridge_PropertySelectionChangeFP propertySelectionChangeFP; + AccessBridge_PropertyTextChangeFP propertyTextChangeFP; + AccessBridge_PropertyCaretChangeFP propertyCaretChangeFP; + AccessBridge_PropertyVisibleDataChangeFP propertyVisibleDataChangeFP; + AccessBridge_PropertyChildChangeFP propertyChildChangeFP; + AccessBridge_PropertyActiveDescendentChangeFP propertyActiveDescendentChangeFP; + + AccessBridge_PropertyTableModelChangeFP propertyTableModelChangeFP; + + + +public: + AccessBridgeEventHandler(); + ~AccessBridgeEventHandler(); + long getJavaEventMask() {return javaEventMask;}; + long getAccessibilityEventMask() {return accessibilityEventMask;}; + + // ------- Registry methods + void setPropertyChangeFP(AccessBridge_PropertyChangeFP fp, WinAccessBridge *wab); + void setJavaShutdownFP(AccessBridge_JavaShutdownFP fp, WinAccessBridge *wab); + void setFocusGainedFP(AccessBridge_FocusGainedFP fp, WinAccessBridge *wab); + void setFocusLostFP(AccessBridge_FocusLostFP fp, WinAccessBridge *wab); + void setCaretUpdateFP(AccessBridge_CaretUpdateFP fp, WinAccessBridge *wab); + void setMouseClickedFP(AccessBridge_MouseClickedFP fp, WinAccessBridge *wab); + void setMouseEnteredFP(AccessBridge_MouseEnteredFP fp, WinAccessBridge *wab); + void setMouseExitedFP(AccessBridge_MouseExitedFP fp, WinAccessBridge *wab); + void setMousePressedFP(AccessBridge_MousePressedFP fp, WinAccessBridge *wab); + void setMouseReleasedFP(AccessBridge_MouseReleasedFP fp, WinAccessBridge *wab); + void setMenuCanceledFP(AccessBridge_MenuCanceledFP fp, WinAccessBridge *wab); + void setMenuDeselectedFP(AccessBridge_MenuDeselectedFP fp, WinAccessBridge *wab); + void setMenuSelectedFP(AccessBridge_MenuSelectedFP fp, WinAccessBridge *wab); + void setPopupMenuCanceledFP(AccessBridge_PopupMenuCanceledFP fp, WinAccessBridge *wab); + void setPopupMenuWillBecomeInvisibleFP(AccessBridge_PopupMenuWillBecomeInvisibleFP fp, + WinAccessBridge *wab); + void setPopupMenuWillBecomeVisibleFP(AccessBridge_PopupMenuWillBecomeVisibleFP fp, + WinAccessBridge *wab); + + void setPropertyNameChangeFP(AccessBridge_PropertyNameChangeFP fp, WinAccessBridge *wab); + void setPropertyDescriptionChangeFP(AccessBridge_PropertyDescriptionChangeFP fp, + WinAccessBridge *wab); + void setPropertyStateChangeFP(AccessBridge_PropertyStateChangeFP fp, WinAccessBridge *wab); + void setPropertyValueChangeFP(AccessBridge_PropertyValueChangeFP fp, WinAccessBridge *wab); + void setPropertySelectionChangeFP(AccessBridge_PropertySelectionChangeFP fp, + WinAccessBridge *wab); + void setPropertyTextChangeFP(AccessBridge_PropertyTextChangeFP fp, WinAccessBridge *wab); + void setPropertyCaretChangeFP(AccessBridge_PropertyCaretChangeFP fp, WinAccessBridge *wab); + void setPropertyVisibleDataChangeFP(AccessBridge_PropertyVisibleDataChangeFP fp, + WinAccessBridge *wab); + void setPropertyChildChangeFP(AccessBridge_PropertyChildChangeFP fp, WinAccessBridge *wab); + void setPropertyActiveDescendentChangeFP(AccessBridge_PropertyActiveDescendentChangeFP fp, + WinAccessBridge *wab); + + void setPropertyTableModelChangeFP(AccessBridge_PropertyTableModelChangeFP fp, + WinAccessBridge *wab); + + // ------- Event notification methods + void firePropertyChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *property, wchar_t *oldName, wchar_t *newName); + void fireJavaShutdown(long vmID); + void fireFocusGained(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireFocusLost(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireCaretUpdate(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMouseClicked(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMouseEntered(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMouseExited(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMousePressed(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMouseReleased(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMenuCanceled(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMenuDeselected(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMenuSelected(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePopupMenuCanceled(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePopupMenuWillBecomeInvisible(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePopupMenuWillBecomeVisible(long vmID, JOBJECT64 event, JOBJECT64 source); + + void firePropertyNameChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldName, wchar_t *newName); + void firePropertyDescriptionChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldDescription, wchar_t *newDescription); + void firePropertyStateChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldState, wchar_t *newState); + void firePropertyValueChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldValue, wchar_t *newValue); + void firePropertySelectionChange(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePropertyTextChange(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePropertyCaretChange(long vmID, JOBJECT64 event, JOBJECT64 source, + int oldPosition, int newPosition); + void firePropertyVisibleDataChange(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePropertyChildChange(long vmID, JOBJECT64 event, JOBJECT64 source, + JOBJECT64 oldChild, JOBJECT64 newChild); + void firePropertyActiveDescendentChange(long vmID, JOBJECT64 event, JOBJECT64 source, + JOBJECT64 oldActiveDescendent, JOBJECT64 newActiveDescendent); + + void firePropertyTableModelChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldValue, wchar_t *newValue); + +}; + + +#endif --- /dev/null 2015-03-30 10:55:20.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp 2015-03-30 10:55:19.712699000 -0500 @@ -0,0 +1,4793 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage JNI calls into AccessBridge.java + */ + +#include "AccessBridgeJavaEntryPoints.h" +#include "AccessBridgeDebug.h" + + + +/** + * Initialize the AccessBridgeJavaEntryPoints class + * + */ +AccessBridgeJavaEntryPoints::AccessBridgeJavaEntryPoints(JNIEnv *jniEnvironment, + jobject bridgeObject) { + jniEnv = jniEnvironment; + accessBridgeObject = (jobject)bridgeObject; + PrintDebugString("AccessBridgeJavaEntryPoints(%X, %X) called", jniEnv, accessBridgeObject); +} + + +/** + * Destructor + * + */ +AccessBridgeJavaEntryPoints::~AccessBridgeJavaEntryPoints() { +} + +// ----------------------------------- + +#define FIND_CLASS(classRef, className) \ + localClassRef = jniEnv->FindClass(className); \ + if (localClassRef == (jclass) 0) { \ + PrintDebugString(" Error! FindClass(%s) failed!", className); \ + PrintDebugString(" -> jniEnv = %p", jniEnv); \ + return FALSE; \ + } \ + classRef = (jclass) jniEnv->NewGlobalRef(localClassRef); \ + jniEnv->DeleteLocalRef(localClassRef); \ + if (classRef == (jclass) 0) { \ + PrintDebugString(" Error! FindClass(%s) failed!", className); \ + PrintDebugString(" -> (ran out of RAM)"); \ + return FALSE; \ + } + + +#define FIND_METHOD(methodID, classRef, methodString, methodSignature); \ + methodID = jniEnv->GetMethodID(classRef, methodString, methodSignature); \ + if (methodID == (jmethodID) 0) { \ + PrintDebugString(" Error! GetMethodID(%s) failed!", methodString); \ + PrintDebugString(" -> jniEnv = %p; classRef = %p", jniEnv, classRef); \ + return FALSE; \ + } + +#define EXCEPTION_CHECK(situationDescription, returnVal) \ + if (exception = jniEnv->ExceptionOccurred()) { \ + PrintDebugString("\r\n *** Exception occured while doing: %s; returning %d", situationDescription, returnVal); \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + return (returnVal); \ + } + +#define EXCEPTION_CHECK_VOID(situationDescription) \ + if (exception = jniEnv->ExceptionOccurred()) { \ + PrintDebugString("\r\n *** Exception occured while doing: %s", situationDescription); \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + return; \ + } + +/** + * Make all of the getClass() & getMethod() calls + * + */ +BOOL +AccessBridgeJavaEntryPoints::BuildJavaEntryPoints() { + jclass localClassRef; + + PrintDebugString("Calling BuildJavaEntryPoints():"); + + FIND_CLASS(bridgeClass, "com/sun/java/accessibility/AccessBridge"); + + // ------- general methods + + // GetMethodID(decrementReference) + FIND_METHOD(decrementReferenceMethod, bridgeClass, + "decrementReference", + "(Ljava/lang/Object;)V"); + + // GetMethodID(getJavaVersionPropertyMethod) + FIND_METHOD(getJavaVersionPropertyMethod, bridgeClass, + "getJavaVersionProperty", + "()Ljava/lang/String;"); + + // GetMethodID(getAccessBridgeVersionMethod) + FIND_METHOD(getAccessBridgeVersionMethod, bridgeClass, + "getAccessBridgeVersion", + "()Ljava/lang/String;"); + + + // ------- Window methods + + // GetMethodID(isJavaWindow) + FIND_METHOD(isJavaWindowMethod, bridgeClass, + "isJavaWindow", + "(I)Z"); + + // GetMethodID(getAccessibleContextFromHWND) + FIND_METHOD(getAccessibleContextFromHWNDMethod, bridgeClass, + "getContextFromNativeWindowHandle", + "(I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getHWNDFromAccessibleContext) + FIND_METHOD(getHWNDFromAccessibleContextMethod, bridgeClass, + "getNativeWindowHandleFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleParentFromContext) + FIND_METHOD(getAccessibleParentFromContextMethod, bridgeClass, + "getAccessibleParentFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;"); + + // ===== utility methods ===== */ + + // GetMethodID(setTextContents) + FIND_METHOD(setTextContentsMethod, bridgeClass, + "setTextContents", + "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Z"); + + // GetMethodID(getParentWithRole) + FIND_METHOD(getParentWithRoleMethod, bridgeClass, + "getParentWithRole", + "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getTopLevelObject) + FIND_METHOD(getTopLevelObjectMethod, bridgeClass, + "getTopLevelObject", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getParentWithRoleElseRoot) + FIND_METHOD(getParentWithRoleElseRootMethod, bridgeClass, + "getParentWithRoleElseRoot", + "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getObjectDepth) + FIND_METHOD(getObjectDepthMethod, bridgeClass, + "getObjectDepth", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getActiveDescendent) + FIND_METHOD(getActiveDescendentMethod, bridgeClass, + "getActiveDescendent", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;"); + + // ------- AccessibleContext methods + + // GetMethodID(getAccessibleContextAt) + FIND_METHOD(getAccessibleContextAtMethod, bridgeClass, + "getAccessibleContextAt", + "(IILjavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleContextWithFocus) + FIND_METHOD(getAccessibleContextWithFocusMethod, bridgeClass, + "getAccessibleContextWithFocus", + "()Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleNameFromContext) + FIND_METHOD(getAccessibleNameFromContextMethod, bridgeClass, + "getAccessibleNameFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleDescriptionFromContext) + FIND_METHOD(getAccessibleDescriptionFromContextMethod, bridgeClass, + "getAccessibleDescriptionFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleRoleStringFromContext) + FIND_METHOD(getAccessibleRoleStringFromContextMethod, bridgeClass, + "getAccessibleRoleStringFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleRoleStringFromContext_en_US) + FIND_METHOD(getAccessibleRoleStringFromContext_en_USMethod, bridgeClass, + "getAccessibleRoleStringFromContext_en_US", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleStatesStringFromContext) + FIND_METHOD(getAccessibleStatesStringFromContextMethod, bridgeClass, + "getAccessibleStatesStringFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleStatesStringFromContext_en_US) + FIND_METHOD(getAccessibleStatesStringFromContext_en_USMethod, bridgeClass, + "getAccessibleStatesStringFromContext_en_US", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleParentFromContext) + FIND_METHOD(getAccessibleParentFromContextMethod, bridgeClass, + "getAccessibleParentFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleIndexInParentFromContext) + FIND_METHOD(getAccessibleIndexInParentFromContextMethod, bridgeClass, + "getAccessibleIndexInParentFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleChildrenCountFromContext) + FIND_METHOD(getAccessibleChildrenCountFromContextMethod, bridgeClass, + "getAccessibleChildrenCountFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleChildFromContext) + FIND_METHOD(getAccessibleChildFromContextMethod, bridgeClass, + "getAccessibleChildFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleBoundsOnScreenFromContext) + FIND_METHOD(getAccessibleBoundsOnScreenFromContextMethod, bridgeClass, + "getAccessibleBoundsOnScreenFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/awt/Rectangle;"); + + // GetMethodID(getAccessibleXcoordFromContext) + FIND_METHOD(getAccessibleXcoordFromContextMethod, bridgeClass, + "getAccessibleXcoordFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleYcoordFromContext) + FIND_METHOD(getAccessibleYcoordFromContextMethod, bridgeClass, + "getAccessibleYcoordFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleHeightFromContext) + FIND_METHOD(getAccessibleHeightFromContextMethod, bridgeClass, + "getAccessibleHeightFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleWidthFromContext) + FIND_METHOD(getAccessibleWidthFromContextMethod, bridgeClass, + "getAccessibleWidthFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleComponentFromContext) + FIND_METHOD(getAccessibleComponentFromContextMethod, bridgeClass, + "getAccessibleComponentFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleComponent;"); + + // GetMethodID(getAccessibleActionFromContext) + FIND_METHOD(getAccessibleActionFromContextMethod, bridgeClass, + "getAccessibleActionFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleAction;"); + + // GetMethodID(getAccessibleSelectionFromContext) + FIND_METHOD(getAccessibleSelectionFromContextMethod, bridgeClass, + "getAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleSelection;"); + + // GetMethodID(getAccessibleTextFromContext) + FIND_METHOD(getAccessibleTextFromContextMethod, bridgeClass, + "getAccessibleTextFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleText;"); + + // GetMethodID(getAccessibleValueFromContext) + FIND_METHOD(getAccessibleValueFromContextMethod, bridgeClass, + "getAccessibleValueFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleValue;"); + + + // ------- begin AccessibleTable methods + + // GetMethodID(getAccessibleTableFromContext) + FIND_METHOD(getAccessibleTableFromContextMethod, bridgeClass, + "getAccessibleTableFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleTable;"); + + // GetMethodID(getContextFromAccessibleTable) + FIND_METHOD(getContextFromAccessibleTableMethod, bridgeClass, + "getContextFromAccessibleTable", + "(Ljavax/accessibility/AccessibleTable;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleTableRowHeader) + FIND_METHOD(getAccessibleTableRowHeaderMethod, bridgeClass, + "getAccessibleTableRowHeader", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleTable;"); + + + // GetMethodID(getAccessibleTableColumnHeader) + FIND_METHOD(getAccessibleTableColumnHeaderMethod, bridgeClass, + "getAccessibleTableColumnHeader", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleTable;"); + + + // GetMethodID(getAccessibleTableRowCount) + FIND_METHOD(getAccessibleTableRowCountMethod, bridgeClass, + "getAccessibleTableRowCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableColumnCount) + FIND_METHOD(getAccessibleTableColumnCountMethod, bridgeClass, + "getAccessibleTableColumnCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableCellAccessibleContext) + FIND_METHOD(getAccessibleTableCellAccessibleContextMethod, bridgeClass, + "getAccessibleTableCellAccessibleContext", + "(Ljavax/accessibility/AccessibleTable;II)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleTableCellIndex) + FIND_METHOD(getAccessibleTableCellIndexMethod, bridgeClass, + "getAccessibleTableCellIndex", + "(Ljavax/accessibility/AccessibleTable;II)I"); + + // GetMethodID(getAccessibleTableCellRowExtent) + FIND_METHOD(getAccessibleTableCellRowExtentMethod, bridgeClass, + "getAccessibleTableCellRowExtent", + "(Ljavax/accessibility/AccessibleTable;II)I"); + + // GetMethodID(getAccessibleTableCellColumnExtent) + FIND_METHOD(getAccessibleTableCellColumnExtentMethod, bridgeClass, + "getAccessibleTableCellColumnExtent", + "(Ljavax/accessibility/AccessibleTable;II)I"); + + // GetMethodID(isAccessibleTableCellSelected) + FIND_METHOD(isAccessibleTableCellSelectedMethod, bridgeClass, + "isAccessibleTableCellSelected", + "(Ljavax/accessibility/AccessibleTable;II)Z"); + + // GetMethodID(getAccessibleTableRowHeaderRowCount) + FIND_METHOD(getAccessibleTableRowHeaderRowCountMethod, bridgeClass, + "getAccessibleTableRowHeaderRowCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableColumnHeaderRowCount) + FIND_METHOD(getAccessibleTableColumnHeaderRowCountMethod, bridgeClass, + "getAccessibleTableColumnHeaderRowCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableRowHeaderColumnCount) + FIND_METHOD(getAccessibleTableRowHeaderColumnCountMethod, bridgeClass, + "getAccessibleTableRowHeaderColumnCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableColumnHeaderColumnCount) + FIND_METHOD(getAccessibleTableColumnHeaderColumnCountMethod, bridgeClass, + "getAccessibleTableColumnHeaderColumnCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableRowDescription) + FIND_METHOD(getAccessibleTableRowDescriptionMethod, bridgeClass, + "getAccessibleTableRowDescription", + "(Ljavax/accessibility/AccessibleTable;I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleTableColumnDescription) + FIND_METHOD(getAccessibleTableColumnDescriptionMethod, bridgeClass, + "getAccessibleTableColumnDescription", + "(Ljavax/accessibility/AccessibleTable;I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleTableRowSelectionCount) + FIND_METHOD(getAccessibleTableRowSelectionCountMethod, bridgeClass, + "getAccessibleTableRowSelectionCount", + "(Ljavax/accessibility/AccessibleTable;)I"); + + // GetMethodID(isAccessibleTableRowSelected) + FIND_METHOD(isAccessibleTableRowSelectedMethod, bridgeClass, + "isAccessibleTableRowSelected", + "(Ljavax/accessibility/AccessibleTable;I)Z"); + + // GetMethodID(getAccessibleTableRowSelections) + FIND_METHOD(getAccessibleTableRowSelectionsMethod, bridgeClass, + "getAccessibleTableRowSelections", + "(Ljavax/accessibility/AccessibleTable;I)I"); + + // GetMethodID(getAccessibleTableColumnSelectionCount) + FIND_METHOD(getAccessibleTableColumnSelectionCountMethod, bridgeClass, + "getAccessibleTableColumnSelectionCount", + "(Ljavax/accessibility/AccessibleTable;)I"); + + // GetMethodID(isAccessibleTableColumnSelected) + FIND_METHOD(isAccessibleTableColumnSelectedMethod, bridgeClass, + "isAccessibleTableColumnSelected", + "(Ljavax/accessibility/AccessibleTable;I)Z"); + + // GetMethodID(getAccessibleTableColumnSelections) + FIND_METHOD(getAccessibleTableColumnSelectionsMethod, bridgeClass, + "getAccessibleTableColumnSelections", + "(Ljavax/accessibility/AccessibleTable;I)I"); + + // GetMethodID(getAccessibleTableRow) + FIND_METHOD(getAccessibleTableRowMethod, bridgeClass, + "getAccessibleTableRow", + "(Ljavax/accessibility/AccessibleTable;I)I"); + + // GetMethodID(getAccessibleTableColumn) + FIND_METHOD(getAccessibleTableColumnMethod, bridgeClass, + "getAccessibleTableColumn", + "(Ljavax/accessibility/AccessibleTable;I)I"); + + // GetMethodID(getAccessibleTableIndex) + FIND_METHOD(getAccessibleTableIndexMethod, bridgeClass, + "getAccessibleTableIndex", + "(Ljavax/accessibility/AccessibleTable;II)I"); + + /* ------- end AccessibleTable methods */ + + /* start AccessibleRelationSet methods ----- */ + + // GetMethodID(getAccessibleRelationCount) + FIND_METHOD(getAccessibleRelationCountMethod, bridgeClass, + "getAccessibleRelationCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleRelationKey) + FIND_METHOD(getAccessibleRelationKeyMethod, bridgeClass, + "getAccessibleRelationKey", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleRelationTargetCount) + FIND_METHOD(getAccessibleRelationTargetCountMethod, bridgeClass, + "getAccessibleRelationTargetCount", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleRelationTarget) + FIND_METHOD(getAccessibleRelationTargetMethod, bridgeClass, + "getAccessibleRelationTarget", + "(Ljavax/accessibility/AccessibleContext;II)Ljavax/accessibility/AccessibleContext;"); + + + // ------- AccessibleHypertext methods + + // GetMethodID(getAccessibleHypertext) + FIND_METHOD(getAccessibleHypertextMethod, bridgeClass, + "getAccessibleHypertext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleHypertext;"); + + // GetMethodID(activateAccessibleHyperlink) + FIND_METHOD(activateAccessibleHyperlinkMethod, bridgeClass, + "activateAccessibleHyperlink", + "(Ljavax/accessibility/AccessibleContext;Ljavax/accessibility/AccessibleHyperlink;)Z"); + + // GetMethodID(getAccessibleHyperlinkCount) + FIND_METHOD(getAccessibleHyperlinkCountMethod, bridgeClass, + "getAccessibleHyperlinkCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleHyperlink) + FIND_METHOD(getAccessibleHyperlinkMethod, bridgeClass, + "getAccessibleHyperlink", + "(Ljavax/accessibility/AccessibleHypertext;I)Ljavax/accessibility/AccessibleHyperlink;"); + + // GetMethodID(getAccessibleHyperlinkText) + FIND_METHOD(getAccessibleHyperlinkTextMethod, bridgeClass, + "getAccessibleHyperlinkText", + "(Ljavax/accessibility/AccessibleHyperlink;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleHyperlinkURL) + FIND_METHOD(getAccessibleHyperlinkURLMethod, bridgeClass, + "getAccessibleHyperlinkURL", + "(Ljavax/accessibility/AccessibleHyperlink;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleHyperlinkStartIndex) + FIND_METHOD(getAccessibleHyperlinkStartIndexMethod, bridgeClass, + "getAccessibleHyperlinkStartIndex", + "(Ljavax/accessibility/AccessibleHyperlink;)I"); + + // GetMethodID(getAccessibleHyperlinkEndIndex) + FIND_METHOD(getAccessibleHyperlinkEndIndexMethod, bridgeClass, + "getAccessibleHyperlinkEndIndex", + "(Ljavax/accessibility/AccessibleHyperlink;)I"); + + // GetMethodID(getAccessibleHypertextLinkIndex) + FIND_METHOD(getAccessibleHypertextLinkIndexMethod, bridgeClass, + "getAccessibleHypertextLinkIndex", + "(Ljavax/accessibility/AccessibleHypertext;I)I"); + + // Accessible KeyBinding, Icon and Action ==================== + + // GetMethodID(getAccessibleKeyBindingsCount) + FIND_METHOD(getAccessibleKeyBindingsCountMethod, bridgeClass, + "getAccessibleKeyBindingsCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleKeyBindingChar) + FIND_METHOD(getAccessibleKeyBindingCharMethod, bridgeClass, + "getAccessibleKeyBindingChar", + "(Ljavax/accessibility/AccessibleContext;I)C"); + + // GetMethodID(getAccessibleKeyBindingModifiers) + FIND_METHOD(getAccessibleKeyBindingModifiersMethod, bridgeClass, + "getAccessibleKeyBindingModifiers", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleIconsCount) + FIND_METHOD(getAccessibleIconsCountMethod, bridgeClass, + "getAccessibleIconsCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleIconDescription) + FIND_METHOD(getAccessibleIconDescriptionMethod, bridgeClass, + "getAccessibleIconDescription", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleIconHeight) + FIND_METHOD(getAccessibleIconHeightMethod, bridgeClass, + "getAccessibleIconHeight", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleIconWidth) + FIND_METHOD(getAccessibleIconWidthMethod, bridgeClass, + "getAccessibleIconWidth", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleActionsCount) + FIND_METHOD(getAccessibleActionsCountMethod, bridgeClass, + "getAccessibleActionsCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleActionName) + FIND_METHOD(getAccessibleActionNameMethod, bridgeClass, + "getAccessibleActionName", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(doAccessibleActions) + FIND_METHOD(doAccessibleActionsMethod, bridgeClass, + "doAccessibleActions", + "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Z"); + + // ------- AccessibleText methods + + // GetMethodID(getAccessibleCharCountFromContext) + FIND_METHOD(getAccessibleCharCountFromContextMethod, bridgeClass, + "getAccessibleCharCountFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleCaretPositionFromContext) + FIND_METHOD(getAccessibleCaretPositionFromContextMethod, bridgeClass, + "getAccessibleCaretPositionFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleIndexAtPointFromContext) + FIND_METHOD(getAccessibleIndexAtPointFromContextMethod, bridgeClass, + "getAccessibleIndexAtPointFromContext", + "(Ljavax/accessibility/AccessibleContext;II)I"); + + // GetMethodID(getAccessibleLetterAtIndexFromContext) + FIND_METHOD(getAccessibleLetterAtIndexFromContextMethod, bridgeClass, + "getAccessibleLetterAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleWordAtIndexFromContext) + FIND_METHOD(getAccessibleWordAtIndexFromContextMethod, bridgeClass, + "getAccessibleWordAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleSentenceAtIndexFromContext) + FIND_METHOD(getAccessibleSentenceAtIndexFromContextMethod, bridgeClass, + "getAccessibleSentenceAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleTextSelectionStartFromContext) + FIND_METHOD(getAccessibleTextSelectionStartFromContextMethod, bridgeClass, + "getAccessibleTextSelectionStartFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTextSelectionEndFromContext) + FIND_METHOD(getAccessibleTextSelectionEndFromContextMethod, bridgeClass, + "getAccessibleTextSelectionEndFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTextSelectedTextFromContext) + FIND_METHOD(getAccessibleTextSelectedTextFromContextMethod, bridgeClass, + "getAccessibleTextSelectedTextFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleAttributesAtIndexFromContext) + FIND_METHOD(getAccessibleAttributesAtIndexFromContextMethod, bridgeClass, + "getAccessibleAttributesAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleAttributeSetAtIndexFromContext) + FIND_METHOD(getAccessibleAttributeSetAtIndexFromContextMethod, bridgeClass, + "getAccessibleAttributeSetAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljavax/swing/text/AttributeSet;"); + + // GetMethodID(getAccessibleTextRectAtIndexFromContext) + FIND_METHOD(getAccessibleTextRectAtIndexFromContextMethod, bridgeClass, + "getAccessibleTextRectAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/awt/Rectangle;"); + + // GetMethodID(getAccessibleXcoordTextRectAtIndexFromContext) + FIND_METHOD(getAccessibleXcoordTextRectAtIndexFromContextMethod, bridgeClass, + "getAccessibleXcoordTextRectAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleYcoordTextRectAtIndexFromContext) + FIND_METHOD(getAccessibleYcoordTextRectAtIndexFromContextMethod, bridgeClass, + "getAccessibleYcoordTextRectAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleHeightTextRectAtIndexFromContext) + FIND_METHOD(getAccessibleHeightTextRectAtIndexFromContextMethod, bridgeClass, + "getAccessibleHeightTextRectAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleWidthTextRectAtIndexFromContext) + FIND_METHOD(getAccessibleWidthTextRectAtIndexFromContextMethod, bridgeClass, + "getAccessibleWidthTextRectAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getCaretLocationX) + FIND_METHOD(getCaretLocationXMethod, bridgeClass, + "getCaretLocationX", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getCaretLocationY) + FIND_METHOD(getCaretLocationYMethod, bridgeClass, + "getCaretLocationY", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getCaretLocationHeight) + FIND_METHOD(getCaretLocationHeightMethod, bridgeClass, + "getCaretLocationHeight", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getCaretLocationWidth) + FIND_METHOD(getCaretLocationWidthMethod, bridgeClass, + "getCaretLocationWidth", + "(Ljavax/accessibility/AccessibleContext;)I"); + + + // GetMethodID(getAccessibleTextLineLeftBoundsFromContextMethod) + FIND_METHOD(getAccessibleTextLineLeftBoundsFromContextMethod, bridgeClass, + "getAccessibleTextLineLeftBoundsFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleTextLineRightBoundsFromContextMethod) + FIND_METHOD(getAccessibleTextLineRightBoundsFromContextMethod, bridgeClass, + "getAccessibleTextLineRightBoundsFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleTextRangeFromContextMethod) + FIND_METHOD(getAccessibleTextRangeFromContextMethod, bridgeClass, + "getAccessibleTextRangeFromContext", + "(Ljavax/accessibility/AccessibleContext;II)Ljava/lang/String;"); + + + // ------- AccessibleValue methods + + // GetMethodID(getCurrentAccessibleValueFromContext) + FIND_METHOD(getCurrentAccessibleValueFromContextMethod, bridgeClass, + "getCurrentAccessibleValueFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getMaximumAccessibleValueFromContext) + FIND_METHOD(getMaximumAccessibleValueFromContextMethod, bridgeClass, + "getMaximumAccessibleValueFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getMinimumAccessibleValueFromContext) + FIND_METHOD(getMinimumAccessibleValueFromContextMethod, bridgeClass, + "getMinimumAccessibleValueFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + + // ------- AccessibleSelection methods + + // GetMethodID(addAccessibleSelectionFromContext) + FIND_METHOD(addAccessibleSelectionFromContextMethod, bridgeClass, + "addAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;I)V"); + + // GetMethodID(clearAccessibleSelectionFromContext) + FIND_METHOD(clearAccessibleSelectionFromContextMethod, bridgeClass, + "clearAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;)V"); + + // GetMethodID(getAccessibleSelectionFromContext) + FIND_METHOD(getAccessibleSelectionContextFromContextMethod, bridgeClass, + "getAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleSelectionCountFromContext) + FIND_METHOD(getAccessibleSelectionCountFromContextMethod, bridgeClass, + "getAccessibleSelectionCountFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(isAccessibleChildSelectedFromContext) + FIND_METHOD(isAccessibleChildSelectedFromContextMethod, bridgeClass, + "isAccessibleChildSelectedFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Z"); + + // GetMethodID(removeAccessibleSelectionFromContext) + FIND_METHOD(removeAccessibleSelectionFromContextMethod, bridgeClass, + "removeAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;I)V"); + + // GetMethodID(selectAllAccessibleSelectionFromContext) + FIND_METHOD(selectAllAccessibleSelectionFromContextMethod, bridgeClass, + "selectAllAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;)V"); + + + // ------- Event Notification methods + + // GetMethodID(addJavaEventNotification) + FIND_METHOD(addJavaEventNotificationMethod, bridgeClass, + "addJavaEventNotification", "(J)V"); + + // GetMethodID(removeJavaEventNotification) + FIND_METHOD(removeJavaEventNotificationMethod, bridgeClass, + "removeJavaEventNotification", "(J)V"); + + // GetMethodID(addAccessibilityEventNotification) + FIND_METHOD(addAccessibilityEventNotificationMethod, bridgeClass, + "addAccessibilityEventNotification", "(J)V"); + + // GetMethodID(removeAccessibilityEventNotification) + FIND_METHOD(removeAccessibilityEventNotificationMethod, bridgeClass, + "removeAccessibilityEventNotification", "(J)V"); + + + // ------- AttributeSet methods + + // GetMethodID(getBoldFromAttributeSet) + FIND_METHOD(getBoldFromAttributeSetMethod, bridgeClass, + "getBoldFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getItalicFromAttributeSet) + FIND_METHOD(getItalicFromAttributeSetMethod, bridgeClass, + "getItalicFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getUnderlineFromAttributeSet) + FIND_METHOD(getUnderlineFromAttributeSetMethod, bridgeClass, + "getUnderlineFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getStrikethroughFromAttributeSet) + FIND_METHOD(getStrikethroughFromAttributeSetMethod, bridgeClass, + "getStrikethroughFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getSuperscriptFromAttributeSet) + FIND_METHOD(getSuperscriptFromAttributeSetMethod, bridgeClass, + "getSuperscriptFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getSubscriptFromAttributeSet) + FIND_METHOD(getSubscriptFromAttributeSetMethod, bridgeClass, + "getSubscriptFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getBackgroundColorFromAttributeSet) + FIND_METHOD(getBackgroundColorFromAttributeSetMethod, bridgeClass, + "getBackgroundColorFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Ljava/lang/String;"); + + // GetMethodID(getForegroundColorFromAttributeSet) + FIND_METHOD(getForegroundColorFromAttributeSetMethod, bridgeClass, + "getForegroundColorFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Ljava/lang/String;"); + + // GetMethodID(getFontFamilyFromAttributeSet) + FIND_METHOD(getFontFamilyFromAttributeSetMethod, bridgeClass, + "getFontFamilyFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Ljava/lang/String;"); + + // GetMethodID(getFontSizeFromAttributeSet) + FIND_METHOD(getFontSizeFromAttributeSetMethod, bridgeClass, + "getFontSizeFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)I"); + + // GetMethodID(getAlignmentFromAttributeSet) + FIND_METHOD(getAlignmentFromAttributeSetMethod, bridgeClass, + "getAlignmentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)I"); + + // GetMethodID(getBidiLevelFromAttributeSet) + FIND_METHOD(getBidiLevelFromAttributeSetMethod, bridgeClass, + "getBidiLevelFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)I"); + + // GetMethodID(getFirstLineIndentFromAttributeSet) + FIND_METHOD(getFirstLineIndentFromAttributeSetMethod, bridgeClass, + "getFirstLineIndentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + // GetMethodID(getLeftIndentFromAttributeSet) + FIND_METHOD(getLeftIndentFromAttributeSetMethod, bridgeClass, + "getLeftIndentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + // GetMethodID(getRightIndentFromAttributeSet) + FIND_METHOD(getRightIndentFromAttributeSetMethod, bridgeClass, + "getRightIndentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + // GetMethodID(getLineSpacingFromAttributeSet) + FIND_METHOD(getLineSpacingFromAttributeSetMethod, bridgeClass, + "getLineSpacingFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + // GetMethodID(getSpaceAboveFromAttributeSet) + FIND_METHOD(getSpaceAboveFromAttributeSetMethod, bridgeClass, + "getSpaceAboveFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + // GetMethodID(getSpaceBelowFromAttributeSet) + FIND_METHOD(getSpaceBelowFromAttributeSetMethod, bridgeClass, + "getSpaceBelowFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + + /** + * Additional methods for Teton + */ + + // GetMethodID(requestFocus) + FIND_METHOD(requestFocusMethod, bridgeClass, + "requestFocus", + "(Ljavax/accessibility/AccessibleContext;)Z"); + + // GetMethodID(selectTextRange) + FIND_METHOD(selectTextRangeMethod, bridgeClass, + "selectTextRange", + "(Ljavax/accessibility/AccessibleContext;II)Z"); + + // GetMethodID(getVisibleChildrenCount) + FIND_METHOD(getVisibleChildrenCountMethod, bridgeClass, + "getVisibleChildrenCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getVisibleChild) + FIND_METHOD(getVisibleChildMethod, bridgeClass, + "getVisibleChild", + "(Ljavax/accessibility/AccessibleContext;I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(setCaretPosition) + FIND_METHOD(setCaretPositionMethod, bridgeClass, + "setCaretPosition", + "(Ljavax/accessibility/AccessibleContext;I)Z"); + + // GetMethodID(getVirtualAccessibleNameFromContextMethod) Ben Key + FIND_METHOD(getVirtualAccessibleNameFromContextMethod, bridgeClass, + "getVirtualAccessibleNameFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + return TRUE; +} + +// Note for the following code which makes JNI upcalls... +// +// Problem, bug DB 16818166, JBS DB JDK-8015400 +// AccessibleContext is a JOBJECT64 which is a jobject (32 bit pointer) +// for a Legacy (XP) build and a jlong (64 bits) for a -32 or -64 build. +// For the -32 build the lower 32 bits needs to be extracted into a jobject. +// Otherwise, if AccessibleContext is used directly what happens is that +// the JNI code consumes the lower 32 of its 64 bits and that is not a +// problem, but then when the JNI code consumes the next 32 bits for the +// reference to the role String it gets the higher 0x00000000 bits from +// the 64 bit JOBJECT64 AccessibleContext variable and thus a null reference +// is passed as the String reference. +// +// Solution: +// Cast the JOBJECT64 to a jobject. For a 64 bit compile this is basically +// a noop, i.e. JOBJECT64 is a 64 bit jlong and a jobject is a 64 bit reference. +// For a 32 bit compile the cast drops the high order 32 bits, i.e. JOBJECT64 +// is a 64 bit jlong and jobject is a 32 bit reference. For a Legacy build +// JOBJECT64 is a jobject so this is also basically a noop. The casts are +// done in the methods in JavaAccessBridge::processPackage. + +// ----------------------------------- + +/** + * isJavaWindow - returns whether the HWND is a Java window or not + * + */ +BOOL +AccessBridgeJavaEntryPoints::isJavaWindow(jint window) { + jthrowable exception; + BOOL returnVal; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::isJavaWindow(%X):", window); + + if (isJavaWindowMethod != (jmethodID) 0) { + returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, isJavaWindowMethod, window); + EXCEPTION_CHECK("Getting isJavaWindow - call to CallBooleanMethod()", FALSE); + return returnVal; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or isJavaWindowMethod == 0"); + return FALSE; + } +} + +// ----------------------------------- + +/** + * isSameObject - returns whether two object reference refer to the same object + * + */ +BOOL +AccessBridgeJavaEntryPoints::isSameObject(jobject obj1, jobject obj2) { + jthrowable exception; + BOOL returnVal; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::isSameObject(%p %p):", obj1, obj2); + + returnVal = (BOOL) jniEnv->IsSameObject((jobject)obj1, (jobject)obj2); + EXCEPTION_CHECK("Calling IsSameObject", FALSE); + + PrintDebugString("\r\n isSameObject returning %d", returnVal); + return returnVal; +} + +// ----------------------------------- + +/** + * getAccessibleContextFromHWND - returns the AccessibleContext, if any, for an HWND + * + */ +jobject +AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(jint window) { + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(%X):", window); + + if (getAccessibleContextFromHWNDMethod != (jmethodID) 0) { + returnedAccessibleContext = + (jobject)jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleContextFromHWNDMethod, + window); + EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0); + globalRef = (jobject)jniEnv->NewGlobalRef((jobject)returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0); + return globalRef; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getAccessibleContextFromHWNDMethod == 0"); + return (jobject) 0; + } +} + +// ----------------------------------- + +/** + * getHWNDFromAccessibleContext - returns the HWND for an AccessibleContext, if any + * returns (HWND)0 on error. + */ +HWND +AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(jobject accessibleContext) { + jthrowable exception; + HWND rHWND; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(%X):", + accessibleContext); + + if (getHWNDFromAccessibleContextMethod != (jmethodID) 0) { + rHWND = (HWND)jniEnv->CallIntMethod(accessBridgeObject, getHWNDFromAccessibleContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting HWNDFromAccessibleContext - call to CallIntMethod()", (HWND)0); + PrintDebugString("\r\n rHWND = %X", rHWND); + return rHWND; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getHWNDFromAccessibleContextMethod == 0"); + return (HWND)0; + } +} + + +/* ====== Utility methods ===== */ + +/** + * Sets a text field to the specified string. Returns whether successful; + */ +BOOL +AccessBridgeJavaEntryPoints::setTextContents(const jobject accessibleContext, const wchar_t *text) { + jthrowable exception; + BOOL result = FALSE; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::setTextContents(%p, %ls):", + accessibleContext, text); + + if (setTextContentsMethod != (jmethodID) 0) { + + // create a Java String for the text + jstring textString = jniEnv->NewString(text, (jsize)wcslen(text)); + if (textString == 0) { + PrintDebugString("\r NewString failed"); + return FALSE; + } + + result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, + setTextContentsMethod, + accessibleContext, textString); + EXCEPTION_CHECK("setTextContents - call to CallBooleanMethod()", FALSE); + PrintDebugString("\r\n result = %d", result); + return result; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or setTextContentsMethod == 0"); + return result; + } +} + +/** + * Returns the Accessible Context of a Page Tab object that is the + * ancestor of a given object. If the object is a Page Tab object + * or a Page Tab ancestor object was found, returns the object + * AccessibleContext. + * If there is no ancestor object that has an Accessible Role of Page Tab, + * returns (AccessibleContext)0. + */ +jobject +AccessBridgeJavaEntryPoints::getParentWithRole(const jobject accessibleContext, const wchar_t *role) { + jthrowable exception; + jobject rAccessibleContext; + + PrintDebugString("In AccessBridgeJavaEntryPoints::getParentWithRole(%p):", + accessibleContext); + + if (getParentWithRoleMethod != (jmethodID) 0) { + // create a Java String for the role + jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role)); + if (roleName == 0) { + PrintDebugString(" NewString failed"); + return FALSE; + } + + rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getParentWithRoleMethod, + accessibleContext, roleName); + EXCEPTION_CHECK("Getting ParentWithRole - call to CallObjectMethod()", (AccessibleContext)0); + PrintDebugString(" rAccessibleContext = %p", rAccessibleContext); + jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); + EXCEPTION_CHECK("Getting ParentWithRole - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + rAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getParentWithRoleMethod == 0"); + return 0; + } +} + +/** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ +jobject +AccessBridgeJavaEntryPoints::getTopLevelObject(const jobject accessibleContext) { + jthrowable exception; + jobject rAccessibleContext; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getTopLevelObject(%p):", + accessibleContext); + + if (getTopLevelObjectMethod != (jmethodID) 0) { + rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getTopLevelObjectMethod, + accessibleContext); + EXCEPTION_CHECK("Getting TopLevelObject - call to CallObjectMethod()", FALSE); + PrintDebugString("\r\n rAccessibleContext = %p", rAccessibleContext); + jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); + EXCEPTION_CHECK("Getting TopLevelObject - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + rAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getTopLevelObjectMethod == 0"); + return 0; + } +} + +/** + * If there is an Ancestor object that has an Accessible Role of + * Internal Frame, returns the Accessible Context of the Internal + * Frame object. Otherwise, returns the top level object for that + * Java Window. Returns (AccessibleContext)0 on error. + */ +jobject +AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(const jobject accessibleContext, const wchar_t *role) { + jthrowable exception; + jobject rAccessibleContext; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(%p):", + accessibleContext); + + if (getParentWithRoleElseRootMethod != (jmethodID) 0) { + + // create a Java String for the role + jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role)); + if (roleName == 0) { + PrintDebugString("\r NewString failed"); + return FALSE; + } + + rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getParentWithRoleElseRootMethod, + accessibleContext, roleName); + EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to CallObjectMethod()", (AccessibleContext)0); + PrintDebugString(" rAccessibleContext = %p", rAccessibleContext); + jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); + EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + rAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getParentWithRoleElseRootMethod == 0"); + return 0; + } +} + +/** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ +jint +AccessBridgeJavaEntryPoints::getObjectDepth(const jobject accessibleContext) { + jthrowable exception; + jint rResult; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getObjectDepth(%p):", + accessibleContext); + + if (getObjectDepthMethod != (jmethodID) 0) { + rResult = jniEnv->CallIntMethod(accessBridgeObject, + getObjectDepthMethod, + accessibleContext); + EXCEPTION_CHECK("Getting ObjectDepth - call to CallIntMethod()", -1); + PrintDebugString("\r\n rResult = %d", rResult); + return rResult; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getObjectDepthMethod == 0"); + return -1; + } +} + + + +/** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * Returns 0 on error. + */ +jobject +AccessBridgeJavaEntryPoints::getActiveDescendent(const jobject accessibleContext) { + jthrowable exception; + jobject rAccessibleContext; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getActiveDescendent(%p):", + accessibleContext); + + if (getActiveDescendentMethod != (jmethodID) 0) { + rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getActiveDescendentMethod, + accessibleContext); + EXCEPTION_CHECK("Getting ActiveDescendent - call to CallObjectMethod()", (AccessibleContext)0); + PrintDebugString("\r\n rAccessibleContext = %p", rAccessibleContext); + jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); + EXCEPTION_CHECK("Getting ActiveDescendant - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + rAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getActiveDescendentMethod == 0"); + return (AccessibleContext)0; + } +} + +/** + * Additional methods for Teton + */ + +/** + * Returns an AccessibleName for a component using an algorithm optimized + * for the JAWS screen reader by Ben Key (Freedom Scientific). This method + * is only intended for JAWS. All other uses are entirely optional. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ +BOOL +AccessBridgeJavaEntryPoints::getVirtualAccessibleName ( + IN const jobject object, + OUT wchar_t * name, + IN const int nameSize) +{ + /* + + + Parameter validation + + + */ + if ((name == 0) || (nameSize == 0)) + { + return FALSE; + } + ::memset (name, 0, nameSize * sizeof (wchar_t)); + if (0 == object) + { + return FALSE; + } + + jstring js = NULL; + const wchar_t * stringBytes = NULL; + jthrowable exception = NULL; + jsize length = 0; + PrintDebugString("\r\n getVirtualAccessibleName called."); + if (getVirtualAccessibleNameFromContextMethod != (jmethodID) 0) + { + js = (jstring) jniEnv->CallObjectMethod ( + accessBridgeObject, + getVirtualAccessibleNameFromContextMethod, + object); + EXCEPTION_CHECK("Getting AccessibleName - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) + { + stringBytes = (const wchar_t *) jniEnv->GetStringChars (js, 0); + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); + wcsncpy(name, stringBytes, nameSize - 1); + length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod ( + accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Name = %ls", name); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE); + } + else + { + PrintDebugString(" Accessible Name is null."); + } + } + else + { + PrintDebugString("\r\n Error! either jniEnv == 0 or getVirtualAccessibleNameFromContextMethod == 0"); + return FALSE; + } + if ( 0 != name [0] ) + { + return TRUE; + } + return FALSE; +} + + +/** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ +BOOL +AccessBridgeJavaEntryPoints::requestFocus(const jobject accessibleContext) { + + jthrowable exception; + BOOL result = FALSE; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::requestFocus(%p):", + accessibleContext); + + if (requestFocusMethod != (jmethodID) 0) { + result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, + requestFocusMethod, + accessibleContext); + EXCEPTION_CHECK("requestFocus - call to CallBooleanMethod()", FALSE); + PrintDebugString("\r\n result = %d", result); + return result; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or requestFocusMethod == 0"); + return result; + } +} + +/** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ +BOOL +AccessBridgeJavaEntryPoints::selectTextRange(const jobject accessibleContext, int startIndex, int endIndex) { + + jthrowable exception; + BOOL result = FALSE; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::selectTextRange(%p start = %d end = %d):", + accessibleContext, startIndex, endIndex); + + if (selectTextRangeMethod != (jmethodID) 0) { + result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, + selectTextRangeMethod, + accessibleContext, + startIndex, endIndex); + EXCEPTION_CHECK("selectTextRange - call to CallBooleanMethod()", FALSE); + PrintDebugString("\r\n result = %d", result); + return result; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or selectTextRangeMethod == 0"); + return result; + } +} + +/* + * Returns whether two text attributes are the same. + */ +static BOOL CompareAccessibleTextAttributesInfo(AccessibleTextAttributesInfo *one, + AccessibleTextAttributesInfo *two) { + return(one->bold == two->bold + && one->italic == two->italic + && one->underline == two->underline + && one->strikethrough == two->strikethrough + && one->superscript == two->superscript + && one->subscript == two->subscript + && one->fontSize == two->fontSize + && one->alignment == two->alignment + && one->bidiLevel == two->bidiLevel + && one->firstLineIndent == two->firstLineIndent + && one->leftIndent == two->leftIndent + && one->rightIndent == two->rightIndent + && one->lineSpacing == two->lineSpacing + && one->spaceAbove == two->spaceAbove + && one->spaceBelow == two->spaceBelow + && !wcscmp(one->backgroundColor,two->backgroundColor) + && !wcscmp(one->foregroundColor,two->foregroundColor) + && !wcscmp(one->fullAttributesString,two->fullAttributesString)); +} + +/** + * Get text attributes between two indices. + * + * Only one AccessibleTextAttributesInfo structure is passed - which + * contains the attributes for the first character, the function then goes + * through the following characters in the range specified and stops when the + * attributes are different from the first, it then returns in the passed + * parameter len the number of characters with the attributes returned. In most + * situations this will be all the characters, and if not the calling program + * can easily get the attributes for the next characters with different + * attributes + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + +/* NEW FASTER CODE!!*/ +BOOL +AccessBridgeJavaEntryPoints::getTextAttributesInRange(const jobject accessibleContext, + int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len) { + + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + BOOL result = FALSE; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getTextAttributesInRange(%p start = %d end = %d):", + accessibleContext, startIndex, endIndex); + + *len = 0; + result = getAccessibleTextAttributes((jobject)accessibleContext, startIndex, attributes); + if (result != TRUE) { + return FALSE; + } + (*len)++; + + for (jint i = startIndex+1; i <= endIndex; i++) { + + AccessibleTextAttributesInfo test_attributes = *attributes; + // Get the full test_attributes string at i + if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) { + PrintDebugString(" Getting full test_attributes string from Context..."); + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleAttributesAtIndexFromContextMethod, + accessibleContext, i); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE); + wcsncpy(test_attributes.fullAttributesString, stringBytes, (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + test_attributes.fullAttributesString[length < (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t)) ? + length : (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Text attributes = %ls", test_attributes.fullAttributesString); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Text attributes is null."); + test_attributes.fullAttributesString[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0"); + return FALSE; + } + + if(wcscmp(attributes->fullAttributesString,test_attributes.fullAttributesString)) + break; + if (result != TRUE) { + return FALSE; + } + (*len)++; + } + return TRUE; +} + +/* + * Returns the number of visible children of a component + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ +int +AccessBridgeJavaEntryPoints::getVisibleChildrenCount(const jobject accessibleContext) { + + jthrowable exception; + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getVisibleChildrenCount(%p)", + accessibleContext); + + // get the visible children count + int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### visible children count = %d", numChildren); + + return numChildren; +} + + +/* + * This method is used to iterate through the visible children of a component. It + * returns visible children information for a component starting at nStartIndex. + * No more than MAX_VISIBLE_CHILDREN VisibleChildrenInfo objects will + * be returned for each call to this method. Returns FALSE on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ +BOOL AccessBridgeJavaEntryPoints::getVisibleChildren(const jobject accessibleContext, + const int nStartIndex, + /* OUT */ VisibleChildrenInfo *visibleChildrenInfo) { + + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getVisibleChildren(%p, startIndex = %d)", + accessibleContext, nStartIndex); + + // get the visible children count + int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### visible children count = %d", numChildren); + + if (nStartIndex >= numChildren) { + return FALSE; + } + + // get the visible children + int bufIndex = 0; + for (int i = nStartIndex; (i < numChildren) && (i < nStartIndex + MAX_VISIBLE_CHILDREN); i++) { + PrintDebugString(" getting visible child %d ...", i); + + // get the visible child at index i + jobject ac = jniEnv->CallObjectMethod(accessBridgeObject, getVisibleChildMethod, + accessibleContext, i); + EXCEPTION_CHECK("##### getVisibleChildMethod - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(ac); + EXCEPTION_CHECK("##### getVisibleChildMethod - call to NewGlobalRef()", FALSE); + visibleChildrenInfo->children[bufIndex] = (JOBJECT64)globalRef; + PrintDebugString(" ##### visible child = %p", globalRef); + + bufIndex++; + } + visibleChildrenInfo->returnedChildrenCount = bufIndex; + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getVisibleChildren succeeded"); + return TRUE; +} + +/** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ +BOOL +AccessBridgeJavaEntryPoints::setCaretPosition(const jobject accessibleContext, int position) { + + jthrowable exception; + BOOL result = FALSE; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::setCaretPostion(%p position = %d):", + accessibleContext, position); + + if (setCaretPositionMethod != (jmethodID) 0) { + result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, + setCaretPositionMethod, + accessibleContext, position); + EXCEPTION_CHECK("setCaretPostion - call to CallBooleanMethod()", FALSE); + PrintDebugString("\r\n result = %d", result); + return result; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or setCaretPositionMethod == 0"); + return result; + } +} + + +// ----------------------------------- + +/** + * getVersionInfo - returns the version string of the java.version property + * and the AccessBridge.java version + * + */ +BOOL +AccessBridgeJavaEntryPoints::getVersionInfo(AccessBridgeVersionInfo *info) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getVersionInfo():"); + + if (getJavaVersionPropertyMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getJavaVersionPropertyMethod); + EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + length = jniEnv->GetStringLength(js); + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + if (stringBytes == NULL) { + if (!jniEnv->ExceptionCheck()) { + PrintDebugString("\r\n *** Exception when getting JavaVersionProperty - call to GetStringChars"); + jniEnv->ExceptionDescribe(); + jniEnv->ExceptionClear(); + } + return FALSE; + } + wcsncpy(info->bridgeJavaDLLVersion, + stringBytes, + sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t)); + info->bridgeJavaDLLVersion[length < (sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t)) ? + length : (sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t))-2] = (wchar_t) 0; + wcsncpy(info->VMversion, + stringBytes, + sizeof(info->VMversion) / sizeof(wchar_t)); + info->VMversion[length < (sizeof(info->VMversion) / sizeof(wchar_t)) ? + length : (sizeof(info->VMversion) / sizeof(wchar_t))-2] = (wchar_t) 0; + wcsncpy(info->bridgeJavaClassVersion, + stringBytes, + sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t)); + info->bridgeJavaClassVersion[length < (sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t)) ? + length : (sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t))-2] = (wchar_t) 0; + wcsncpy(info->bridgeWinDLLVersion, + stringBytes, + sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t)); + info->bridgeWinDLLVersion[length < (sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t)) ? + length : (sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t))-2] = (wchar_t) 0; + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting JavaVersionProperty - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Java version = %ls", info->VMversion); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting JavaVersionProperty - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Java version is null."); + info->VMversion[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getJavaVersionPropertyMethod == 0"); + return FALSE; + } + + return TRUE; +} + + +/* + * Verifies the Java VM still exists and obj is an + * instance of AccessibleText + */ +BOOL AccessBridgeJavaEntryPoints::verifyAccessibleText(jobject obj) { + JavaVM *vm; + BOOL retval; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::verifyAccessibleText"); + + if (jniEnv->GetJavaVM(&vm) != 0) { + PrintDebugString(" Error! No Java VM"); + return FALSE; + } + + if (obj == (jobject)0) { + PrintDebugString(" Error! Null jobject"); + return FALSE; + } + + // Copied from getAccessibleContextInfo + if (getAccessibleTextFromContextMethod != (jmethodID) 0) { + jobject returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTextFromContextMethod, + (jobject)obj); + EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleText = %p", returnedJobject); + retval = returnedJobject != (jobject) 0; + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextFromContextMethod == 0"); + return FALSE; + } + if (retval == FALSE) { + PrintDebugString(" Error! jobject is not an AccessibleText"); + } + return retval; +} + + +/********** AccessibleContext routines ***********************************/ + +/** + * getAccessibleContextAt - performs the Java method call: + * Accessible AccessBridge.getAccessibleContextAt(x, y) + * + * Note: this call explicitly goes through the AccessBridge, + * so that it can keep a reference the returned jobject for the JavaVM. + * You must explicity call INTreleaseJavaObject() when you are through using + * the Accessible returned, to let the AccessBridge know it can release the + * object, so that the can then garbage collect it. + * + */ +jobject +AccessBridgeJavaEntryPoints::getAccessibleContextAt(jint x, jint y, jobject accessibleContext) { + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleContextAt(%d, %d, %p):", + x, y, accessibleContext); + + if (getAccessibleContextAtMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleContextAtMethod, + x, y, accessibleContext); + EXCEPTION_CHECK("Getting AccessibleContextAt - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleContextAt - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleContextAtMethod == 0"); + return (jobject) 0; + } +} + +/** + * getAccessibleWithFocus - performs the Java method calls: + * Accessible Translator.getAccessible(SwingEventMonitor.getComponentWithFocus(); + * + * Note: this call explicitly goes through the AccessBridge, + * so that the AccessBridge can hide expected changes in how this functions + * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some + * of this functionality may be built into the platform + * + */ +jobject +AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus() { + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus()"); + + if (getAccessibleContextWithFocusMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleContextWithFocusMethod); + EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either jniEnv == 0 or getAccessibleContextWithFocusMethod == 0"); + return (jobject) 0; + } +} + +/** + * getAccessibleContextInfo - fills a struct with a bunch of information + * contained in the Java Accessibility API + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + * + * Note: this call explicitly goes through the AccessBridge, + * so that it can keep a reference the returned jobject for the JavaVM. + * You must explicity call releaseJavaObject() when you are through using + * the AccessibleContext returned, to let the AccessBridge know it can release the + * object, so that the JavaVM can then garbage collect it. + */ +BOOL +AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, AccessibleContextInfo *info) { + jstring js; + const wchar_t *stringBytes; + jobject returnedJobject; + jthrowable exception; + jsize length; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleContextInfo(%p):", accessibleContext); + + ZeroMemory(info, sizeof(AccessibleContextInfo)); + + if (accessibleContext == (jobject) 0) { + PrintDebugString(" passed in AccessibleContext == null! (oops)"); + return (FALSE); + } + + // Get the Accessible Name + if (getAccessibleNameFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleNameFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleName - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); + wcsncpy(info->name, stringBytes, (sizeof(info->name) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->name[length < (sizeof(info->name) / sizeof(wchar_t)) ? + length : (sizeof(info->name) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Name = %ls", info->name); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Name is null."); + info->name[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleNameFromContextMethod == 0"); + return FALSE; + } + + + // Get the Accessible Description + if (getAccessibleDescriptionFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleDescriptionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleDescription - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); + wcsncpy(info->description, stringBytes, (sizeof(info->description) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->description[length < (sizeof(info->description) / sizeof(wchar_t)) ? + length : (sizeof(info->description) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Description = %ls", info->description); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Description is null."); + info->description[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleDescriptionFromContextMethod == 0"); + return FALSE; + } + + + // Get the Accessible Role String + if (getAccessibleRoleStringFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleRoleStringFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleRole - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringChars()", FALSE); + wcsncpy(info->role, stringBytes, (sizeof(info->role) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->role[length < (sizeof(info->role) / sizeof(wchar_t)) ? + length : (sizeof(info->role) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleRole - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleRole - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Role = %ls", info->role); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleRole - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Role is null."); + info->role[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleRoleStringFromContextMethod == 0"); + return FALSE; + } + + + // Get the Accessible Role String in the en_US locale + if (getAccessibleRoleStringFromContext_en_USMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleRoleStringFromContext_en_USMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringChars()", FALSE); + wcsncpy(info->role_en_US, stringBytes, (sizeof(info->role_en_US) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->role_en_US[length < (sizeof(info->role_en_US) / sizeof(wchar_t)) ? + length : (sizeof(info->role_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Role en_US = %ls", info->role_en_US); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Role en_US is null."); + info->role[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleRoleStringFromContext_en_USMethod == 0"); + return FALSE; + } + + // Get the Accessible States String + if (getAccessibleStatesStringFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleStatesStringFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleState - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleState - call to GetStringChars()", FALSE); + wcsncpy(info->states, stringBytes, (sizeof(info->states) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->states[length < (sizeof(info->states) / sizeof(wchar_t)) ? + length : (sizeof(info->states) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleState - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleState - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleState - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible States = %ls", info->states); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleState - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible States is null."); + info->states[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleStatesStringFromContextMethod == 0"); + return FALSE; + } + + // Get the Accessible States String in the en_US locale + if (getAccessibleStatesStringFromContext_en_USMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleStatesStringFromContext_en_USMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringChars()", FALSE); + wcsncpy(info->states_en_US, stringBytes, (sizeof(info->states_en_US) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->states_en_US[length < (sizeof(info->states_en_US) / sizeof(wchar_t)) ? + length : (sizeof(info->states_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible States en_US = %ls", info->states_en_US); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible States en_US is null."); + info->states[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleStatesStringFromContext_en_USMethod == 0"); + return FALSE; + } + + + // Get the index in Parent + if (getAccessibleIndexInParentFromContextMethod != (jmethodID) 0) { + info->indexInParent = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleIndexInParentFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleIndexInParent - call to CallIntMethod()", FALSE); + PrintDebugString(" Index in Parent = %d", info->indexInParent); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleIndexInParentFromContextMethod == 0"); + return FALSE; + } + + + PrintDebugString("*** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %p ***", + jniEnv, accessBridgeObject, accessibleContext); + + // Get the children count + if (getAccessibleChildrenCountFromContextMethod != (jmethodID) 0) { + info->childrenCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleChildrenCountFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleChildrenCount - call to CallIntMethod()", FALSE); + PrintDebugString(" Children count = %d", info->childrenCount); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleChildrenCountFromContextMethod == 0"); + return FALSE; + } + + PrintDebugString("*** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %X ***", + jniEnv, accessBridgeObject, accessibleContext); + + + // Get the x coord + if (getAccessibleXcoordFromContextMethod != (jmethodID) 0) { + info->x = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleXcoordFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleXcoord - call to CallIntMethod()", FALSE); + PrintDebugString(" X coord = %d", info->x); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleXcoordFromContextMethod == 0"); + return FALSE; + } + + PrintDebugString("*** jniEnv: %X; accessBridgeObject: %X; AccessibleContext: %p ***", + jniEnv, accessBridgeObject, accessibleContext); + + + // Get the y coord + if (getAccessibleYcoordFromContextMethod != (jmethodID) 0) { + info->y = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleYcoordFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleYcoord - call to CallIntMethod()", FALSE); + PrintDebugString(" Y coord = %d", info->y); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleYcoordFromContextMethod == 0"); + return FALSE; + } + + // Get the width + if (getAccessibleWidthFromContextMethod != (jmethodID) 0) { + info->width = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleWidthFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleWidth - call to CallIntMethod()", FALSE); + PrintDebugString(" Width = %d", info->width); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleWidthFromContextMethod == 0"); + return FALSE; + } + + // Get the height + if (getAccessibleHeightFromContextMethod != (jmethodID) 0) { + info->height = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHeightFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleHeight - call to CallIntMethod()", FALSE); + PrintDebugString(" Height = %d", info->height); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleHeightFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleComponent + if (getAccessibleComponentFromContextMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleComponentFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleComponent - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleComponent = %p", returnedJobject); + info->accessibleComponent = (returnedJobject != (jobject) 0 ? TRUE : FALSE); + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleComponent - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleComponentFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleAction + if (getAccessibleActionFromContextMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleActionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleAction - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleAction = %p", returnedJobject); + info->accessibleAction = (returnedJobject != (jobject) 0 ? TRUE : FALSE); + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleAction - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleActionFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleSelection + if (getAccessibleSelectionFromContextMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleSelectionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleSelection - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleSelection = %p", returnedJobject); + info->accessibleSelection = (returnedJobject != (jobject) 0 ? TRUE : FALSE); + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleSelection - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleSelectionFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleTable + if (getAccessibleTableFromContextMethod != (jmethodID) 0) { + PrintDebugString("##### Calling getAccessibleTableFromContextMethod ..."); + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableFromContextMethod, + accessibleContext); + PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod"); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE); + PrintDebugString(" ##### AccessibleTable = %p", returnedJobject); + if (returnedJobject != (jobject) 0) { + info->accessibleInterfaces |= cAccessibleTableInterface; + } + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to DeleteLocalRef()", FALSE); + + /* + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableFromContextMethod, + AccessibleContext); + PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod"); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE); + PrintDebugString(" ##### AccessibleTable = %X", returnedJobject); + info->accessibleTable = returnedJobject; + */ + + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleText + if (getAccessibleTextFromContextMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTextFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleText = %p", returnedJobject); + info->accessibleText = (returnedJobject != (jobject) 0 ? TRUE : FALSE); + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleValue + if (getAccessibleValueFromContextMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleValueFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleValue - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleValue = %p", returnedJobject); + if (returnedJobject != (jobject) 0) { + info->accessibleInterfaces |= cAccessibleValueInterface; + } + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleValue - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleValueFromContextMethod == 0"); + return FALSE; + } + + // FIX + // get the AccessibleHypertext + if (getAccessibleHypertextMethod != (jmethodID) 0 && + getAccessibleHyperlinkCountMethod != (jmethodID) 0 && + getAccessibleHyperlinkMethod != (jmethodID) 0 && + getAccessibleHyperlinkTextMethod != (jmethodID) 0 && + getAccessibleHyperlinkStartIndexMethod != (jmethodID) 0 && + getAccessibleHyperlinkEndIndexMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHypertextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleHypertext - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleHypertext = %p", + returnedJobject); + if (returnedJobject != (jobject) 0) { + info->accessibleInterfaces |= cAccessibleHypertextInterface; + } + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleHypertext - call to DeleteLocalRef()", FALSE); + } + + // set new accessibleInterfaces flags from old BOOL values + if(info->accessibleComponent) + info->accessibleInterfaces |= cAccessibleComponentInterface; + if(info->accessibleAction) + info->accessibleInterfaces |= cAccessibleActionInterface; + if(info->accessibleSelection) + info->accessibleInterfaces |= cAccessibleSelectionInterface; + if(info->accessibleText) + info->accessibleInterfaces |= cAccessibleTextInterface; + // FIX END + + return TRUE; +} + +/** + * getAccessibleChildFromContext - performs the Java method call: + * AccessibleContext AccessBridge.getAccessibleChildContext(AccessibleContext) + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + * + * Note: this call explicitly goes through the AccessBridge, + * so that it can keep a reference the returned jobject for the JavaVM. + * You must explicity call releaseJavaObject() when you are through using + * the AccessibleContext returned, to let the AccessBridge know it can release the + * object, so that the JavaVM can then garbage collect it. + */ +jobject +AccessBridgeJavaEntryPoints::getAccessibleChildFromContext(jobject accessibleContext, jint childIndex) { + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleChildContext(%p, %d):", + accessibleContext, childIndex); + + if (getAccessibleChildFromContextMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleChildFromContextMethod, + accessibleContext, childIndex); + EXCEPTION_CHECK("Getting AccessibleChild - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleChild - call to NewGlobalRef()", FALSE); + jniEnv->DeleteLocalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleChild - call to DeleteLocalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleChildContextMethod == 0"); + return (jobject) 0; + } +} + +/** + * getAccessibleParentFromContext - returns the AccessibleContext parent + * + */ +jobject +AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(jobject accessibleContext) +{ + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(%p):", accessibleContext); + + if (getAccessibleParentFromContextMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleParentFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleParent - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleParent - call to NewGlobalRef()", FALSE); + jniEnv->DeleteLocalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleParent - call to DeleteLocalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleParentFromContextMethod == 0"); + return (jobject) 0; + } +} + + +/********** AccessibleTable routines **********************************/ + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableInfo(jobject accessibleContext, + AccessibleTableInfo *tableInfo) { + + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo(%p):", + accessibleContext); + + // get the table row count + if (getAccessibleTableRowCountMethod != (jmethodID) 0) { + tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting AccessibleTableRowCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row count = %d", tableInfo->rowCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleRowCountMethod == 0"); + return FALSE; + } + + // get the table column count + if (getAccessibleTableColumnCountMethod != (jmethodID) 0) { + tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnCountMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleTableColumnCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table column count = %d", tableInfo->columnCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnCountMethod == 0"); + return FALSE; + } + + // get the AccessibleTable + if (getAccessibleTableFromContextMethod != (jmethodID) 0) { + PrintDebugString("##### Calling getAccessibleTableFromContextMethod ..."); + jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableFromContextMethod, + accessibleContext); + PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod"); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(accTable); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE); + tableInfo->accessibleTable = (JOBJECT64)globalRef; + PrintDebugString(" ##### accessibleTable = %p", globalRef); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableFromContextMethod == 0"); + return FALSE; + } + + // cache the AccessibleContext + if (getContextFromAccessibleTableMethod != (jmethodID) 0) { + PrintDebugString("##### Calling getContextFromAccessibleTable Method ..."); + jobject ac = jniEnv->CallObjectMethod(accessBridgeObject, + getContextFromAccessibleTableMethod, + accessibleContext); + PrintDebugString("##### ... Returned from getContextFromAccessibleTable Method"); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(ac); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE); + tableInfo->accessibleContext = (JOBJECT64)globalRef; + PrintDebugString(" ##### accessibleContext = %p", globalRef); + } else { + PrintDebugString(" ##### Error! either env == 0 or getContextFromAccessibleTable Method == 0"); + return FALSE; + } + + // FIX - set unused elements + tableInfo->caption = NULL; + tableInfo->summary = NULL; + + PrintDebugString("##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo succeeded"); + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(jobject accessibleTable, jint row, jint column, + AccessibleTableCellInfo *tableCellInfo) { + + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(%p): row=%d, column=%d", + accessibleTable, row, column); + + // FIX + ZeroMemory(tableCellInfo, sizeof(AccessibleTableCellInfo)); + tableCellInfo->row = row; + tableCellInfo->column = column; + // FIX END + + // get the table cell index + if (getAccessibleTableCellIndexMethod != (jmethodID) 0) { + tableCellInfo->index = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableCellIndexMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting AccessibleTableCellIndex - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table cell index = %d", tableCellInfo->index); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellIndexMethod == 0"); + return FALSE; + } + + // get the table cell row extent + if (getAccessibleTableCellRowExtentMethod != (jmethodID) 0) { + tableCellInfo->rowExtent = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableCellRowExtentMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting AccessibleTableCellRowExtentCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table cell row extent = %d", tableCellInfo->rowExtent); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellRowExtentMethod == 0"); + return FALSE; + } + + // get the table cell column extent + if (getAccessibleTableCellColumnExtentMethod != (jmethodID) 0) { + tableCellInfo->columnExtent = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableCellColumnExtentMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting AccessibleTableCellColumnExtentCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table cell column extent = %d", tableCellInfo->columnExtent); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellColumnExtentMethod == 0"); + return FALSE; + } + + // get whether the table cell is selected + if (isAccessibleTableCellSelectedMethod != (jmethodID) 0) { + tableCellInfo->isSelected = jniEnv->CallBooleanMethod(accessBridgeObject, + isAccessibleTableCellSelectedMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting isAccessibleTableCellSelected - call to CallBooleanMethod()", FALSE); + PrintDebugString(" ##### table cell isSelected = %d", tableCellInfo->isSelected); + } else { + PrintDebugString(" ##### Error! either env == 0 or isAccessibleTableCellSelectedMethod == 0"); + return FALSE; + } + + // get the table cell AccessibleContext + if (getAccessibleTableCellAccessibleContextMethod != (jmethodID) 0) { + jobject tableCellAC = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableCellAccessibleContextMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(tableCellAC); + EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to NewGlobalRef()", FALSE); + tableCellInfo->accessibleContext = (JOBJECT64)globalRef; + PrintDebugString(" ##### table cell AccessibleContext = %p", globalRef); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellAccessibleContextMethod == 0"); + return FALSE; + } + + PrintDebugString(" ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo succeeded"); + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(jobject acParent, AccessibleTableInfo *tableInfo) { + + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(%p):", + acParent); + + // get the header row count + if (getAccessibleTableRowHeaderRowCountMethod != (jmethodID) 0) { + tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowHeaderRowCountMethod, + acParent); + EXCEPTION_CHECK("##### Getting AccessibleTableRowHeaderRowCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row count = %d", tableInfo->rowCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleRowHeaderRowCountMethod == 0"); + return FALSE; + } + + // get the header column count + if (getAccessibleTableRowHeaderColumnCountMethod != (jmethodID) 0) { + tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowHeaderColumnCountMethod, + acParent); + EXCEPTION_CHECK("Getting AccessibleTableRowHeaderColumnCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table column count = %d", tableInfo->columnCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowHeaderColumnCountMethod == 0"); + return FALSE; + } + + // get the header AccessibleTable + if (getAccessibleTableRowHeaderMethod != (jmethodID) 0) { + jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableRowHeaderMethod, + acParent); + EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(accTable); + EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to NewGlobalRef()", FALSE); + tableInfo->accessibleTable = (JOBJECT64)globalRef; + PrintDebugString(" ##### row header AccessibleTable = %p", globalRef); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowHeaderMethod == 0"); + return FALSE; + } + + // FIX - set unused elements + tableInfo->caption = NULL; + tableInfo->summary = NULL; + tableInfo->accessibleContext = NULL; + + PrintDebugString(" ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader succeeded"); + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(jobject acParent, AccessibleTableInfo *tableInfo) { + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(%p):", + acParent); + + // get the header row count + if (getAccessibleTableColumnHeaderRowCountMethod != (jmethodID) 0) { + tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnHeaderRowCountMethod, + acParent); + EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeaderRowCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row count = %d", tableInfo->rowCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleColumnHeaderRowCountMethod == 0"); + return FALSE; + } + + // get the header column count + if (getAccessibleTableColumnHeaderColumnCountMethod != (jmethodID) 0) { + tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnHeaderColumnCountMethod, + acParent); + EXCEPTION_CHECK("Getting AccessibleTableColumnHeaderColumnCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table column count = %d", tableInfo->columnCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnHeaderColumnCountMethod == 0"); + return FALSE; + } + // get the header AccessibleTable + if (getAccessibleTableColumnHeaderMethod != (jmethodID) 0) { + jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableColumnHeaderMethod, + acParent); + EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(accTable); + EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to NewGlobalRef()", FALSE); + tableInfo->accessibleTable = (JOBJECT64)globalRef; + PrintDebugString(" ##### column header AccessibleTable = %p", globalRef); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnHeaderMethod == 0"); + return FALSE; + } + + // FIX - set unused elements + tableInfo->caption = NULL; + tableInfo->summary = NULL; + tableInfo->accessibleContext = NULL; + + PrintDebugString(" ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader succeeded"); + return TRUE; +} + +jobject +AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(jobject acParent, jint row) { + + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(%p):", + acParent); + + if (getAccessibleTableRowDescriptionMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableRowDescriptionMethod, + acParent, row); + EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to NewGlobalRef()", FALSE); + jniEnv->DeleteLocalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to DeleteLocalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTableRowDescriptionMethod == 0"); + return (jobject) 0; + } +} + +jobject +AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(jobject acParent, jint column) { + + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(%p):", + acParent); + + if (getAccessibleTableColumnDescriptionMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod( + accessBridgeObject, + getAccessibleTableColumnDescriptionMethod, + acParent, column); + EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to NewGlobalRef()", FALSE); + jniEnv->DeleteLocalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to DeleteLocalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTableColumnDescriptionMethod == 0"); + return (jobject) 0; + } +} + +jint +AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(jobject accessibleTable) { + + jthrowable exception; + jint count; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(%p)", + accessibleTable); + + // Get the table row selection count + if (getAccessibleTableRowSelectionCountMethod != (jmethodID) 0) { + count = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowSelectionCountMethod, + accessibleTable); + EXCEPTION_CHECK("##### Getting AccessibleTableRowSelectionCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row selection count = %d", count); + return count; + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowSelectionCountMethod == 0"); + return 0; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount failed"); + return 0; +} + +BOOL +AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(jobject accessibleTable, jint row) { + jthrowable exception; + BOOL result; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(%p, %d)", + accessibleTable, row); + + if (isAccessibleTableRowSelectedMethod != (jmethodID) 0) { + result = jniEnv->CallBooleanMethod(accessBridgeObject, + isAccessibleTableRowSelectedMethod, + accessibleTable, row); + EXCEPTION_CHECK("##### Getting isAccessibleTableRowSelected - call to CallBooleanMethod()", FALSE); + PrintDebugString(" ##### table row isSelected = %d", result); + return result; + } else { + PrintDebugString(" ##### Error! either env == 0 or isAccessibleTableRowSelectedMethod == 0"); + return FALSE; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected failed"); + return FALSE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(jobject accessibleTable, jint count, + jint *selections) { + + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(%p, %d %p)", + accessibleTable, count, selections); + + if (getAccessibleTableRowSelectionsMethod == (jmethodID) 0) { + return FALSE; + } + // Get the table row selections + for (int i = 0; i < count; i++) { + + selections[i] = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowSelectionsMethod, + accessibleTable, + i); + EXCEPTION_CHECK("##### Getting AccessibleTableRowSelections - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row selection[%d] = %d", i, selections[i]); + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections succeeded"); + return TRUE; +} + + +jint +AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(jobject accessibleTable) { + + jthrowable exception; + jint count; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(%p)", + accessibleTable); + + // Get the table column selection count + if (getAccessibleTableColumnSelectionCountMethod != (jmethodID) 0) { + count = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnSelectionCountMethod, + accessibleTable); + EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelectionCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table column selection count = %d", count); + return count; + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleRowCountMethod == 0"); + return 0; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount failed"); + return 0; +} + +BOOL +AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(jobject accessibleTable, jint column) { + jthrowable exception; + BOOL result; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(%p, %d)", + accessibleTable, column); + + if (isAccessibleTableColumnSelectedMethod != (jmethodID) 0) { + result = jniEnv->CallBooleanMethod(accessBridgeObject, + isAccessibleTableColumnSelectedMethod, + accessibleTable, column); + EXCEPTION_CHECK("##### Getting isAccessibleTableColumnSelected - call to CallBooleanMethod()", FALSE); + PrintDebugString(" ##### table column isSelected = %d", result); + return result; + } else { + PrintDebugString(" ##### Error! either env == 0 or isAccessibleTableColumnSelectedMethod == 0"); + return FALSE; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected failed"); + return FALSE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(jobject accessibleTable, jint count, + jint *selections) { + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(%p, %d, %p)", + accessibleTable, count, selections); + + if (getAccessibleTableColumnSelectionsMethod == (jmethodID) 0) { + return FALSE; + } + // Get the table column selections + for (int i = 0; i < count; i++) { + + selections[i] = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnSelectionsMethod, + accessibleTable, + i); + EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelections - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table Column selection[%d] = %d", i, selections[i]); + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections succeeded"); + return TRUE; +} + + +jint +AccessBridgeJavaEntryPoints::getAccessibleTableRow(jobject accessibleTable, jint index) { + jthrowable exception; + jint result; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRow(%p, index=%d)", + accessibleTable, index); + + if (getAccessibleTableRowMethod != (jmethodID) 0) { + result = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowMethod, + accessibleTable, index); + EXCEPTION_CHECK("##### Getting AccessibleTableRow - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row = %d", result); + return result; + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowMethod == 0"); + return -1; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow failed"); + return -1; +} + +jint +AccessBridgeJavaEntryPoints::getAccessibleTableColumn(jobject accessibleTable, jint index) { + jthrowable exception; + jint result; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn(%p, index=%d)", + accessibleTable, index); + + if (getAccessibleTableColumnMethod != (jmethodID) 0) { + result = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnMethod, + accessibleTable, index); + EXCEPTION_CHECK("##### Getting AccessibleTableColumn - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table column = %d", result); + return result; + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnMethod == 0"); + return -1; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn failed"); + return -1; +} + +jint +AccessBridgeJavaEntryPoints::getAccessibleTableIndex(jobject accessibleTable, jint row, jint column) { + jthrowable exception; + jint result; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex(%p, row=%d, col=%d)", + accessibleTable, row, column); + + if (getAccessibleTableIndexMethod != (jmethodID) 0) { + result = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableIndexMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting getAccessibleTableIndex - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table index = %d", result); + return result; + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableIndexMethod == 0"); + return -1; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex failed"); + return -1; +} + +/********** end AccessibleTable routines ******************************/ + + +/********** begin AccessibleRelationSet routines **********************/ + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleRelationSet(jobject accessibleContext, + AccessibleRelationSetInfo *relationSet) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet(%p, %p)", + accessibleContext, relationSet); + + if (getAccessibleRelationCountMethod == (jmethodID) 0 || + getAccessibleRelationKeyMethod == (jmethodID) 0 || + getAccessibleRelationTargetCountMethod == (jmethodID) 0 || + getAccessibleRelationTargetMethod == (jmethodID) 0) { + return FALSE; + } + + // Get the relations set count + relationSet->relationCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleRelationCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting AccessibleRelationCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### AccessibleRelation count = %d", relationSet->relationCount); + + + // Get the relation set + for (int i = 0; i < relationSet->relationCount && i < MAX_RELATIONS; i++) { + + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleRelationKeyMethod, + accessibleContext, + i); + + EXCEPTION_CHECK("Getting AccessibleRelationKey - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringChars()", FALSE); + wcsncpy(relationSet->relations[i].key, stringBytes, (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + relationSet->relations[i].key [length < (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t)) ? + length : (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleRelation key - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleRelation key - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleRelation key = %ls", relationSet->relations[i].key ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleRelation key - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AccessibleRelation key is null."); + relationSet->relations[i].key [0] = (wchar_t) 0; + } + + relationSet->relations[i].targetCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleRelationTargetCountMethod, + accessibleContext, + i); + + for (int j = 0; j < relationSet->relations[i].targetCount && j < MAX_RELATION_TARGETS; j++) { + jobject target = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleRelationTargetMethod, + accessibleContext, i, j); + EXCEPTION_CHECK("Getting AccessibleRelationSet - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(target); + EXCEPTION_CHECK("Getting AccessibleRelationSet - call to NewGlobalRef()", FALSE); + relationSet->relations[i].targets[j] = (JOBJECT64)globalRef; + PrintDebugString(" relation set item: %p", globalRef); + } + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet succeeded"); + return TRUE; +} + + +/********** end AccessibleRelationSet routines ************************/ + + +/********** begin AccessibleHypertext routines **********************/ + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleHypertext(jobject accessibleContext, + AccessibleHypertextInfo *hypertext) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertext(%p, %p)", + accessibleContext, hypertext); + + // get the AccessibleHypertext + jobject ht = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHypertextMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(ht); + EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE); + hypertext->accessibleHypertext = (JOBJECT64)globalRef; + PrintDebugString(" ##### AccessibleHypertext = %p", globalRef); + + if (hypertext->accessibleHypertext == 0) { + PrintDebugString(" ##### null AccessibleHypertext; returning FALSE"); + return false; + } + + // get the hyperlink count + hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkCountMethod,accessibleContext); + + EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink count = %d", hypertext->linkCount); + + + // get the hypertext links + for (int i = 0; i < hypertext->linkCount && i < MAX_HYPERLINKS; i++) { + + // get the hyperlink + jobject hl = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkMethod, + accessibleContext, + i); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(hl); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE); + hypertext->links[i].accessibleHyperlink = (JOBJECT64)globalRef; + PrintDebugString(" ##### AccessibleHyperlink = %p", globalRef); + + // get the hyperlink text + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkTextMethod, + hypertext->links[i].accessibleHyperlink, + i); + + EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE); + wcsncpy(hypertext->links[i].text, stringBytes, (sizeof(hypertext->links[i].text) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + if (length >= (sizeof(hypertext->links[i].text) / sizeof(wchar_t))) { + length = (sizeof(hypertext->links[i].text) / sizeof(wchar_t)) - 2; + } + hypertext->links[i].text[length] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleHyperlink text = %ls", hypertext->links[i].text ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AccessibleHyperlink text is null."); + hypertext->links[i].text[0] = (wchar_t) 0; + } + + hypertext->links[i].startIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkStartIndexMethod, + hypertext->links[i].accessibleHyperlink, + i); + EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink start index = %d", hypertext->links[i].startIndex); + + + hypertext->links[i].endIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkEndIndexMethod, + hypertext->links[i].accessibleHyperlink, + i); + EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink end index = %d", hypertext->links[i].endIndex); + + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext succeeded"); + return TRUE; +} + +/* + * Activates an AccessibleHyperlink + */ +BOOL +AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(jobject accessibleContext, + jobject accessibleHyperlink) { + + jthrowable exception; + BOOL returnVal; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(%p, %p):", + accessibleContext, accessibleHyperlink); + + if (activateAccessibleHyperlinkMethod != (jmethodID) 0) { + returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, activateAccessibleHyperlinkMethod, + accessibleContext, accessibleHyperlink); + EXCEPTION_CHECK("activateAccessibleHyperlink - call to CallBooleanMethod()", FALSE); + return returnVal; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or activateAccessibleHyperlinkMethod == 0"); + return FALSE; + } +} + + +/* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * returns FALSE on error. + */ +BOOL +AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(const jobject accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertext) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(%p, %p, startIndex = %d)", + accessibleContext, hypertext, nStartIndex); + + // get the AccessibleHypertext + jobject ht = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleHypertextMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(ht); + EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE); + hypertext->accessibleHypertext = (JOBJECT64)globalRef; + PrintDebugString(" ##### AccessibleHypertext = %p", globalRef); + if (hypertext->accessibleHypertext == 0) { + PrintDebugString(" ##### null AccessibleHypertext; returning FALSE"); + return FALSE; + } + + // get the hyperlink count + hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink count = %d", hypertext->linkCount); + + if (nStartIndex >= hypertext->linkCount) { + return FALSE; + } + + // get the hypertext links + // NOTE: To avoid a crash when there are more than MAX_HYPERLINKS (64) links + // in the document, test for i < MAX_HYPERLINKS in addition to + // i < hypertext->linkCount + int bufIndex = 0; + for (int i = nStartIndex; (i < hypertext->linkCount) && (i < nStartIndex + MAX_HYPERLINKS); i++) { + PrintDebugString(" getting hyperlink %d ...", i); + + // get the hyperlink + jobject hl = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkMethod, + hypertext->accessibleHypertext, + i); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(hl); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE); + hypertext->links[bufIndex].accessibleHyperlink = (JOBJECT64)globalRef; + PrintDebugString(" ##### AccessibleHyperlink = %p", globalRef); + + // get the hyperlink text + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkTextMethod, + hypertext->links[bufIndex].accessibleHyperlink, + i); + + EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE); + wcsncpy(hypertext->links[bufIndex].text, stringBytes, + (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + if (length >= (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t))) { + length = (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t)) - 2; + } + hypertext->links[bufIndex].text[length] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleHyperlink text = %ls", hypertext->links[bufIndex].text ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE); + + } else { + PrintDebugString(" AccessibleHyperlink text is null."); + hypertext->links[bufIndex].text[0] = (wchar_t) 0; + } + + hypertext->links[bufIndex].startIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkStartIndexMethod, + hypertext->links[bufIndex].accessibleHyperlink, + i); + EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink start index = %d", hypertext->links[bufIndex].startIndex); + + hypertext->links[bufIndex].endIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkEndIndexMethod, + hypertext->links[bufIndex].accessibleHyperlink, + i); + EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink end index = %d", hypertext->links[bufIndex].endIndex); + + bufIndex++; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt succeeded"); + return TRUE; +} + +jint AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(const jobject accessibleContext) { + + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(%X)", + accessibleContext); + + if (getAccessibleHyperlinkCountMethod == (jmethodID)0) { + return -1; + } + + // get the hyperlink count + jint linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", -1); + PrintDebugString(" ##### hyperlink count = %d", linkCount); + + return linkCount; +} + + +jint AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(const jobject hypertext, + const jint nIndex) { + + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(%p, index = %d)", + hypertext, nIndex); + + if (getAccessibleHypertextLinkIndexMethod == (jmethodID)0) { + return -1; + } + + // get the hyperlink index + jint index = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHypertextLinkIndexMethod, + hypertext, nIndex); + + EXCEPTION_CHECK("##### Getting hyperlink index - call to CallIntMethod()", -1); + PrintDebugString(" ##### hyperlink index = %d", index); + + return index; +} + +BOOL AccessBridgeJavaEntryPoints::getAccessibleHyperlink(jobject hypertext, + const jint index, + /* OUT */ AccessibleHyperlinkInfo *info) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHyperlink(%p, index = %d)", + hypertext, index); + + + // get the hyperlink + jobject hl = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkMethod, + hypertext, + index); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(hl); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE); + info->accessibleHyperlink = (JOBJECT64)globalRef; + PrintDebugString(" ##### AccessibleHyperlink = %p", globalRef); + + // get the hyperlink text + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkTextMethod, + info->accessibleHyperlink, + index); + + EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE); + wcsncpy(info->text, stringBytes, + (sizeof(info->text) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + if (length >= (sizeof(info->text) / sizeof(wchar_t))) { + length = (sizeof(info->text) / sizeof(wchar_t)) - 2; + } + info->text[length] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleHyperlink text = %ls", info->text ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE); + + } else { + PrintDebugString(" AccessibleHyperlink text is null."); + info->text[0] = (wchar_t) 0; + } + + info->startIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkStartIndexMethod, + info->accessibleHyperlink, + index); + EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink start index = %d", info->startIndex); + + info->endIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkEndIndexMethod, + info->accessibleHyperlink, + index); + EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink end index = %d", info->endIndex); + + return TRUE; +} + + +/********** end AccessibleHypertext routines ************************/ + +// Accessible Keybinding methods +BOOL AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(jobject accessibleContext, + AccessibleKeyBindings *keyBindings) { + + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(%p, %p)", + accessibleContext, keyBindings); + + if (getAccessibleKeyBindingsCountMethod == (jmethodID) 0 || + getAccessibleKeyBindingCharMethod == (jmethodID) 0 || + getAccessibleKeyBindingModifiersMethod == (jmethodID) 0) { + return FALSE; + } + + // get the key binding count + keyBindings->keyBindingsCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleKeyBindingsCountMethod, accessibleContext); + + EXCEPTION_CHECK("##### Getting key bindings count - call to CallIntMethod()", FALSE); + + PrintDebugString(" ##### key bindings count = %d", keyBindings->keyBindingsCount); + + // get the key bindings + for (int i = 0; i < keyBindings->keyBindingsCount && i < MAX_KEY_BINDINGS; i++) { + + // get the key binding character + keyBindings->keyBindingInfo[i].character = jniEnv->CallCharMethod(accessBridgeObject, + getAccessibleKeyBindingCharMethod, + accessibleContext, + i); + EXCEPTION_CHECK("##### Getting key binding character - call to CallCharMethod()", FALSE); + PrintDebugString(" ##### key binding character = %c", keyBindings->keyBindingInfo[i].character); + PrintDebugString(" ##### key binding character in hex = %hx", keyBindings->keyBindingInfo[i].character); + + // get the key binding modifiers + keyBindings->keyBindingInfo[i].modifiers = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleKeyBindingModifiersMethod, + accessibleContext, + i); + EXCEPTION_CHECK("##### Getting key binding modifiers - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### key binding modifiers = %x", keyBindings->keyBindingInfo[i].modifiers); + } + return FALSE; +} + +// AccessibleIcon methods +BOOL AccessBridgeJavaEntryPoints::getAccessibleIcons(jobject accessibleContext, + AccessibleIcons *icons) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)", + accessibleContext, icons); + + if (getAccessibleIconsCountMethod == (jmethodID) 0 || + getAccessibleIconDescriptionMethod == (jmethodID) 0 || + getAccessibleIconHeightMethod == (jmethodID) 0 || + getAccessibleIconWidthMethod == (jmethodID) 0) { + PrintDebugString(" ##### missing method(s) !!!"); + return FALSE; + } + + + // get the icons count + icons->iconsCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleIconsCountMethod, accessibleContext); + + EXCEPTION_CHECK("##### Getting icons count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### icons count = %d", icons->iconsCount); + + + // get the icons + for (int i = 0; i < icons->iconsCount && i < MAX_ICON_INFO; i++) { + + // get the icon description + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleIconDescriptionMethod, + accessibleContext, + i); + + EXCEPTION_CHECK("Getting icon description - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringChars()", FALSE); + wcsncpy(icons->iconInfo[i].description, stringBytes, (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + if (length >= (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t))) { + length = (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t)) - 2; + } + icons->iconInfo[i].description[length] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleIcon description - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleIcon description - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleIcon description = %ls", icons->iconInfo[i].description ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleIcon description - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AccessibleIcon description is null."); + icons->iconInfo[i].description[0] = (wchar_t) 0; + } + + + // get the icon height + icons->iconInfo[i].height = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleIconHeightMethod, + accessibleContext, + i); + EXCEPTION_CHECK("##### Getting icon height - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### icon height = %d", icons->iconInfo[i].height); + + // get the icon width + icons->iconInfo[i].width = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleIconWidthMethod, + accessibleContext, + i); + EXCEPTION_CHECK("##### Getting icon width - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### icon width = %d", icons->iconInfo[i].width); + } + return FALSE; +} + +// AccessibleActionMethods +BOOL AccessBridgeJavaEntryPoints::getAccessibleActions(jobject accessibleContext, + AccessibleActions *actions) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)", + accessibleContext, actions); + + if (getAccessibleActionsCountMethod == (jmethodID) 0 || + getAccessibleActionNameMethod == (jmethodID) 0) { + PrintDebugString(" ##### missing method(s) !!!"); + return FALSE; + } + + + // get the icons count + actions->actionsCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleActionsCountMethod,accessibleContext); + + EXCEPTION_CHECK("##### Getting actions count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### key actions count = %d", actions->actionsCount); + + + // get the actions + for (int i = 0; i < actions->actionsCount && i < MAX_ACTION_INFO; i++) { + + // get the action name + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleActionNameMethod, + accessibleContext, + i); + + EXCEPTION_CHECK("Getting Action Name - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleAction Name - call to GetStringChars()", FALSE); + wcsncpy(actions->actionInfo[i].name , stringBytes, (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + if (length >= (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t))) { + length = (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t)) - 2; + } + actions->actionInfo[i].name [length] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleAction name - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleAction name - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleAction name - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleAction name = %ls", actions->actionInfo[i].name ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleAction name - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AccessibleAction name is null."); + actions->actionInfo[i].name [0] = (wchar_t) 0; + } + } + return FALSE; +} + +BOOL AccessBridgeJavaEntryPoints::doAccessibleActions(jobject accessibleContext, + AccessibleActionsToDo *actionsToDo, + jint *failure) { + + jthrowable exception; + BOOL returnVal; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::doAccessibleActions(%p, #actions %d %s):", + accessibleContext, + actionsToDo->actionsCount, + actionsToDo->actions[0].name); + + if (doAccessibleActionsMethod == (jmethodID) 0) { + *failure = 0; + return FALSE; + } + + PrintDebugString("\r\n doing %d actions ...", actionsToDo->actionsCount); + for (int i = 0; i < actionsToDo->actionsCount && i < MAX_ACTIONS_TO_DO; i++) { + PrintDebugString("\r doing action %d: %s ...", i, actionsToDo->actions[i].name); + + // create a Java String for the action name + wchar_t *actionName = (wchar_t *)actionsToDo->actions[i].name; + jstring javaName = jniEnv->NewString(actionName, (jsize)wcslen(actionName)); + if (javaName == 0) { + PrintDebugString("\r NewString failed"); + *failure = i; + return FALSE; + } + + returnVal = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, doAccessibleActionsMethod, + accessibleContext, javaName); + jniEnv->DeleteLocalRef(javaName); + EXCEPTION_CHECK("doAccessibleActions - call to CallBooleanMethod()", FALSE); + + if (returnVal != TRUE) { + PrintDebugString("\r Action %d failed", i); + *failure = i; + return FALSE; + } + } + *failure = -1; + return TRUE; +} + + +/********** AccessibleText routines ***********************************/ + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextInfo(jobject accessibleContext, + AccessibleTextInfo *textInfo, + jint x, jint y) { + jthrowable exception; + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextInfo(%p, %d, %d):", + accessibleContext, x, y); + + // Get the character count + if (getAccessibleCharCountFromContextMethod != (jmethodID) 0) { + textInfo->charCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleCharCountFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleCharCount - call to CallIntMethod()", FALSE); + PrintDebugString(" Char count = %d", textInfo->charCount); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleCharCountFromContextMethod == 0"); + return FALSE; + } + + // Get the index of the caret + if (getAccessibleCaretPositionFromContextMethod != (jmethodID) 0) { + textInfo->caretIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleCaretPositionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleCaretPosition - call to CallIntMethod()", FALSE); + PrintDebugString(" Index at caret = %d", textInfo->caretIndex); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleCaretPositionFromContextMethod == 0"); + return FALSE; + } + + // Get the index at the given point + if (getAccessibleIndexAtPointFromContextMethod != (jmethodID) 0) { + textInfo->indexAtPoint = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleIndexAtPointFromContextMethod, + accessibleContext, x, y); + EXCEPTION_CHECK("Getting AccessibleIndexAtPoint - call to CallIntMethod()", FALSE); + PrintDebugString(" Index at point = %d", textInfo->indexAtPoint); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleIndexAtPointFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextItems(jobject accessibleContext, + AccessibleTextItemsInfo *textItems, jint index) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextItems(%p):", accessibleContext); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // Get the letter at index + if (getAccessibleLetterAtIndexFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleLetterAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallIntMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to GetStringChars()", FALSE); + textItems->letter = stringBytes[0]; + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallVoidMethod()", FALSE); + PrintDebugString(" Accessible Text letter = %c", textItems->letter); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Text letter is null."); + textItems->letter = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleLetterAtIndexFromContextMethod == 0"); + return FALSE; + } + + + // Get the word at index + if (getAccessibleWordAtIndexFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleWordAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallIntMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringChars()", FALSE); + wcsncpy(textItems->word, stringBytes, (sizeof(textItems->word) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + textItems->word[length < (sizeof(textItems->word) / sizeof(wchar_t)) ? + length : (sizeof(textItems->word) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Text word = %ls", textItems->word); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Text word is null."); + textItems->word[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleWordAtIndexFromContextMethod == 0"); + return FALSE; + } + + // Get the sentence at index + if (getAccessibleSentenceAtIndexFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleSentenceAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringChars()", FALSE); + wcsncpy(textItems->sentence, stringBytes, (sizeof(textItems->sentence) / sizeof(wchar_t))-2); + length = jniEnv->GetStringLength(js); + + if (length < sizeof(textItems->sentence) / sizeof(wchar_t)) { + textItems->sentence[length] = (wchar_t) 0; + } else { + textItems->sentence[(sizeof(textItems->sentence) / sizeof(wchar_t))-2] = (wchar_t) 0; + } + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Text sentence = %ls", textItems->sentence); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Text sentence is null."); + textItems->sentence[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleSentenceAtIndexFromContextMethod == 0"); + return FALSE; + } + + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(jobject accessibleContext, + AccessibleTextSelectionInfo *selectionInfo) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(%p):", + accessibleContext); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // Get the selection start index + if (getAccessibleTextSelectionStartFromContextMethod != (jmethodID) 0) { + selectionInfo->selectionStartIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTextSelectionStartFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleTextSelectionStart - call to CallIntMethod()", FALSE); + PrintDebugString(" Selection start = %d", selectionInfo->selectionStartIndex); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextSelectionStartFromContextMethod == 0"); + return FALSE; + } + + // Get the selection end index + if (getAccessibleTextSelectionEndFromContextMethod != (jmethodID) 0) { + selectionInfo->selectionEndIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTextSelectionEndFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleTextSelectionEnd - call to CallIntMethod()", FALSE); + PrintDebugString(" Selection end = %d", selectionInfo->selectionEndIndex); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextSelectionEndFromContextMethod == 0"); + return FALSE; + } + + // Get the selected text + if (getAccessibleTextSelectedTextFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTextSelectedTextFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringChars()", FALSE); + wcsncpy(selectionInfo->selectedText, stringBytes, (sizeof(selectionInfo->selectedText) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + selectionInfo->selectedText[length < (sizeof(selectionInfo->selectedText) / sizeof(wchar_t)) ? + length : (sizeof(selectionInfo->selectedText) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallVoidMethod()", FALSE); + PrintDebugString(" Accessible's selected text = %s", selectionInfo->selectedText); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible's selected text is null."); + selectionInfo->selectedText[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextSelectedTextFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleContext, jint index, AccessibleTextAttributesInfo *attributes) { + jstring js; + const wchar_t *stringBytes; + jobject AttributeSet; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(%p):", accessibleContext); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + if (accessibleContext == (jobject) 0) { + PrintDebugString(" passed in AccessibleContext == null! (oops)"); + + attributes->bold = FALSE; + attributes->italic = FALSE; + attributes->underline = FALSE; + attributes->strikethrough = FALSE; + attributes->superscript = FALSE; + attributes->subscript = FALSE; + attributes->backgroundColor[0] = (wchar_t) 0; + attributes->foregroundColor[0] = (wchar_t) 0; + attributes->fontFamily[0] = (wchar_t) 0; + attributes->fontSize = -1; + attributes->alignment = -1; + attributes->bidiLevel = -1; + attributes->firstLineIndent = -1; + attributes->leftIndent = -1; + attributes->rightIndent = -1; + attributes->lineSpacing = -1; + attributes->spaceAbove = -1; + attributes->spaceBelow = -1; + attributes->fullAttributesString[0] = (wchar_t) 0; + + return (FALSE); + } + + // Get the AttributeSet + if (getAccessibleAttributeSetAtIndexFromContextMethod != (jmethodID) 0) { + PrintDebugString(" Getting AttributeSet at index..."); + AttributeSet = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleAttributeSetAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to CallObjectMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleAttributeSetAtIndexFromContextMethod == 0"); + return FALSE; + } + + // It is legal for the AttributeSet object to be null, in which case we return false! + if (AttributeSet == (jobject) 0) { + PrintDebugString(" AttributeSet returned at index is null (this is legal! - see AWT in J2SE 1.3"); + + attributes->bold = FALSE; + attributes->italic = FALSE; + attributes->underline = FALSE; + attributes->strikethrough = FALSE; + attributes->superscript = FALSE; + attributes->subscript = FALSE; + attributes->backgroundColor[0] = (wchar_t) 0; + attributes->foregroundColor[0] = (wchar_t) 0; + attributes->fontFamily[0] = (wchar_t) 0; + attributes->fontSize = -1; + attributes->alignment = -1; + attributes->bidiLevel = -1; + attributes->firstLineIndent = -1; + attributes->leftIndent = -1; + attributes->rightIndent = -1; + attributes->lineSpacing = -1; + attributes->spaceAbove = -1; + attributes->spaceBelow = -1; + attributes->fullAttributesString[0] = (wchar_t) 0; + + return (FALSE); + } + + // Get the bold setting + if (getBoldFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting bold from AttributeSet..."); + attributes->bold = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getBoldFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getBoldFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the italic setting + if (getItalicFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting italic from AttributeSet..."); + attributes->italic = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getItalicFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getItalicdFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the underline setting + if (getUnderlineFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting underline from AttributeSet..."); + attributes->underline = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getUnderlineFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getUnderlineFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the strikethrough setting + if (getStrikethroughFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting strikethrough from AttributeSet..."); + attributes->strikethrough = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getStrikethroughFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getStrikethroughFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the superscript setting + if (getSuperscriptFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting superscript from AttributeSet..."); + attributes->superscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getSuperscriptFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getSuperscripteFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the subscript setting + if (getSubscriptFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting subscript from AttributeSet..."); + attributes->subscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getSubscriptFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getSubscriptFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the backgroundColor setting + if (getBackgroundColorFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting backgroundColor from AttributeSet..."); + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getBackgroundColorFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringChars()", FALSE); + wcsncpy(attributes->backgroundColor, stringBytes, (sizeof(attributes->backgroundColor) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + attributes->backgroundColor[length < (sizeof(attributes->backgroundColor) / sizeof(wchar_t)) ? + length : (sizeof(attributes->backgroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" AttributeSet's background color = %ls", attributes->backgroundColor); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AttributeSet's background color is null."); + attributes->backgroundColor[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getBackgroundColorFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the foregroundColor setting + if (getForegroundColorFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting foregroundColor from AttributeSet..."); + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getForegroundColorFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringChars()", FALSE); + wcsncpy(attributes->foregroundColor, stringBytes, (sizeof(attributes->foregroundColor) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + attributes->foregroundColor[length < (sizeof(attributes->foregroundColor) / sizeof(wchar_t)) ? + length : (sizeof(attributes->foregroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" AttributeSet's foreground color = %ls", attributes->foregroundColor); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AttributeSet's foreground color is null."); + attributes->foregroundColor[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getForegroundColorFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the fontFamily setting + if (getFontFamilyFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting fontFamily from AttributeSet..."); + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getFontFamilyFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringChars()", FALSE); + wcsncpy(attributes->fontFamily, stringBytes, (sizeof(attributes->fontFamily) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + attributes->fontFamily[length < (sizeof(attributes->fontFamily) / sizeof(wchar_t)) ? + length : (sizeof(attributes->fontFamily) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" AttributeSet's fontFamily = %ls", attributes->fontFamily); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AttributeSet's fontFamily is null."); + attributes->backgroundColor[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getFontFamilyFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the font size + if (getFontSizeFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting font size from AttributeSet..."); + attributes->fontSize = jniEnv->CallIntMethod(accessBridgeObject, + getFontSizeFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallIntMethod()", FALSE); + PrintDebugString(" AttributeSet's font size = %d", attributes->fontSize); + } else { + PrintDebugString(" Error! either env == 0 or getAlignmentFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + + // Get the alignment setting + if (getAlignmentFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting alignment from AttributeSet..."); + attributes->alignment = jniEnv->CallIntMethod(accessBridgeObject, + getAlignmentFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAlignmentFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the bidiLevel setting + if (getBidiLevelFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting bidiLevel from AttributeSet..."); + attributes->bidiLevel = jniEnv->CallIntMethod(accessBridgeObject, + getBidiLevelFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getBidiLevelFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the firstLineIndent setting + if (getFirstLineIndentFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting firstLineIndent from AttributeSet..."); + attributes->firstLineIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getFirstLineIndentFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getFirstLineIndentFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the leftIndent setting + if (getLeftIndentFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting leftIndent from AttributeSet..."); + attributes->leftIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getLeftIndentFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getLeftIndentFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the rightIndent setting + if (getRightIndentFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting rightIndent from AttributeSet..."); + attributes->rightIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getRightIndentFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getRightIndentFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the lineSpacing setting + if (getLineSpacingFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting lineSpacing from AttributeSet..."); + attributes->lineSpacing = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getLineSpacingFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getLineSpacingFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the spaceAbove setting + if (getSpaceAboveFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting spaceAbove from AttributeSet..."); + attributes->spaceAbove = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getSpaceAboveFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getSpaceAboveFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the spaceBelow setting + if (getSpaceBelowFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting spaceBelow from AttributeSet..."); + attributes->spaceBelow = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getSpaceBelowFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getSpaceBelowFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Release the AttributeSet object + if (decrementReferenceMethod != (jmethodID) 0) { + PrintDebugString(" Decrementing reference to AttributeSet..."); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Releasing AttributeSet object - call to CallVoidMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or accessBridgeObject == 0"); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Releasing AttributeSet object - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the full attributes string at index + if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) { + PrintDebugString(" Getting full attributes string from Context..."); + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleAttributesAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE); + wcsncpy(attributes->fullAttributesString, stringBytes, (sizeof(attributes->fullAttributesString) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + attributes->fullAttributesString[length < (sizeof(attributes->fullAttributesString) / sizeof(wchar_t)) ? + length : (sizeof(attributes->fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Text attributes = %ls", attributes->fullAttributesString); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Text attributes is null."); + attributes->fullAttributesString[0] = (wchar_t) 0; + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE); + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0"); + jniEnv->DeleteLocalRef(AttributeSet); + return FALSE; + } + + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to DeleteLocalRef()", FALSE); + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextRect(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) { + + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextRect(%p), index = %d", + accessibleContext, index); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // Get the x coord + if (getAccessibleXcoordTextRectAtIndexFromContextMethod != (jmethodID) 0) { + rectInfo->x = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleXcoordTextRectAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleXcoordTextRect - call to CallIntMethod()", FALSE); + PrintDebugString(" X coord = %d", rectInfo->x); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleXcoordTextRectAtIndexFromContextMethod == 0"); + return FALSE; + } + + // Get the y coord + if (getAccessibleYcoordTextRectAtIndexFromContextMethod != (jmethodID) 0) { + rectInfo->y = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleYcoordTextRectAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleYcoordTextRect - call to CallIntMethod()", FALSE); + PrintDebugString(" Y coord = %d", rectInfo->y); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleYcoordTextRectAtIndexFromContextMethod == 0"); + return FALSE; + } + + // Get the width + if (getAccessibleWidthTextRectAtIndexFromContextMethod != (jmethodID) 0) { + rectInfo->width = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleWidthTextRectAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleWidthTextRect - call to CallIntMethod()", FALSE); + PrintDebugString(" Width = %d", rectInfo->width); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleWidthTextRectAtIndexFromContextMethod == 0"); + return FALSE; + } + + // Get the height + if (getAccessibleHeightTextRectAtIndexFromContextMethod != (jmethodID) 0) { + rectInfo->height = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHeightTextRectAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleHeightTextRect - call to CallIntMethod()", FALSE); + PrintDebugString(" Height = %d", rectInfo->height); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleHeightTextRectAtIndexFromContextMethod == 0"); + return FALSE; + } + + return TRUE; +} + +// ===== + +/** + * gets the bounding rectangle for the text caret + */ +BOOL +AccessBridgeJavaEntryPoints::getCaretLocation(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) { + + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getCaretLocation(%p), index = %d", + accessibleContext, index); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // Get the x coord + if (getCaretLocationXMethod != (jmethodID) 0) { + rectInfo->x = jniEnv->CallIntMethod(accessBridgeObject, + getCaretLocationXMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting caret X coordinate - call to CallIntMethod()", FALSE); + PrintDebugString(" X coord = %d", rectInfo->x); + } else { + PrintDebugString(" Error! either env == 0 or getCaretLocationXMethod == 0"); + return FALSE; + } + + // Get the y coord + if (getCaretLocationYMethod != (jmethodID) 0) { + rectInfo->y = jniEnv->CallIntMethod(accessBridgeObject, + getCaretLocationYMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting caret Y coordinate - call to CallIntMethod()", FALSE); + PrintDebugString(" Y coord = %d", rectInfo->y); + } else { + PrintDebugString(" Error! either env == 0 or getCaretLocationYMethod == 0"); + return FALSE; + } + + // Get the width + if (getCaretLocationWidthMethod != (jmethodID) 0) { + rectInfo->width = jniEnv->CallIntMethod(accessBridgeObject, + getCaretLocationWidthMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting caret width - call to CallIntMethod()", FALSE); + PrintDebugString(" Width = %d", rectInfo->width); + } else { + PrintDebugString(" Error! either env == 0 or getCaretLocationWidthMethod == 0"); + return FALSE; + } + + // Get the height + if (getCaretLocationHeightMethod != (jmethodID) 0) { + rectInfo->height = jniEnv->CallIntMethod(accessBridgeObject, + getCaretLocationHeightMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting caret height - call to CallIntMethod()", FALSE); + PrintDebugString(" Height = %d", rectInfo->height); + } else { + PrintDebugString(" Error! either env == 0 or getCaretLocationHeightMethod == 0"); + return FALSE; + } + + return TRUE; +} + +// ===== + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(jobject accessibleContext, jint index, jint *startIndex, jint *endIndex) { + + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(%p):", accessibleContext); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // Get the index of the left boundary of the line containing 'index' + if (getAccessibleTextLineLeftBoundsFromContextMethod != (jmethodID) 0) { + *startIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTextLineLeftBoundsFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleTextLineLeftBounds - call to CallIntMethod()", FALSE); + PrintDebugString(" startIndex = %d", *startIndex); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextLineLeftBoundsFromContextMethod == 0"); + return FALSE; + } + + // Get the index of the right boundary of the line containing 'index' + if (getAccessibleTextLineRightBoundsFromContextMethod != (jmethodID) 0) { + *endIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTextLineRightBoundsFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleTextLineRightBounds - call to CallIntMethod()", FALSE); + PrintDebugString(" endIndex = %d", *endIndex); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextLineRightBoundsFromContextMethod == 0"); + return FALSE; + } + + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextRange(jobject accessibleContext, + jint start, jint end, wchar_t *text, short len) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextRange(%p, %d, %d, *text, %d):", accessibleContext, start, end, len); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // range is inclusive + if (end < start) { + PrintDebugString(" Error! end < start!"); + text[0] = (wchar_t) 0; + return FALSE; + } + + // Get the text range within [start, end] inclusive + if (getAccessibleTextRangeFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTextRangeFromContextMethod, + accessibleContext, start, end); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringChars()", FALSE); + wPrintDebugString(L" Accessible Text stringBytes returned from Java = %ls", stringBytes); + wcsncpy(text, stringBytes, len); + length = jniEnv->GetStringLength(js); + PrintDebugString(" Accessible Text stringBytes length = %d", length); + text[length < len ? length : len - 2] = (wchar_t) 0; + wPrintDebugString(L" Accessible Text 'text' after null termination = %ls", text); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Text range = %ls", text); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" current Accessible Text range is null."); + text[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextRangeFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + +/********** AccessibleValue routines ***************/ + +BOOL +AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(%p):", accessibleContext); + + // Get the current Accessible Value + if (getCurrentAccessibleValueFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getCurrentAccessibleValueFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringChars()", FALSE); + wcsncpy(value, stringBytes, len); + length = jniEnv->GetStringLength(js); + value[length < len ? length : len - 2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallVoidMethod()", FALSE); + PrintDebugString(" current Accessible Value = %s", value); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" current Accessible Value is null."); + value[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getCurrentAccessibleValueFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(%p):", accessibleContext); + + // Get the maximum Accessible Value + if (getMaximumAccessibleValueFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getMaximumAccessibleValueFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringChars()", FALSE); + wcsncpy(value, stringBytes, len); + length = jniEnv->GetStringLength(js); + value[length < len ? length : len - 2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallVoidMethod()", FALSE); + PrintDebugString(" maximum Accessible Value = %s", value); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" maximum Accessible Value is null."); + value[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getMaximumAccessibleValueFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(%p):", accessibleContext); + + // Get the mimimum Accessible Value + if (getMinimumAccessibleValueFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getMinimumAccessibleValueFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringChars()", FALSE); + wcsncpy(value, stringBytes, len); + length = jniEnv->GetStringLength(js); + value[length < len ? length : len - 2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallVoidMethod()", FALSE); + PrintDebugString(" mimimum Accessible Value = %s", value); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" mimimum Accessible Value is null."); + value[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getMinimumAccessibleValueFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + + +/********** AccessibleSelection routines ***************/ + +void +AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(jobject accessibleContext, int i) { + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(%p):", accessibleContext); + + // Add the child to the AccessibleSelection + if (addAccessibleSelectionFromContextMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + addAccessibleSelectionFromContextMethod, + accessibleContext, i); + EXCEPTION_CHECK_VOID("Doing addAccessibleSelection - call to CallVoidMethod()"); + PrintDebugString(" returned from CallObjectMethod()"); + } else { + PrintDebugString(" Error! either env == 0 or addAccessibleSelectionFromContextMethod == 0"); + } +} + +void +AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(jobject accessibleContext) { + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(%p):", accessibleContext); + + // Clearing the Selection of the AccessibleSelection + if (clearAccessibleSelectionFromContextMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + clearAccessibleSelectionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK_VOID("Doing clearAccessibleSelection - call to CallVoidMethod()"); + PrintDebugString(" returned from CallObjectMethod()"); + } else { + PrintDebugString(" Error! either env == 0 or clearAccessibleSelectionFromContextMethod == 0"); + } +} + +jobject +AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(jobject accessibleContext, int i) { + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(%p):", accessibleContext); + + if (getAccessibleSelectionContextFromContextMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod( + accessBridgeObject, + getAccessibleSelectionContextFromContextMethod, + accessibleContext, i); + EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to CallObjectMethod()", (jobject) 0); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to NewGlobalRef()", (jobject) 0); + jniEnv->DeleteLocalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to DeleteLocalRef()", (jobject) 0); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleSelectionContextFromContextMethod == 0"); + return (jobject) 0; + } +} + +int +AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(jobject accessibleContext) { + int count; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(%p):", accessibleContext); + + // Get (& return) the # of items selected in the AccessibleSelection + if (getAccessibleSelectionCountFromContextMethod != (jmethodID) 0) { + count = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleSelectionCountFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleSelectionCount - call to CallIntMethod()", -1); + PrintDebugString(" returned from CallObjectMethod()"); + return count; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleSelectionCountFromContextMethod == 0"); + return -1; + } +} + +BOOL +AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(jobject accessibleContext, int i) { + jboolean result; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(%p):", accessibleContext); + + // Get (& return) the # of items selected in the AccessibleSelection + if (isAccessibleChildSelectedFromContextMethod != (jmethodID) 0) { + result = jniEnv->CallBooleanMethod(accessBridgeObject, + isAccessibleChildSelectedFromContextMethod, + accessibleContext, i); + EXCEPTION_CHECK("Doing isAccessibleChildSelected - call to CallBooleanMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod()"); + if (result != 0) { + return TRUE; + } + } else { + PrintDebugString(" Error! either env == 0 or isAccessibleChildSelectedFromContextMethod == 0"); + } + return FALSE; +} + + +void +AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(jobject accessibleContext, int i) { + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(%p):", accessibleContext); + + // Remove the i-th child from the AccessibleSelection + if (removeAccessibleSelectionFromContextMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + removeAccessibleSelectionFromContextMethod, + accessibleContext, i); + EXCEPTION_CHECK_VOID("Doing removeAccessibleSelection - call to CallVoidMethod()"); + PrintDebugString(" returned from CallObjectMethod()"); + } else { + PrintDebugString(" Error! either env == 0 or removeAccessibleSelectionFromContextMethod == 0"); + } +} + +void +AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(jobject accessibleContext) { + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(%p):", accessibleContext); + + // Select all children (if possible) of the AccessibleSelection + if (selectAllAccessibleSelectionFromContextMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + selectAllAccessibleSelectionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK_VOID("Doing selectAllAccessibleSelection - call to CallVoidMethod()"); + PrintDebugString(" returned from CallObjectMethod()"); + } else { + PrintDebugString(" Error! either env == 0 or selectAllAccessibleSelectionFromContextMethod == 0"); + } +} + + +/********** Event Notification Registration routines ***************/ + +BOOL +AccessBridgeJavaEntryPoints::addJavaEventNotification(jlong type) { + jthrowable exception; + + PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::addJavaEventNotification(%016I64X);", type); + + // Let AccessBridge know we want to add an event type + if (addJavaEventNotificationMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + addJavaEventNotificationMethod, type); + EXCEPTION_CHECK("Doing addJavaEventNotification - call to CallVoidMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or addJavaEventNotificationMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::removeJavaEventNotification(jlong type) { + jthrowable exception; + + PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::removeJavaEventNotification(%016I64X):", type); + + // Let AccessBridge know we want to remove an event type + if (removeJavaEventNotificationMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + removeJavaEventNotificationMethod, type); + EXCEPTION_CHECK("Doing removeJavaEventNotification - call to CallVoidMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or removeJavaEventNotificationMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(jlong type) { + jthrowable exception; + + PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(%016I64X);", type); + + // Let AccessBridge know we want to add an event type + if (addAccessibilityEventNotificationMethod != (jmethodID) 0) { + PrintDebugString("\r\n addAccessibilityEventNotification: calling void method: accessBridgeObject = %p", accessBridgeObject); + jniEnv->CallVoidMethod(accessBridgeObject, + addAccessibilityEventNotificationMethod, type); + EXCEPTION_CHECK("Doing addAccessibilityEvent - call to CallVoidMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or addAccessibilityEventNotificationMethod == 0"); + return FALSE; + } + PrintDebugString("\r\n addAccessibilityEventNotification: just returning true"); + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(jlong type) { + jthrowable exception; + + PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(%016I64X):", type); + + // Let AccessBridge know we want to remove an event type + if (removeAccessibilityEventNotificationMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + removeAccessibilityEventNotificationMethod, type); + EXCEPTION_CHECK("Doing removeAccessibilityEvent - call to CallVoidMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or removeAccessibilityEventNotificationMethod == 0"); + return FALSE; + } + return TRUE; +} --- /dev/null 2015-03-30 10:55:23.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.h 2015-03-30 10:55:22.937710500 -0500 @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage JNI calls into AccessBridge.java + */ + +#include "AccessBridgePackages.h" + +#include +#include + +#ifndef __AccessBridgeJavaEntryPoints_H__ +#define __AccessBridgeJavaEntryPoints_H__ + +class AccessBridgeJavaEntryPoints { + JNIEnv *jniEnv; + + jobject accessBridgeObject; + + jclass bridgeClass; + jclass eventHandlerClass; + + jmethodID decrementReferenceMethod; + jmethodID getJavaVersionPropertyMethod; + jmethodID getAccessBridgeVersionMethod; + + jmethodID isJavaWindowMethod; + jmethodID isSameObjectMethod; + jmethodID getAccessibleContextFromHWNDMethod; + jmethodID getHWNDFromAccessibleContextMethod; + + jmethodID getAccessibleContextAtMethod; + jmethodID getAccessibleContextWithFocusMethod; + + jmethodID getAccessibleNameFromContextMethod; + jmethodID getAccessibleDescriptionFromContextMethod; + jmethodID getAccessibleRoleStringFromContextMethod; + jmethodID getAccessibleRoleStringFromContext_en_USMethod; + jmethodID getAccessibleStatesStringFromContextMethod; + jmethodID getAccessibleStatesStringFromContext_en_USMethod; + jmethodID getAccessibleParentFromContextMethod; + jmethodID getAccessibleIndexInParentFromContextMethod; + jmethodID getAccessibleChildrenCountFromContextMethod; + jmethodID getAccessibleChildFromContextMethod; + jmethodID getAccessibleBoundsOnScreenFromContextMethod; + jmethodID getAccessibleXcoordFromContextMethod; + jmethodID getAccessibleYcoordFromContextMethod; + jmethodID getAccessibleHeightFromContextMethod; + jmethodID getAccessibleWidthFromContextMethod; + + jmethodID getAccessibleComponentFromContextMethod; + jmethodID getAccessibleActionFromContextMethod; + jmethodID getAccessibleSelectionFromContextMethod; + jmethodID getAccessibleTextFromContextMethod; + jmethodID getAccessibleValueFromContextMethod; + + /* begin AccessibleTable */ + jmethodID getAccessibleTableFromContextMethod; + jmethodID getAccessibleTableRowHeaderMethod; + jmethodID getAccessibleTableColumnHeaderMethod; + jmethodID getAccessibleTableRowCountMethod; + jmethodID getAccessibleTableColumnCountMethod; + jmethodID getAccessibleTableCaptionMethod; + jmethodID getAccessibleTableSummaryMethod; + + jmethodID getContextFromAccessibleTableMethod; + jmethodID getAccessibleTableCellAccessibleContextMethod; + jmethodID getAccessibleTableCellIndexMethod; + jmethodID getAccessibleTableCellRowExtentMethod; + jmethodID getAccessibleTableCellColumnExtentMethod; + jmethodID isAccessibleTableCellSelectedMethod; + + jmethodID getAccessibleTableRowHeaderRowCountMethod; + jmethodID getAccessibleTableColumnHeaderRowCountMethod; + + jmethodID getAccessibleTableRowHeaderColumnCountMethod; + jmethodID getAccessibleTableColumnHeaderColumnCountMethod; + + jmethodID getAccessibleTableRowDescriptionMethod; + jmethodID getAccessibleTableColumnDescriptionMethod; + + jmethodID getAccessibleTableRowSelectionCountMethod; + jmethodID isAccessibleTableRowSelectedMethod; + jmethodID getAccessibleTableRowSelectionsMethod; + + jmethodID getAccessibleTableColumnSelectionCountMethod; + jmethodID isAccessibleTableColumnSelectedMethod; + jmethodID getAccessibleTableColumnSelectionsMethod; + + jmethodID getAccessibleTableRowMethod; + jmethodID getAccessibleTableColumnMethod; + jmethodID getAccessibleTableIndexMethod; + + /* end AccessibleTable */ + + /* begin AccessibleRelationSet */ + + jmethodID getAccessibleRelationSetMethod; + jmethodID getAccessibleRelationCountMethod; + jmethodID getAccessibleRelationKeyMethod; + jmethodID getAccessibleRelationTargetCountMethod; + jmethodID getAccessibleRelationTargetMethod; + + /* end AccessibleRelationSet */ + + // AccessibleHypertext methods + jmethodID getAccessibleHypertextMethod; + jmethodID getAccessibleHyperlinkCountMethod; + jmethodID getAccessibleHyperlinkTextMethod; + jmethodID getAccessibleHyperlinkURLMethod; + jmethodID getAccessibleHyperlinkStartIndexMethod; + jmethodID getAccessibleHyperlinkEndIndexMethod; + jmethodID getAccessibleHypertextLinkIndexMethod; + jmethodID getAccessibleHyperlinkMethod; + jmethodID activateAccessibleHyperlinkMethod; + + // AccessibleKeyBinding + jmethodID getAccessibleKeyBindingsCountMethod; + jmethodID getAccessibleKeyBindingCharMethod; + jmethodID getAccessibleKeyBindingModifiersMethod; + + // AccessibleIcon + jmethodID getAccessibleIconsCountMethod; + jmethodID getAccessibleIconDescriptionMethod; + jmethodID getAccessibleIconHeightMethod; + jmethodID getAccessibleIconWidthMethod; + + // AccessibleAction + jmethodID getAccessibleActionsCountMethod; + jmethodID getAccessibleActionNameMethod; + jmethodID doAccessibleActionsMethod; + + // AccessibleText + jmethodID getAccessibleCharCountFromContextMethod; + jmethodID getAccessibleCaretPositionFromContextMethod; + jmethodID getAccessibleIndexAtPointFromContextMethod; + + jmethodID getAccessibleLetterAtIndexFromContextMethod; + jmethodID getAccessibleWordAtIndexFromContextMethod; + jmethodID getAccessibleSentenceAtIndexFromContextMethod; + + jmethodID getAccessibleTextSelectionStartFromContextMethod; + jmethodID getAccessibleTextSelectionEndFromContextMethod; + jmethodID getAccessibleTextSelectedTextFromContextMethod; + jmethodID getAccessibleAttributesAtIndexFromContextMethod; + jmethodID getAccessibleAttributeSetAtIndexFromContextMethod; + jmethodID getAccessibleTextRectAtIndexFromContextMethod; + jmethodID getAccessibleXcoordTextRectAtIndexFromContextMethod; + jmethodID getAccessibleYcoordTextRectAtIndexFromContextMethod; + jmethodID getAccessibleHeightTextRectAtIndexFromContextMethod; + jmethodID getAccessibleWidthTextRectAtIndexFromContextMethod; + jmethodID getAccessibleTextLineLeftBoundsFromContextMethod; + jmethodID getAccessibleTextLineRightBoundsFromContextMethod; + jmethodID getAccessibleTextRangeFromContextMethod; + + jmethodID getCurrentAccessibleValueFromContextMethod; + jmethodID getMaximumAccessibleValueFromContextMethod; + jmethodID getMinimumAccessibleValueFromContextMethod; + + jmethodID addAccessibleSelectionFromContextMethod; + jmethodID clearAccessibleSelectionFromContextMethod; + jmethodID getAccessibleSelectionContextFromContextMethod; + jmethodID getAccessibleSelectionCountFromContextMethod; + jmethodID isAccessibleChildSelectedFromContextMethod; + jmethodID removeAccessibleSelectionFromContextMethod; + jmethodID selectAllAccessibleSelectionFromContextMethod; + + jmethodID addJavaEventNotificationMethod; + jmethodID removeJavaEventNotificationMethod; + jmethodID addAccessibilityEventNotificationMethod; + jmethodID removeAccessibilityEventNotificationMethod; + + jmethodID getBoldFromAttributeSetMethod; + jmethodID getItalicFromAttributeSetMethod; + jmethodID getUnderlineFromAttributeSetMethod; + jmethodID getStrikethroughFromAttributeSetMethod; + jmethodID getSuperscriptFromAttributeSetMethod; + jmethodID getSubscriptFromAttributeSetMethod; + jmethodID getBackgroundColorFromAttributeSetMethod; + jmethodID getForegroundColorFromAttributeSetMethod; + jmethodID getFontFamilyFromAttributeSetMethod; + jmethodID getFontSizeFromAttributeSetMethod; + jmethodID getAlignmentFromAttributeSetMethod; + jmethodID getBidiLevelFromAttributeSetMethod; + jmethodID getFirstLineIndentFromAttributeSetMethod; + jmethodID getLeftIndentFromAttributeSetMethod; + jmethodID getRightIndentFromAttributeSetMethod; + jmethodID getLineSpacingFromAttributeSetMethod; + jmethodID getSpaceAboveFromAttributeSetMethod; + jmethodID getSpaceBelowFromAttributeSetMethod; + + jmethodID setTextContentsMethod; + jmethodID getParentWithRoleMethod; + jmethodID getTopLevelObjectMethod; + jmethodID getParentWithRoleElseRootMethod; + jmethodID getObjectDepthMethod; + jmethodID getActiveDescendentMethod; + + /** + * Additional methods for Teton + */ + jmethodID getVirtualAccessibleNameFromContextMethod; // Ben Key + jmethodID requestFocusMethod; + jmethodID selectTextRangeMethod; + jmethodID getTextAttributesInRangeMethod; + jmethodID getVisibleChildrenCountMethod; + jmethodID getVisibleChildMethod; + jmethodID setCaretPositionMethod; + + jmethodID getCaretLocationMethod; + jmethodID getCaretLocationXMethod; + jmethodID getCaretLocationYMethod; + jmethodID getCaretLocationHeightMethod; + jmethodID getCaretLocationWidthMethod; + +public: + AccessBridgeJavaEntryPoints(JNIEnv *jniEnvironment, jobject bridgeObject); + ~AccessBridgeJavaEntryPoints(); + BOOL BuildJavaEntryPoints(); + + // HWND management methods + BOOL isJavaWindow(jint window); + jobject getAccessibleContextFromHWND(jint window); + HWND getHWNDFromAccessibleContext(jobject accessibleContext); + + // version methods + BOOL getVersionInfo(AccessBridgeVersionInfo *info); + + // verification methods + BOOL verifyAccessibleText(jobject obj); + + /* ===== utility methods ===== */ + BOOL isSameObject(jobject obj1, jobject obj2); + BOOL setTextContents(const jobject accessibleContext, const wchar_t *text); + jobject getParentWithRole (const jobject accessibleContext, const wchar_t *role); + jobject getTopLevelObject (const jobject accessibleContext); + jobject getParentWithRoleElseRoot (const jobject accessibleContext, const wchar_t *role); + jint getObjectDepth (const jobject accessibleContext); + jobject getActiveDescendent (const jobject accessibleContext); + + // Accessible Context methods + jobject getAccessibleContextAt(jint x, jint y, jobject AccessibleContext); + jobject getAccessibleContextWithFocus(); + BOOL getAccessibleContextInfo(jobject AccessibleContext, AccessibleContextInfo *info); + jobject getAccessibleChildFromContext(jobject AccessibleContext, jint childIndex); + jobject getAccessibleParentFromContext(jobject AccessibleContext); + + /* begin AccessibleTable methods */ + + BOOL getAccessibleTableInfo(jobject acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableCellInfo(jobject accessibleTable,jint row, jint column, + AccessibleTableCellInfo *tableCellInfo); + + BOOL getAccessibleTableRowHeader(jobject acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableColumnHeader(jobject acParent, AccessibleTableInfo *tableInfo); + + jobject getAccessibleTableRowDescription(jobject acParent, jint row); + jobject getAccessibleTableColumnDescription(jobject acParent, jint column); + + jint getAccessibleTableRowSelectionCount(jobject accessibleTable); + BOOL isAccessibleTableRowSelected(jobject accessibleTable, jint row); + BOOL getAccessibleTableRowSelections(jobject accessibleTable, jint count, jint *selections); + + jint getAccessibleTableColumnSelectionCount(jobject accessibleTable); + BOOL isAccessibleTableColumnSelected(jobject accessibleTable, jint column); + BOOL getAccessibleTableColumnSelections(jobject accessibleTable, jint count, jint *selections); + + jint getAccessibleTableRow(jobject accessibleTable, jint index); + jint getAccessibleTableColumn(jobject accessibleTable, jint index); + jint getAccessibleTableIndex(jobject accessibleTable, jint row, jint column); + + /* end AccessibleTable methods */ + + BOOL getAccessibleRelationSet(jobject accessibleContext, AccessibleRelationSetInfo *relationSetInfo); + + // AccessibleHypertext methods + BOOL getAccessibleHypertext(jobject accessibleContext, AccessibleHypertextInfo *hyperlink); + + BOOL activateAccessibleHyperlink(jobject accessibleContext, jobject accessibleHyperlink); + + BOOL getAccessibleHypertextExt(const jobject accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertext); + jint getAccessibleHyperlinkCount(const jobject accessibleContext); + jint getAccessibleHypertextLinkIndex(const jobject accessibleContext, + const jint nIndex); + BOOL getAccessibleHyperlink(const jobject accessibleContext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + // Accessible Keybinding methods + BOOL getAccessibleKeyBindings(jobject accessibleContext, AccessibleKeyBindings *keyBindings); + + // AccessibleIcon methods + BOOL getAccessibleIcons(jobject accessibleContext, AccessibleIcons *icons); + + // AccessibleActionMethods + BOOL getAccessibleActions(jobject accessibleContext, AccessibleActions *actions); + BOOL doAccessibleActions(jobject accessibleContext, AccessibleActionsToDo *actionsToDo, jint *failure); + + // Accessible Text methods + BOOL getAccessibleTextInfo(jobject AccessibleContext, AccessibleTextInfo *textInfo, jint x, jint y); + BOOL getAccessibleTextItems(jobject AccessibleContext, AccessibleTextItemsInfo *textItems, jint index); + BOOL getAccessibleTextSelectionInfo(jobject AccessibleContext, AccessibleTextSelectionInfo *selectionInfo); + BOOL getAccessibleTextAttributes(jobject AccessibleContext, jint index, AccessibleTextAttributesInfo *attributes); + BOOL getAccessibleTextRect(jobject AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + BOOL getAccessibleCaretRect(jobject AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + BOOL getAccessibleTextLineBounds(jobject AccessibleContext, jint index, jint *startIndex, jint *endIndex); + BOOL getAccessibleTextRange(jobject AccessibleContext, jint start, jint end, wchar_t *text, short len); + + // Accessible Value methods + BOOL getCurrentAccessibleValueFromContext(jobject AccessibleContext, wchar_t *value, short len); + BOOL getMaximumAccessibleValueFromContext(jobject AccessibleContext, wchar_t *value, short len); + BOOL getMinimumAccessibleValueFromContext(jobject AccessibleContext, wchar_t *value, short len); + + // Accessible Selection methods + void addAccessibleSelectionFromContext(jobject AccessibleContext, int i); + void clearAccessibleSelectionFromContext(jobject AccessibleContext); + jobject getAccessibleSelectionFromContext(jobject AccessibleContext, int i); + int getAccessibleSelectionCountFromContext(jobject AccessibleContext); + BOOL isAccessibleChildSelectedFromContext(jobject AccessibleContext, int i); + void removeAccessibleSelectionFromContext(jobject AccessibleContext, int i); + void selectAllAccessibleSelectionFromContext(jobject AccessibleContext); + + // Event handling methods + BOOL addJavaEventNotification(jlong type); + BOOL removeJavaEventNotification(jlong type); + BOOL addAccessibilityEventNotification(jlong type); + BOOL removeAccessibilityEventNotification(jlong type); + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(const jobject accessibleContext, wchar_t *name, int len); + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(const jobject accessibleContext); + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(const jobject accessibleContext, int startIndex, int endIndex); + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(const jobject accessibleContext, int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + /** + * Gets the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(const jobject accessibleContext); + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(const jobject accessibleContext, const int startIndex, + VisibleChildrenInfo *visibleChildrenInfo); + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const jobject accessibleContext, int position); + + /** + * Gets the bounding rectangle for the text caret + */ + BOOL getCaretLocation(jobject AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + +}; + +#endif --- /dev/null 2015-03-30 10:55:27.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp 2015-03-30 10:55:26.046720900 -0500 @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to track key JVM instance info from the AT WinAccessBridge + */ + +#include "AccessBridgeDebug.h" +#include "AccessBridgeJavaVMInstance.h" +#include "AccessBridgeMessages.h" +#include "AccessBridgePackages.h" +#include "accessBridgeResource.h" // for debugging messages + +#include +#include + +// The initialization must only be done one time and to provide for that the initialization +// is now done in WinAccessBridge and the CRITICAL_SECTION memory has been moved to there. +// send memory lock +//CRITICAL_SECTION sendMemoryIPCLock; +extern CRITICAL_SECTION sendMemoryIPCLock; + +// protects the javaVMs chain while in use +extern bool isVMInstanceChainInUse; + +DEBUG_CODE(extern HWND theDialogWindow); +extern "C" { + DEBUG_CODE(void AppendToCallInfo(char *s)); +} + + +/** + * + * + */ +AccessBridgeJavaVMInstance::AccessBridgeJavaVMInstance(HWND ourABWindow, + HWND javaABWindow, + long javaVMID, + AccessBridgeJavaVMInstance *next) { + goingAway = FALSE; + // This should be called once. Moved to WinAccessBridge c'tor + //InitializeCriticalSection(&sendMemoryIPCLock); + ourAccessBridgeWindow = ourABWindow; + javaAccessBridgeWindow = javaABWindow; + vmID = javaVMID; + nextJVMInstance = next; + memoryMappedFileMapHandle = (HANDLE) 0; + memoryMappedView = (char *) 0; + sprintf(memoryMappedFileName, "AccessBridge-%p-%p.mmf", + ourAccessBridgeWindow, javaAccessBridgeWindow); +} + +/** + * + * + */ +AccessBridgeJavaVMInstance::~AccessBridgeJavaVMInstance() { + DEBUG_CODE(char buffer[256]); + + DEBUG_CODE(AppendToCallInfo("***** in AccessBridgeJavaVMInstance::~AccessBridgeJavaVMInstance\r\n")); + EnterCriticalSection(&sendMemoryIPCLock); + + // if IPC memory mapped file view is valid, unmap it + goingAway = TRUE; + if (memoryMappedView != (char *) 0) { + DEBUG_CODE(sprintf(buffer, " unmapping memoryMappedView; view = %p\r\n", memoryMappedView)); + DEBUG_CODE(AppendToCallInfo(buffer)); + UnmapViewOfFile(memoryMappedView); + memoryMappedView = (char *) 0; + } + // if IPC memory mapped file handle map is open, close it + if (memoryMappedFileMapHandle != (HANDLE) 0) { + DEBUG_CODE(sprintf(buffer, " closing memoryMappedFileMapHandle; handle = %p\r\n", memoryMappedFileMapHandle)); + DEBUG_CODE(AppendToCallInfo(buffer)); + CloseHandle(memoryMappedFileMapHandle); + memoryMappedFileMapHandle = (HANDLE) 0; + } + LeaveCriticalSection(&sendMemoryIPCLock); + +} + +/** + * initiateIPC - sets up the memory-mapped file to do IPC messaging + * 1 file is created: to handle requests for information + * initiated from Windows AT. The package is placed into + * the memory-mapped file (char *memoryMappedView), + * and then a special SendMessage() is sent. When the + * JavaDLL returns from SendMessage() processing, the + * data will be in memoryMappedView. The SendMessage() + * return value tells us if all is right with the world. + * + * The set-up proces involves creating the memory-mapped + * file, and handshaking with the JavaDLL so it knows + * about it as well. + * + */ +LRESULT +AccessBridgeJavaVMInstance::initiateIPC() { + DEBUG_CODE(char debugBuf[256]); + DWORD errorCode; + + DEBUG_CODE(AppendToCallInfo(" in AccessBridgeJavaVMInstance::initiateIPC()\r\n")); + + // create Windows-initiated IPC file & map it to a ptr + memoryMappedFileMapHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, 0, + // 8 bytes for return code + sizeof(WindowsInitiatedPackages) + 8, + memoryMappedFileName); + if (memoryMappedFileMapHandle == NULL) { + errorCode = GetLastError(); + DEBUG_CODE(sprintf(debugBuf, " Failed to CreateFileMapping for %s, error: %X", memoryMappedFileName, errorCode)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + return errorCode; + } else { + DEBUG_CODE(sprintf(debugBuf, " CreateFileMapping worked - filename: %s\r\n", memoryMappedFileName)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + } + + memoryMappedView = (char *) MapViewOfFile(memoryMappedFileMapHandle, + FILE_MAP_READ | FILE_MAP_WRITE, + 0, 0, 0); + if (memoryMappedView == NULL) { + errorCode = GetLastError(); + DEBUG_CODE(sprintf(debugBuf, " Failed to MapViewOfFile for %s, error: %X", memoryMappedFileName, errorCode)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + return errorCode; + } else { + DEBUG_CODE(sprintf(debugBuf, " MapViewOfFile worked - view: %p\r\n", memoryMappedView)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + } + + + // write some data to the memory mapped file + strcpy(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_QUERY); + + + // inform the JavaDLL that we've a memory mapped file ready for it + char buffer[sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage)]; + PackageType *type = (PackageType *) buffer; + MemoryMappedFileCreatedPackage *pkg = (MemoryMappedFileCreatedPackage *) (buffer + sizeof(PackageType)); + *type = cMemoryMappedFileCreatedPackage; + pkg->bridgeWindow = ABHandleToLong(ourAccessBridgeWindow); + strncpy(pkg->filename, memoryMappedFileName, cMemoryMappedNameSize); + sendPackage(buffer, sizeof(buffer)); + + + // look for the JavaDLL's answer to see if it could read the file + if (strcmp(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_ANSWER) != 0) { + DEBUG_CODE(sprintf(debugBuf, " JavaVM failed to deal with memory mapped file %s\r\n", + memoryMappedFileName)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + return -1; + } else { + DEBUG_CODE(sprintf(debugBuf, " Success! JavaVM accpeted our file\r\n")); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + } + + return 0; +} + +// ----------------------- + +/** + * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging + * with the Java AccessBridge DLL + * + * NOTE: WM_COPYDATA is only for one-way IPC; there + * is now way to return parameters (especially big ones) + * Use sendMemoryPackage() to do that! + */ +LRESULT +AccessBridgeJavaVMInstance::sendPackage(char *buffer, long bufsize) { + COPYDATASTRUCT toCopy; + toCopy.dwData = 0; // 32-bits we could use for something... + toCopy.cbData = bufsize; + toCopy.lpData = buffer; + + PrintDebugString("In AccessBridgeVMInstance::sendPackage"); + PrintDebugString(" javaAccessBridgeWindow: %p", javaAccessBridgeWindow); + /* This was SendMessage. Normally that is a blocking call. However, if + * SendMessage is sent to another process, e.g. another JVM and an incoming + * SendMessage is pending, control will be passed to the DialogProc to handle + * the incoming message. A bug occurred where this allowed an AB_DLL_GOING_AWAY + * message to be processed deleting an AccessBridgeJavaVMInstance object in + * the javaVMs chain. SendMessageTimeout with SMTO_BLOCK set will prevent the + * calling thread from processing other requests while waiting, i.e control + * will not be passed to the DialogProc. Also note that PostMessage or + * SendNotifyMessage can't be used. Although they don't allow transfer to + * the DialogProc they can't be used in cases where pointers are passed. This + * is because the referenced memory needs to be available when the other thread + * gets control. + */ + UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG; + DWORD_PTR out; // not used + LRESULT lr = SendMessageTimeout( javaAccessBridgeWindow, WM_COPYDATA, + (WPARAM)ourAccessBridgeWindow, (LPARAM)&toCopy, + flags, 4000, &out ); + return lr; +} + + +/** + * sendMemoryPackage - uses Memory-Mapped files to do IPC messaging + * with the Java AccessBridge DLL, informing the + * Java AccessBridge DLL via SendMessage that something + * is waiting for it in the shared file... + * + * In the SendMessage call, the third param (WPARAM) is + * the source HWND (ourAccessBridgeWindow in this case), + * and the fourth param (LPARAM) is the size in bytes of + * the package put into shared memory. + * + */ +BOOL +AccessBridgeJavaVMInstance::sendMemoryPackage(char *buffer, long bufsize) { + + // Protect against race condition where the memory mapped file is + // deallocated before the memory package is being sent + if (goingAway) { + return FALSE; + } + BOOL retval = FALSE; + + DEBUG_CODE(char outputBuf[256]); + DEBUG_CODE(sprintf(outputBuf, "AccessBridgeJavaVMInstance::sendMemoryPackage(, %d)", bufsize)); + DEBUG_CODE(AppendToCallInfo(outputBuf)); + + DEBUG_CODE(PackageType *type = (PackageType *) buffer); + DEBUG_CODE(if (*type == cGetAccessibleTextRangePackage) {) + DEBUG_CODE(AppendToCallInfo(" 'buffer' contains:")); + DEBUG_CODE(GetAccessibleTextRangePackage *pkg = (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType))); + DEBUG_CODE(sprintf(outputBuf, " PackageType = %X", *type)); + DEBUG_CODE(AppendToCallInfo(outputBuf)); + DEBUG_CODE(sprintf(outputBuf, " GetAccessibleTextRange: start = %d, end = %d, rText = %ls", + pkg->start, pkg->end, pkg->rText)); + DEBUG_CODE(AppendToCallInfo(outputBuf)); + DEBUG_CODE(}) + + EnterCriticalSection(&sendMemoryIPCLock); + { + // copy the package into shared memory + if (!goingAway) { + memcpy(memoryMappedView, buffer, bufsize); + + DEBUG_CODE(PackageType *type = (PackageType *) memoryMappedView); + DEBUG_CODE(if (*type == cGetAccessibleTextItemsPackage) {) + DEBUG_CODE(AppendToCallInfo(" 'memoryMappedView' now contains:")); + DEBUG_CODE(GetAccessibleTextItemsPackage *pkg = (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType))); + DEBUG_CODE(sprintf(outputBuf, " PackageType = %X", *type)); + DEBUG_CODE(AppendToCallInfo(outputBuf)); + DEBUG_CODE(}) + } + + if (!goingAway) { + // Let the recipient know there is a package waiting for them. The unset byte + // at end of buffer which will only be set if message is properly received + char *done = &memoryMappedView[bufsize]; + *done = 0; + + PrintDebugString(" javaAccessBridgeWindow: %p", javaAccessBridgeWindow); + // See the comment above the call to SendMessageTimeout in SendPackage method above. + UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG; + DWORD_PTR out; // not used + SendMessageTimeout( javaAccessBridgeWindow, AB_MESSAGE_WAITING, (WPARAM)ourAccessBridgeWindow, (LPARAM)bufsize, + flags, 4000, &out ); + + // only succeed if message has been properly received + if(!goingAway) retval = (*done == 1); + } + + // copy the package back from shared memory + if (!goingAway) { + memcpy(buffer, memoryMappedView, bufsize); + } + } + LeaveCriticalSection(&sendMemoryIPCLock); + return retval; +} + + +/** + * findAccessBridgeWindow - walk through linked list from where we are, + * return the HWND of the ABJavaVMInstance that + * matches the passed in vmID; no match: return 0 + * + */ +HWND +AccessBridgeJavaVMInstance::findAccessBridgeWindow(long javaVMID) { + PrintDebugString("In findAccessBridgeWindow"); + // no need to recurse really + if (vmID == javaVMID) { + return javaAccessBridgeWindow; + } else { + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = nextJVMInstance; + while (current != (AccessBridgeJavaVMInstance *) 0) { + if (current->vmID == javaVMID) { + isVMInstanceChainInUse = false; + return current->javaAccessBridgeWindow; + } + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; + } + return 0; +} + +/** + * findABJavaVMInstanceFromJavaHWND - walk through linked list from + * where we are. Return the + * AccessBridgeJavaVMInstance + * of the ABJavaVMInstance that + * matches the passed in vmID; + * no match: return 0 + */ +AccessBridgeJavaVMInstance * +AccessBridgeJavaVMInstance::findABJavaVMInstanceFromJavaHWND(HWND window) { + PrintDebugString("In findABJavaInstanceFromJavaHWND"); + // no need to recurse really + if (javaAccessBridgeWindow == window) { + return this; + } else { + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = nextJVMInstance; + while (current != (AccessBridgeJavaVMInstance *) 0) { + if (current->javaAccessBridgeWindow == window) { + isVMInstanceChainInUse = false; + return current; + } + current = current->nextJVMInstance; + } + } + isVMInstanceChainInUse = false; + return (AccessBridgeJavaVMInstance *) 0; +} --- /dev/null 2015-03-30 10:55:30.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.h 2015-03-30 10:55:29.185733700 -0500 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to track key JVM instance info from the AT WinAccessBridge + */ + +#ifndef __AccessBridgeJavaVMInstance_H__ +#define __AccessBridgeJavaVMInstance_H__ + +#include "AccessBridgePackages.h" + +#include +#include + +/** + * The AccessBridgeJavaVMInstance class. + */ +class AccessBridgeJavaVMInstance { + friend class WinAccessBridge; + + AccessBridgeJavaVMInstance *nextJVMInstance; + HWND ourAccessBridgeWindow; + HWND javaAccessBridgeWindow; + long vmID; + + // IPC variables + HANDLE memoryMappedFileMapHandle; // handle to file map + char *memoryMappedView; // ptr to shared memory + char memoryMappedFileName[cMemoryMappedNameSize]; + BOOL goingAway; + + +public: + AccessBridgeJavaVMInstance(HWND ourABWindow, HWND javaABWindow, + long javaVMID, + AccessBridgeJavaVMInstance *next); + ~AccessBridgeJavaVMInstance(); + LRESULT initiateIPC(); + LRESULT sendPackage(char *buffer, long bufsize); + BOOL sendMemoryPackage(char *buffer, long bufsize); + HWND findAccessBridgeWindow(long javaVMID); + AccessBridgeJavaVMInstance *findABJavaVMInstanceFromJavaHWND(HWND window); +}; + +#endif --- /dev/null 2015-03-30 10:55:33.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp 2015-03-30 10:55:32.355744200 -0500 @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage queueing of messages for IPC + */ + +#include "AccessBridgeDebug.h" +#include "AccessBridgeMessageQueue.h" +#include "AccessBridgePackages.h" // for debugging only +#include +#include + +DEBUG_CODE(extern HWND theDialogWindow); +extern "C" { + DEBUG_CODE(void AppendToCallInfo(char *s)); +} + +// ------------------- + + +AccessBridgeQueueElement::AccessBridgeQueueElement(char *buf, int size) { + bufsize = size; + next = (AccessBridgeQueueElement *) 0; + previous = (AccessBridgeQueueElement *) 0; + buffer = (char *) malloc(bufsize); + memcpy(buffer, buf, bufsize); +} + +AccessBridgeQueueElement::~AccessBridgeQueueElement() { + // delete buffer; + free(buffer); +} + + +// ------------------- + + +AccessBridgeMessageQueue::AccessBridgeMessageQueue() { + queueLocked = FALSE; + queueRemoveLocked = FALSE; + start = (AccessBridgeQueueElement *) 0; + end = (AccessBridgeQueueElement *) 0; + size = 0; +} + +AccessBridgeMessageQueue::~AccessBridgeMessageQueue() { + // empty queue, then exit +} + +/** + * getEventsWaiting - gets the number of events waiting to fire + */ +int +AccessBridgeMessageQueue::getEventsWaiting() { + return size; +} + +/** + * add - add an element to the queue, which is locked with semaphores + * + */ +QueueReturns +AccessBridgeMessageQueue::add(AccessBridgeQueueElement *element) { + PrintDebugString(" in AccessBridgeMessageQueue::add()"); + PrintDebugString(" queue size = %d", size); + + QueueReturns returnVal = cElementPushedOK; + if (queueLocked) { + PrintDebugString(" queue was locked; returning cQueueInUse!"); + return cQueueInUse; + } + queueLocked = TRUE; + { + PrintDebugString(" adding element to queue!"); + if (end == (AccessBridgeQueueElement *) 0) { + if (start == (AccessBridgeQueueElement *) 0 && size == 0) { + start = element; + end = element; + element->previous = (AccessBridgeQueueElement *) 0; + element->next = (AccessBridgeQueueElement *) 0; + size++; + } else { + returnVal = cQueueBroken; // bad voodo! + } + } else { + element->previous = end; + element->next = (AccessBridgeQueueElement *) 0; + end->next = element; + end = element; + size++; + } + } + queueLocked = FALSE; + PrintDebugString(" returning from AccessBridgeMessageQueue::add()"); + return returnVal; +} + + +/** + * remove - remove an element from the queue, which is locked with semaphores + * + */ +QueueReturns +AccessBridgeMessageQueue::remove(AccessBridgeQueueElement **element) { + PrintDebugString(" in AccessBridgeMessageQueue::remove()"); + PrintDebugString(" queue size = %d", size); + + QueueReturns returnVal = cMoreMessages; + if (queueLocked) { + PrintDebugString(" queue was locked; returning cQueueInUse!"); + return cQueueInUse; + } + queueLocked = TRUE; + { + PrintDebugString(" removing element from queue!"); + if (size > 0) { + if (start != (AccessBridgeQueueElement *) 0) { + *element = start; + start = start->next; + if (start != (AccessBridgeQueueElement *) 0) { + start->previous = (AccessBridgeQueueElement *) 0; + } else { + end = (AccessBridgeQueueElement *) 0; + if (size != 1) { + returnVal = cQueueBroken; // bad voodo, should only be 1 in this situation + } + } + size--; + } else { + returnVal = cQueueBroken; // bad voodo! + } + } else { + returnVal = cQueueEmpty; + } + } + queueLocked = FALSE; + PrintDebugString(" returning from AccessBridgeMessageQueue::remove()"); + return returnVal; +} + + +/** + * setRemoveLock - set the state of the removeLock (TRUE or FALSE) + * + */ +QueueReturns +AccessBridgeMessageQueue::setRemoveLock(BOOL removeLockSetting) { + if (queueLocked) { + return cQueueInUse; + } + queueRemoveLocked = removeLockSetting; + + return cQueueOK; +} + +/** + * setRemoveLock - set the state of the removeLock (TRUE or FALSE) + * + */ +BOOL +AccessBridgeMessageQueue::getRemoveLockSetting() { + return queueRemoveLocked; +} --- /dev/null 2015-03-30 10:55:36.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeMessageQueue.h 2015-03-30 10:55:35.475755300 -0500 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage queueing of messages for IPC + */ + +#include + +#ifndef __AccessBridgeMessageQueue_H__ +#define __AccessBridgeMessageQueue_H__ + + +enum QueueReturns { + cQueueEmpty = 0, + cMoreMessages = 1, + cQueueInUse, + cElementPushedOK, + cQueueFull, + cQueueOK, + cQueueBroken // shouldn't ever happen! +}; + +class AccessBridgeQueueElement { + friend class AccessBridgeMessageQueue; + friend class WinAccessBridge; + char *buffer; + int bufsize; + AccessBridgeQueueElement *next; + AccessBridgeQueueElement *previous; + +public: + AccessBridgeQueueElement(char *buf, int size); + ~AccessBridgeQueueElement(); +}; + +class AccessBridgeMessageQueue { + BOOL queueLocked; + BOOL queueRemoveLocked; + AccessBridgeQueueElement *start; + AccessBridgeQueueElement *end; + int size; + +public: + AccessBridgeMessageQueue(); + ~AccessBridgeMessageQueue(); + + int getEventsWaiting(); + + QueueReturns add(AccessBridgeQueueElement *element); + QueueReturns remove(AccessBridgeQueueElement **element); + QueueReturns setRemoveLock(BOOL removeLockSetting); + BOOL getRemoveLockSetting(); +}; + + +#endif --- /dev/null 2015-03-30 10:55:39.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeMessages.cpp 2015-03-30 10:55:38.592762800 -0500 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Common AccessBridge IPC message definitions + */ + +#include "AccessBridgeMessages.h" + + +// unique broadcast msg. IDs gotten dymanically + +// wParam == sourceHwnc; lParam = *vmID +UINT theFromJavaHelloMsgID; +// wParam == sourceHwnc; lParam unused +UINT theFromWindowsHelloMsgID; + + +BOOL initBroadcastMessageIDs() { + theFromJavaHelloMsgID = RegisterWindowMessage("AccessBridge-FromJava-Hello"); + theFromWindowsHelloMsgID = RegisterWindowMessage("AccessBridge-FromWindows-Hello"); + + if (theFromJavaHelloMsgID == 0 || theFromWindowsHelloMsgID) { + return FALSE; + } + return TRUE; +} --- /dev/null 2015-03-30 10:55:43.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeMessages.h 2015-03-30 10:55:42.283807700 -0500 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Common AccessBridge IPC message definitions + */ + +#include +#include + +#ifndef __AccessBridgeMessages_H__ +#define __AccessBridgeMessages_H__ + + +// used for messages between AccessBridge dlls to manage IPC +// In the SendMessage call, the third param (WPARAM) is +// the source HWND (ourAccessBridgeWindow in this case), +// and the fourth param (LPARAM) is the size in bytes of +// the package put into shared memory. +#define AB_MEMORY_MAPPED_FILE_SETUP (WM_USER+0x1000) + +// used for messages between AccessBridge dlls to manage IPC +// In the SendMessage call, the third param (WPARAM) is +// the source HWND (ourAccessBridgeWindow in this case), +// and the fourth param (LPARAM) is the size in bytes of +// the package put into shared memory. +#define AB_MESSAGE_WAITING (WM_USER+0x1001) + +// used for messages from JavaDLL to itself (or perhaps later also +// for messages from WindowsDLL to itself). Used with PostMessage, +// it is called for deferred processing of messages to send across +// to another DLL (or DLLs) +#define AB_MESSAGE_QUEUED (WM_USER+0x1002) + +// used to let other AccessBridge DLLs know that one of the DLLs +// they are communicating with is going away (not reversable) +#define AB_DLL_GOING_AWAY (WM_USER+0x1003) + + +// used as part of the Memory-Mapped file IPC setup. The first +// constant is the query, the second the response, that are put +// into the memory mapped file for reading by the opposite DLL +// to verify that communication is working +#define AB_MEMORY_MAPPED_FILE_OK_QUERY "OK?" +#define AB_MEMORY_MAPPED_FILE_OK_ANSWER "OK!" + + +BOOL initBroadcastMessageIDs(); + + +#endif --- /dev/null 2015-03-30 10:55:46.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgePackages.h 2015-03-30 10:55:45.583826800 -0500 @@ -0,0 +1,2215 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Header file for packages of paramaters passed between Java Accessibility + * and native Assistive Technologies + */ + +#ifndef __AccessBridgePackages_H__ +#define __AccessBridgePackages_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef ACCESSBRIDGE_ARCH_LEGACY +typedef jobject JOBJECT64; +typedef HWND ABHWND64; +#define ABHandleToLong +#define ABLongToHandle +#else +typedef jlong JOBJECT64; +typedef long ABHWND64; +#define ABHandleToLong HandleToLong +#define ABLongToHandle LongToHandle +#endif + +#define MAX_BUFFER_SIZE 10240 +#define MAX_STRING_SIZE 1024 +#define SHORT_STRING_SIZE 256 + + // object types + typedef JOBJECT64 AccessibleContext; + typedef JOBJECT64 AccessibleText; + typedef JOBJECT64 AccessibleValue; + typedef JOBJECT64 AccessibleSelection; + typedef JOBJECT64 Java_Object; + typedef JOBJECT64 PropertyChangeEvent; + typedef JOBJECT64 FocusEvent; + typedef JOBJECT64 CaretEvent; + typedef JOBJECT64 MouseEvent; + typedef JOBJECT64 MenuEvent; + typedef JOBJECT64 AccessibleTable; + typedef JOBJECT64 AccessibleHyperlink; + typedef JOBJECT64 AccessibleHypertext; + + /** + ****************************************************** + * Java event types + ****************************************************** + */ + +#define cPropertyChangeEvent (jlong) 1 // 1 +#define cFocusGainedEvent (jlong) 2 // 2 +#define cFocusLostEvent (jlong) 4 // 4 +#define cCaretUpdateEvent (jlong) 8 // 8 +#define cMouseClickedEvent (jlong) 16 // 10 +#define cMouseEnteredEvent (jlong) 32 // 20 +#define cMouseExitedEvent (jlong) 64 // 40 +#define cMousePressedEvent (jlong) 128 // 80 +#define cMouseReleasedEvent (jlong) 256 // 100 +#define cMenuCanceledEvent (jlong) 512 // 200 +#define cMenuDeselectedEvent (jlong) 1024 // 400 +#define cMenuSelectedEvent (jlong) 2048 // 800 +#define cPopupMenuCanceledEvent (jlong) 4096 // 1000 +#define cPopupMenuWillBecomeInvisibleEvent (jlong) 8192 // 2000 +#define cPopupMenuWillBecomeVisibleEvent (jlong) 16384 // 4000 +#define cJavaShutdownEvent (jlong) 32768 // 8000 + + /** + ****************************************************** + * Accessible Roles + * Defines all AccessibleRoles in Local.US + ****************************************************** + */ + + /** + * Object is used to alert the user about something. + */ +#define ACCESSIBLE_ALERT L"alert" + + /** + * The header for a column of data. + */ +#define ACCESSIBLE_COLUMN_HEADER L"column header" + + /** + * Object that can be drawn into and is used to trap + * events. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_CANVAS L"canvas" + + /** + * A list of choices the user can select from. Also optionally + * allows the user to enter a choice of their own. + */ +#define ACCESSIBLE_COMBO_BOX L"combo box" + + /** + * An iconified internal frame in a DESKTOP_PANE. + * see ACCESSIBLE_DESKTOP_PANE + * see ACCESSIBLE_INTERNAL_FRAME + */ +#define ACCESSIBLE_DESKTOP_ICON L"desktop icon" + + /** + * A frame-like object that is clipped by a desktop pane. The + * desktop pane, internal frame, and desktop icon objects are + * often used to create multiple document interfaces within an + * application. + * see ACCESSIBLE_DESKTOP_ICON + * see ACCESSIBLE_DESKTOP_PANE + * see ACCESSIBLE_FRAME + */ +#define ACCESSIBLE_INTERNAL_FRAME L"internal frame" + + /** + * A pane that supports internal frames and + * iconified versions of those internal frames. + * see ACCESSIBLE_DESKTOP_ICON + * see ACCESSIBLE_INTERNAL_FRAME + */ +#define ACCESSIBLE_DESKTOP_PANE L"desktop pane" + + /** + * A specialized pane whose primary use is inside a DIALOG + * see ACCESSIBLE_DIALOG + */ +#define ACCESSIBLE_OPTION_PANE L"option pane" + + /** + * A top level window with no title or border. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_DIALOG + */ +#define ACCESSIBLE_WINDOW L"window" + + /** + * A top level window with a title bar, border, menu bar, etc. It is + * often used as the primary window for an application. + * see ACCESSIBLE_DIALOG + * see ACCESSIBLE_CANVAS + * see ACCESSIBLE_WINDOW + */ +#define ACCESSIBLE_FRAME L"frame" + + /** + * A top level window with title bar and a border. A dialog is similar + * to a frame, but it has fewer properties and is often used as a + * secondary window for an application. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_WINDOW + */ +#define ACCESSIBLE_DIALOG L"dialog" + + /** + * A specialized dialog that lets the user choose a color. + */ +#define ACCESSIBLE_COLOR_CHOOSER L"color chooser" + + + /** + * A pane that allows the user to navigate through + * and select the contents of a directory. May be used + * by a file chooser. + * see ACCESSIBLE_FILE_CHOOSER + */ +#define ACCESSIBLE_DIRECTORY_PANE L"directory pane" + + /** + * A specialized dialog that displays the files in the directory + * and lets the user select a file, browse a different directory, + * or specify a filename. May use the directory pane to show the + * contents of a directory. + * see ACCESSIBLE_DIRECTORY_PANE + */ +#define ACCESSIBLE_FILE_CHOOSER L"file chooser" + + /** + * An object that fills up space in a user interface. It is often + * used in interfaces to tweak the spacing between components, + * but serves no other purpose. + */ +#define ACCESSIBLE_FILLER L"filler" + + /** + * A hypertext anchor + */ +#define ACCESSIBLE_HYPERLINK L"hyperlink" + + /** + * A small fixed size picture, typically used to decorate components. + */ +#define ACCESSIBLE_ICON L"icon" + + /** + * An object used to present an icon or short string in an interface. + */ +#define ACCESSIBLE_LABEL L"label" + + /** + * A specialized pane that has a glass pane and a layered pane as its + * children. + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_ROOT_PANE L"root pane" + + /** + * A pane that is guaranteed to be painted on top + * of all panes beneath it. + * see ACCESSIBLE_ROOT_PANE + * see ACCESSIBLE_CANVAS + */ +#define ACCESSIBLE_GLASS_PANE L"glass pane" + + /** + * A specialized pane that allows its children to be drawn in layers, + * providing a form of stacking order. This is usually the pane that + * holds the menu bar as well as the pane that contains most of the + * visual components in a window. + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_ROOT_PANE + */ +#define ACCESSIBLE_LAYERED_PANE L"layered pane" + + /** + * An object that presents a list of objects to the user and allows the + * user to select one or more of them. A list is usually contained + * within a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + * see ACCESSIBLE_LIST_ITEM + */ +#define ACCESSIBLE_LIST L"list" + + /** + * An object that presents an element in a list. A list is usually + * contained within a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + * see ACCESSIBLE_LIST + */ +#define ACCESSIBLE_LIST_ITEM L"list item" + + /** + * An object usually drawn at the top of the primary dialog box of + * an application that contains a list of menus the user can choose + * from. For example, a menu bar might contain menus for "File," + * "Edit," and "Help." + * see ACCESSIBLE_MENU + * see ACCESSIBLE_POPUP_MENU + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_MENU_BAR L"menu bar" + + /** + * A temporary window that is usually used to offer the user a + * list of choices, and then hides when the user selects one of + * those choices. + * see ACCESSIBLE_MENU + * see ACCESSIBLE_MENU_ITEM + */ +#define ACCESSIBLE_POPUP_MENU L"popup menu" + + /** + * An object usually found inside a menu bar that contains a list + * of actions the user can choose from. A menu can have any object + * as its children, but most often they are menu items, other menus, + * or rudimentary objects such as radio buttons, check boxes, or + * separators. For example, an application may have an "Edit" menu + * that contains menu items for "Cut" and "Paste." + * see ACCESSIBLE_MENU_BAR + * see ACCESSIBLE_MENU_ITEM + * see ACCESSIBLE_SEPARATOR + * see ACCESSIBLE_RADIO_BUTTON + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_POPUP_MENU + */ +#define ACCESSIBLE_MENU L"menu" + + /** + * An object usually contained in a menu that presents an action + * the user can choose. For example, the "Cut" menu item in an + * "Edit" menu would be an action the user can select to cut the + * selected area of text in a document. + * see ACCESSIBLE_MENU_BAR + * see ACCESSIBLE_SEPARATOR + * see ACCESSIBLE_POPUP_MENU + */ +#define ACCESSIBLE_MENU_ITEM L"menu item" + + /** + * An object usually contained in a menu to provide a visual + * and logical separation of the contents in a menu. For example, + * the "File" menu of an application might contain menu items for + * "Open," "Close," and "Exit," and will place a separator between + * "Close" and "Exit" menu items. + * see ACCESSIBLE_MENU + * see ACCESSIBLE_MENU_ITEM + */ +#define ACCESSIBLE_SEPARATOR L"separator" + + /** + * An object that presents a series of panels (or page tabs), one at a + * time, through some mechanism provided by the object. The most common + * mechanism is a list of tabs at the top of the panel. The children of + * a page tab list are all page tabs. + * see ACCESSIBLE_PAGE_TAB + */ +#define ACCESSIBLE_PAGE_TAB_LIST L"page tab list" + + /** + * An object that is a child of a page tab list. Its sole child is + * the panel that is to be presented to the user when the user + * selects the page tab from the list of tabs in the page tab list. + * see ACCESSIBLE_PAGE_TAB_LIST + */ +#define ACCESSIBLE_PAGE_TAB L"page tab" + + /** + * A generic container that is often used to group objects. + */ +#define ACCESSIBLE_PANEL L"panel" + + /** + * An object used to indicate how much of a task has been completed. + */ +#define ACCESSIBLE_PROGRESS_BAR L"progress bar" + + /** + * A text object used for passwords, or other places where the + * text contents is not shown visibly to the user + */ +#define ACCESSIBLE_PASSWORD_TEXT L"password text" + + /** + * An object the user can manipulate to tell the application to do + * something. + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_PUSH_BUTTON L"push button" + + /** + * A specialized push button that can be checked or unchecked, but + * does not provide a separate indicator for the current state. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_TOGGLE_BUTTON L"toggle button" + + /** + * A choice that can be checked or unchecked and provides a + * separate indicator for the current state. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_CHECK_BOX L"check box" + + /** + * A specialized check box that will cause other radio buttons in the + * same group to become unchecked when this one is checked. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_CHECK_BOX + */ +#define ACCESSIBLE_RADIO_BUTTON L"radio button" + + /** + * The header for a row of data. + */ +#define ACCESSIBLE_ROW_HEADER L"row header" + + /** + * An object that allows a user to incrementally view a large amount + * of information. Its children can include scroll bars and a viewport. + * see ACCESSIBLE_SCROLL_BAR + * see ACCESSIBLE_VIEWPORT + */ +#define ACCESSIBLE_SCROLL_PANE L"scroll pane" + + /** + * An object usually used to allow a user to incrementally view a + * large amount of data. Usually used only by a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + */ +#define ACCESSIBLE_SCROLL_BAR L"scroll bar" + + /** + * An object usually used in a scroll pane. It represents the portion + * of the entire data that the user can see. As the user manipulates + * the scroll bars, the contents of the viewport can change. + * see ACCESSIBLE_SCROLL_PANE + */ +#define ACCESSIBLE_VIEWPORT L"viewport" + + /** + * An object that allows the user to select from a bounded range. For + * example, a slider might be used to select a number between 0 and 100. + */ +#define ACCESSIBLE_SLIDER L"slider" + + /** + * A specialized panel that presents two other panels at the same time. + * Between the two panels is a divider the user can manipulate to make + * one panel larger and the other panel smaller. + */ +#define ACCESSIBLE_SPLIT_PANE L"split pane" + + /** + * An object used to present information in terms of rows and columns. + * An example might include a spreadsheet application. + */ +#define ACCESSIBLE_TABLE L"table" + + /** + * An object that presents text to the user. The text is usually + * editable by the user as opposed to a label. + * see ACCESSIBLE_LABEL + */ +#define ACCESSIBLE_TEXT L"text" + + /** + * An object used to present hierarchical information to the user. + * The individual nodes in the tree can be collapsed and expanded + * to provide selective disclosure of the tree's contents. + */ +#define ACCESSIBLE_TREE L"tree" + + /** + * A bar or palette usually composed of push buttons or toggle buttons. + * It is often used to provide the most frequently used functions for an + * application. + */ +#define ACCESSIBLE_TOOL_BAR L"tool bar" + + /** + * An object that provides information about another object. The + * accessibleDescription property of the tool tip is often displayed + * to the user in a small L"help bubble" when the user causes the + * mouse to hover over the object associated with the tool tip. + */ +#define ACCESSIBLE_TOOL_TIP L"tool tip" + + /** + * An AWT component, but nothing else is known about it. + * see ACCESSIBLE_SWING_COMPONENT + * see ACCESSIBLE_UNKNOWN + */ +#define ACCESSIBLE_AWT_COMPONENT L"awt component" + + /** + * A Swing component, but nothing else is known about it. + * see ACCESSIBLE_AWT_COMPONENT + * see ACCESSIBLE_UNKNOWN + */ +#define ACCESSIBLE_SWING_COMPONENT L"swing component" + + /** + * The object contains some Accessible information, but its role is + * not known. + * see ACCESSIBLE_AWT_COMPONENT + * see ACCESSIBLE_SWING_COMPONENT + */ +#define ACCESSIBLE_UNKNOWN L"unknown" + + /** + * A STATUS_BAR is an simple component that can contain + * multiple labels of status information to the user. + */ +#define ACCESSIBLE_STATUS_BAR L"status bar" + + /** + * A DATE_EDITOR is a component that allows users to edit + * java.util.Date and java.util.Time objects + */ +#define ACCESSIBLE_DATE_EDITOR L"date editor" + + /** + * A SPIN_BOX is a simple spinner component and its main use + * is for simple numbers. + */ +#define ACCESSIBLE_SPIN_BOX L"spin box" + + /** + * A FONT_CHOOSER is a component that lets the user pick various + * attributes for fonts. + */ +#define ACCESSIBLE_FONT_CHOOSER L"font chooser" + + /** + * A GROUP_BOX is a simple container that contains a border + * around it and contains components inside it. + */ +#define ACCESSIBLE_GROUP_BOX L"group box" + + /** + * A text header + */ +#define ACCESSIBLE_HEADER L"header" + + /** + * A text footer + */ +#define ACCESSIBLE_FOOTER L"footer" + + /** + * A text paragraph + */ +#define ACCESSIBLE_PARAGRAPH L"paragraph" + + /** + * A ruler is an object used to measure distance + */ +#define ACCESSIBLE_RULER L"ruler" + + /** + * A role indicating the object acts as a formula for + * calculating a value. An example is a formula in + * a spreadsheet cell. + */ +#define ACCESSIBLE_EDITBAR L"editbar" + + /** + * A role indicating the object monitors the progress + * of some operation. + */ +#define PROGRESS_MONITOR L"progress monitor" + + + /** + ****************************************************** + * Accessibility event types + ****************************************************** + */ + +#define cPropertyNameChangeEvent (jlong) 1 // 1 +#define cPropertyDescriptionChangeEvent (jlong) 2 // 2 +#define cPropertyStateChangeEvent (jlong) 4 // 4 +#define cPropertyValueChangeEvent (jlong) 8 // 8 +#define cPropertySelectionChangeEvent (jlong) 16 // 10 +#define cPropertyTextChangeEvent (jlong) 32 // 20 +#define cPropertyCaretChangeEvent (jlong) 64 // 40 +#define cPropertyVisibleDataChangeEvent (jlong) 128 // 80 +#define cPropertyChildChangeEvent (jlong) 256 // 100 +#define cPropertyActiveDescendentChangeEvent (jlong) 512 // 200 +#define cPropertyTableModelChangeEvent (jlong) 1024 // 400 + + /** + ****************************************************** + * optional AccessibleContext interfaces + * + * This version of the bridge reuses the accessibleValue + * field in the AccessibleContextInfo struct to represent + * additional optional interfaces that are supported by + * the Java AccessibleContext. This is backwardly compatable + * because the old accessibleValue was set to the BOOL + * value TRUE (i.e., 1) if the AccessibleValue interface is + * supported. + ****************************************************** + */ + +#define cAccessibleValueInterface (jlong) 1 // 1 << 1 (TRUE) +#define cAccessibleActionInterface (jlong) 2 // 1 << 2 +#define cAccessibleComponentInterface (jlong) 4 // 1 << 3 +#define cAccessibleSelectionInterface (jlong) 8 // 1 << 4 +#define cAccessibleTableInterface (jlong) 16 // 1 << 5 +#define cAccessibleTextInterface (jlong) 32 // 1 << 6 +#define cAccessibleHypertextInterface (jlong) 64 // 1 << 7 + + + /** + ****************************************************** + * Accessibility information bundles + ****************************************************** + */ + + typedef struct AccessBridgeVersionInfoTag { + wchar_t VMversion[SHORT_STRING_SIZE]; // output of "java -version" + wchar_t bridgeJavaClassVersion[SHORT_STRING_SIZE]; // version of the AccessBridge.class + wchar_t bridgeJavaDLLVersion[SHORT_STRING_SIZE]; // version of JavaAccessBridge.dll + wchar_t bridgeWinDLLVersion[SHORT_STRING_SIZE]; // version of WindowsAccessBridge.dll + } AccessBridgeVersionInfo; + + + typedef struct AccessibleContextInfoTag { + wchar_t name[MAX_STRING_SIZE]; // the AccessibleName of the object + wchar_t description[MAX_STRING_SIZE]; // the AccessibleDescription of the object + + wchar_t role[SHORT_STRING_SIZE]; // localized AccesibleRole string + wchar_t role_en_US[SHORT_STRING_SIZE]; // AccesibleRole string in the en_US locale + wchar_t states[SHORT_STRING_SIZE]; // localized AccesibleStateSet string (comma separated) + wchar_t states_en_US[SHORT_STRING_SIZE]; // AccesibleStateSet string in the en_US locale (comma separated) + + jint indexInParent; // index of object in parent + jint childrenCount; // # of children, if any + + jint x; // screen coords in pixels + jint y; // " + jint width; // pixel width of object + jint height; // pixel height of object + + BOOL accessibleComponent; // flags for various additional + BOOL accessibleAction; // Java Accessibility interfaces + BOOL accessibleSelection; // FALSE if this object doesn't + BOOL accessibleText; // implement the additional interface + // in question + + // BOOL accessibleValue; // old BOOL indicating whether AccessibleValue is supported + BOOL accessibleInterfaces; // new bitfield containing additional interface flags + + } AccessibleContextInfo; + + + + // AccessibleText packages + typedef struct AccessibleTextInfoTag { + jint charCount; // # of characters in this text object + jint caretIndex; // index of caret + jint indexAtPoint; // index at the passsed in point + } AccessibleTextInfo; + + typedef struct AccessibleTextItemsInfoTag { + wchar_t letter; + wchar_t word[SHORT_STRING_SIZE]; + wchar_t sentence[MAX_STRING_SIZE]; + } AccessibleTextItemsInfo; + + typedef struct AccessibleTextSelectionInfoTag { + jint selectionStartIndex; + jint selectionEndIndex; + wchar_t selectedText[MAX_STRING_SIZE]; + } AccessibleTextSelectionInfo; + + typedef struct AccessibleTextRectInfoTag { + jint x; // bounding rect of char at index + jint y; // " + jint width; // " + jint height; // " + } AccessibleTextRectInfo; + + // standard attributes for text; note: tabstops are not supported + typedef struct AccessibleTextAttributesInfoTag { + BOOL bold; + BOOL italic; + BOOL underline; + BOOL strikethrough; + BOOL superscript; + BOOL subscript; + + wchar_t backgroundColor[SHORT_STRING_SIZE]; + wchar_t foregroundColor[SHORT_STRING_SIZE]; + wchar_t fontFamily[SHORT_STRING_SIZE]; + jint fontSize; + + jint alignment; + jint bidiLevel; + + jfloat firstLineIndent; + jfloat leftIndent; + jfloat rightIndent; + jfloat lineSpacing; + jfloat spaceAbove; + jfloat spaceBelow; + + wchar_t fullAttributesString[MAX_STRING_SIZE]; + } AccessibleTextAttributesInfo; + + /** + ****************************************************** + * IPC management typedefs + ****************************************************** + */ + +#define cMemoryMappedNameSize 255 + + /** + * sent by the WindowsDLL -> the memory-mapped file is setup + * + */ + typedef struct MemoryMappedFileCreatedPackageTag { +// HWND bridgeWindow; // redundant, but easier to get to here... + ABHWND64 bridgeWindow; // redundant, but easier to get to here... + char filename[cMemoryMappedNameSize]; + } MemoryMappedFileCreatedPackage; + + + + + /** + * sent when a new JavaVM attaches to the Bridge + * + */ + typedef struct JavaVMCreatedPackageTag { + ABHWND64 bridgeWindow; + long vmID; + } JavaVMCreatedPackage; + + /** + * sent when a JavaVM detatches from the Bridge + * + */ + typedef struct JavaVMDestroyedPackageTag { + ABHWND64 bridgeWindow; + } JavaVMDestroyedPackage; + + /** + * sent when a new AT attaches to the Bridge + * + */ + typedef struct WindowsATCreatedPackageTag { + ABHWND64 bridgeWindow; + } WindowsATCreatedPackage; + + /** + * sent when an AT detatches from the Bridge + * + */ + typedef struct WindowsATDestroyedPackageTag { + ABHWND64 bridgeWindow; + } WindowsATDestroyedPackage; + + + /** + * sent by JVM Bridges in response to a WindowsATCreate + * message; saying "howdy, welcome to the neighborhood" + * + */ + typedef struct JavaVMPresentNotificationPackageTag { + ABHWND64 bridgeWindow; + long vmID; + } JavaVMPresentNotificationPackage; + + /** + * sent by AT Bridges in response to a JavaVMCreate + * message; saying "howdy, welcome to the neighborhood" + * + */ + typedef struct WindowsATPresentNotificationPackageTag { + ABHWND64 bridgeWindow; + } WindowsATPresentNotificationPackage; + + + /** + ****************************************************** + * Core packages + ****************************************************** + */ + + typedef struct ReleaseJavaObjectPackageTag { + long vmID; + JOBJECT64 object; + } ReleaseJavaObjectPackage; + + typedef struct GetAccessBridgeVersionPackageTag { + long vmID; // can't get VM info w/out a VM! + AccessBridgeVersionInfo rVersionInfo; + } GetAccessBridgeVersionPackage; + + typedef struct IsSameObjectPackageTag { + long vmID; + JOBJECT64 obj1; + JOBJECT64 obj2; + jboolean rResult; + } IsSameObjectPackage; + + /** + ****************************************************** + * Windows packages + ****************************************************** + */ + + typedef struct IsJavaWindowPackageTag { + jint window; + jboolean rResult; + } IsJavaWindowPackage; + + typedef struct GetAccessibleContextFromHWNDPackageTag { + jint window; + long rVMID; + JOBJECT64 rAccessibleContext; + } GetAccessibleContextFromHWNDPackage; + + typedef struct GetHWNDFromAccessibleContextPackageTag { + JOBJECT64 accessibleContext; + ABHWND64 rHWND; + } GetHWNDFromAccessibleContextPackage; + + /** +****************************************************** +* AccessibleContext packages +****************************************************** +*/ + + typedef struct GetAccessibleContextAtPackageTag { + jint x; + jint y; + long vmID; + JOBJECT64 AccessibleContext; // look within this AC + JOBJECT64 rAccessibleContext; + } GetAccessibleContextAtPackage; + + typedef struct GetAccessibleContextWithFocusPackageTag { + long rVMID; + JOBJECT64 rAccessibleContext; + } GetAccessibleContextWithFocusPackage; + + typedef struct GetAccessibleContextInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + AccessibleContextInfo rAccessibleContextInfo; + } GetAccessibleContextInfoPackage; + + typedef struct GetAccessibleChildFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint childIndex; + JOBJECT64 rAccessibleContext; + } GetAccessibleChildFromContextPackage; + + typedef struct GetAccessibleParentFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + JOBJECT64 rAccessibleContext; + } GetAccessibleParentFromContextPackage; + + /** +****************************************************** +* AccessibleTable packages +****************************************************** +*/ + +#define MAX_TABLE_SELECTIONS 64 + + // table information + typedef struct AccessibleTableInfoTag { + JOBJECT64 caption; // AccesibleContext + JOBJECT64 summary; // AccessibleContext + jint rowCount; + jint columnCount; + JOBJECT64 accessibleContext; + JOBJECT64 accessibleTable; + } AccessibleTableInfo; + + typedef struct GetAccessibleTableInfoPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableInfoPackage; + + // table cell information + typedef struct AccessibleTableCellInfoTag { + JOBJECT64 accessibleContext; + jint index; + jint row; + jint column; + jint rowExtent; + jint columnExtent; + jboolean isSelected; + } AccessibleTableCellInfo; + + typedef struct GetAccessibleTableCellInfoPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jint column; + AccessibleTableCellInfo rTableCellInfo; + } GetAccessibleTableCellInfoPackage; + + typedef struct GetAccessibleTableRowHeaderPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableRowHeaderPackage; + + typedef struct GetAccessibleTableColumnHeaderPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableColumnHeaderPackage; + + typedef struct GetAccessibleTableRowDescriptionPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint row; + JOBJECT64 rAccessibleContext; + } GetAccessibleTableRowDescriptionPackage; + + typedef struct GetAccessibleTableColumnDescriptionPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint column; + JOBJECT64 rAccessibleContext; + } GetAccessibleTableColumnDescriptionPackage; + + typedef struct GetAccessibleTableRowSelectionCountPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint rCount; + } GetAccessibleTableRowSelectionCountPackage; + + typedef struct IsAccessibleTableRowSelectedPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jboolean rResult; + } IsAccessibleTableRowSelectedPackage; + + typedef struct GetAccessibleTableRowSelectionsPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint count; + jint rSelections[MAX_TABLE_SELECTIONS]; + } GetAccessibleTableRowSelectionsPackage; + + typedef struct GetAccessibleTableColumnSelectionCountPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint rCount; + } GetAccessibleTableColumnSelectionCountPackage; + + typedef struct IsAccessibleTableColumnSelectedPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint column; + jboolean rResult; + } IsAccessibleTableColumnSelectedPackage; + + typedef struct GetAccessibleTableColumnSelectionsPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint count; + jint rSelections[MAX_TABLE_SELECTIONS]; + } GetAccessibleTableColumnSelectionsPackage; + + + typedef struct GetAccessibleTableRowPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint index; + jint rRow; + } GetAccessibleTableRowPackage; + + typedef struct GetAccessibleTableColumnPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint index; + jint rColumn; + } GetAccessibleTableColumnPackage; + + typedef struct GetAccessibleTableIndexPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jint column; + jint rIndex; + } GetAccessibleTableIndexPackage; + + + /** + ****************************************************** + * AccessibleRelationSet packages + ****************************************************** + */ + +#define MAX_RELATION_TARGETS 25 +#define MAX_RELATIONS 5 + + typedef struct AccessibleRelationInfoTag { + wchar_t key[SHORT_STRING_SIZE]; + jint targetCount; + JOBJECT64 targets[MAX_RELATION_TARGETS]; // AccessibleContexts + } AccessibleRelationInfo; + + typedef struct AccessibleRelationSetInfoTag { + jint relationCount; + AccessibleRelationInfo relations[MAX_RELATIONS]; + } AccessibleRelationSetInfo; + + typedef struct GetAccessibleRelationSetPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleRelationSetInfo rAccessibleRelationSetInfo; + } GetAccessibleRelationSetPackage; + + /** + ****************************************************** + * AccessibleHypertext packagess + ****************************************************** + */ + +#define MAX_HYPERLINKS 64 // maximum number of hyperlinks returned + + // hyperlink information + typedef struct AccessibleHyperlinkInfoTag { + wchar_t text[SHORT_STRING_SIZE]; // the hyperlink text + jint startIndex; //index in the hypertext document where the link begins + jint endIndex; //index in the hypertext document where the link ends + JOBJECT64 accessibleHyperlink; // AccessibleHyperlink object + } AccessibleHyperlinkInfo; + + // hypertext information + typedef struct AccessibleHypertextInfoTag { + jint linkCount; // number of hyperlinks + AccessibleHyperlinkInfo links[MAX_HYPERLINKS]; // the hyperlinks + JOBJECT64 accessibleHypertext; // AccessibleHypertext object + } AccessibleHypertextInfo; + + // struct for sending a message to get the hypertext for an AccessibleContext + typedef struct GetAccessibleHypertextPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext with hypertext + AccessibleHypertextInfo rAccessibleHypertextInfo; // returned hypertext + } GetAccessibleHypertextPackage; + + // struct for sending an message to activate a hyperlink + typedef struct ActivateAccessibleHyperlinkPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext containing the link + JOBJECT64 accessibleHyperlink; // the link to activate + BOOL rResult; // hyperlink activation return value + } ActivateAccessibleHyperlinkPackage; + + // struct for sending a message to get the number of hyperlinks in a component + typedef struct GetAccessibleHyperlinkCountPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext containing AccessibleHypertext + jint rLinkCount; // link count return value + } GetAccessibleHyperlinkCountPackage; + + // struct for sending a message to get the hypertext for an AccessibleContext + // starting at a specified index in the document + typedef struct GetAccessibleHypertextExtPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext with hypertext + jint startIndex; // start index in document + AccessibleHypertextInfo rAccessibleHypertextInfo; // returned hypertext + BOOL rSuccess; // whether call succeeded + } GetAccessibleHypertextExtPackage; + + // struct for sending a message to get the nth hyperlink in a document; + // maps to AccessibleHypertext.getLink + typedef struct GetAccessibleHyperlinkPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 hypertext; // AccessibleHypertext + jint linkIndex; // hyperlink index + AccessibleHyperlinkInfo rAccessibleHyperlinkInfo; // returned hyperlink + } GetAccessibleHyperlinkPackage; + + // struct for sending a message to get the index into an array + // of hyperlinks that is associated with a character index in a + // document; maps to AccessibleHypertext.getLinkIndex + typedef struct GetAccessibleHypertextLinkIndexPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 hypertext; // AccessibleHypertext + jint charIndex; // character index in document + jint rLinkIndex; // returned hyperlink index + } GetAccessibleHypertextLinkIndexPackage; + + /** + ****************************************************** + * Accessible Key Bindings packages + ****************************************************** + */ + +#define MAX_KEY_BINDINGS 10 + + // keyboard character modifiers +#define ACCESSIBLE_SHIFT_KEYSTROKE 1 +#define ACCESSIBLE_CONTROL_KEYSTROKE 2 +#define ACCESSIBLE_META_KEYSTROKE 4 +#define ACCESSIBLE_ALT_KEYSTROKE 8 +#define ACCESSIBLE_ALT_GRAPH_KEYSTROKE 16 +#define ACCESSIBLE_BUTTON1_KEYSTROKE 32 +#define ACCESSIBLE_BUTTON2_KEYSTROKE 64 +#define ACCESSIBLE_BUTTON3_KEYSTROKE 128 +#define ACCESSIBLE_FKEY_KEYSTROKE 256 // F key pressed, character contains 1-24 +#define ACCESSIBLE_CONTROLCODE_KEYSTROKE 512 // Control code key pressed, character contains control code. + +// The supported control code keys are: +#define ACCESSIBLE_VK_BACK_SPACE 8 +#define ACCESSIBLE_VK_DELETE 127 +#define ACCESSIBLE_VK_DOWN 40 +#define ACCESSIBLE_VK_END 35 +#define ACCESSIBLE_VK_HOME 36 +#define ACCESSIBLE_VK_INSERT 155 +#define ACCESSIBLE_VK_KP_DOWN 225 +#define ACCESSIBLE_VK_KP_LEFT 226 +#define ACCESSIBLE_VK_KP_RIGHT 227 +#define ACCESSIBLE_VK_KP_UP 224 +#define ACCESSIBLE_VK_LEFT 37 +#define ACCESSIBLE_VK_PAGE_DOWN 34 +#define ACCESSIBLE_VK_PAGE_UP 33 +#define ACCESSIBLE_VK_RIGHT 39 +#define ACCESSIBLE_VK_UP 38 + + // a key binding associates with a component + typedef struct AccessibleKeyBindingInfoTag { + jchar character; // the key character + jint modifiers; // the key modifiers + } AccessibleKeyBindingInfo; + + // all of the key bindings associated with a component + typedef struct AccessibleKeyBindingsTag { + int keyBindingsCount; // number of key bindings + AccessibleKeyBindingInfo keyBindingInfo[MAX_KEY_BINDINGS]; + } AccessibleKeyBindings; + + // struct to get the key bindings associated with a component + typedef struct GetAccessibleKeyBindingsPackageTag { + long vmID; // the virtual machine id + JOBJECT64 accessibleContext; // the component + AccessibleKeyBindings rAccessibleKeyBindings; // the key bindings + } GetAccessibleKeyBindingsPackage; + + /** +****************************************************** +* AccessibleIcon packages +****************************************************** +*/ +#define MAX_ICON_INFO 8 + + // an icon assocated with a component + typedef struct AccessibleIconInfoTag { + wchar_t description[SHORT_STRING_SIZE]; // icon description + jint height; // icon height + jint width; // icon width + } AccessibleIconInfo; + + // all of the icons associated with a component + typedef struct AccessibleIconsTag { + jint iconsCount; // number of icons + AccessibleIconInfo iconInfo[MAX_ICON_INFO]; // the icons + } AccessibleIcons; + + // struct to get the icons associated with a component + typedef struct GetAccessibleIconsPackageTag { + long vmID; // the virtual machine id + JOBJECT64 accessibleContext; // the component + AccessibleIcons rAccessibleIcons; // the icons + } GetAccessibleIconsPackage; + + + /** +****************************************************** +* AccessibleAction packages +****************************************************** +*/ +#define MAX_ACTION_INFO 256 +#define MAX_ACTIONS_TO_DO 32 + + // an action assocated with a component + typedef struct AccessibleActionInfoTag { + wchar_t name[SHORT_STRING_SIZE]; // action name + } AccessibleActionInfo; + + // all of the actions associated with a component + typedef struct AccessibleActionsTag { + jint actionsCount; // number of actions + AccessibleActionInfo actionInfo[MAX_ACTION_INFO]; // the action information + } AccessibleActions; + + // struct for requesting the actions associated with a component + typedef struct GetAccessibleActionsPackageTag { + long vmID; + JOBJECT64 accessibleContext; // the component + AccessibleActions rAccessibleActions; // the actions + } GetAccessibleActionsPackage; + + // list of AccessibleActions to do + typedef struct AccessibleActionsToDoTag { + jint actionsCount; // number of actions to do + AccessibleActionInfo actions[MAX_ACTIONS_TO_DO];// the accessible actions to do + } AccessibleActionsToDo; + + // struct for sending an message to do one or more actions + typedef struct DoAccessibleActionsPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // component to do the action + AccessibleActionsToDo actionsToDo; // the accessible actions to do + BOOL rResult; // action return value + jint failure; // index of action that failed if rResult is FALSE + } DoAccessibleActionsPackage; + + /** +****************************************************** +* AccessibleText packages +****************************************************** +*/ + + typedef struct GetAccessibleTextInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint x; + jint y; + AccessibleTextInfo rTextInfo; + } GetAccessibleTextInfoPackage; + + typedef struct GetAccessibleTextItemsPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextItemsInfo rTextItemsInfo; + } GetAccessibleTextItemsPackage; + + typedef struct GetAccessibleTextSelectionInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + AccessibleTextSelectionInfo rTextSelectionItemsInfo; + } GetAccessibleTextSelectionInfoPackage; + + typedef struct GetAccessibleTextAttributeInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextAttributesInfo rAttributeInfo; + } GetAccessibleTextAttributeInfoPackage; + + typedef struct GetAccessibleTextRectInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextRectInfo rTextRectInfo; + } GetAccessibleTextRectInfoPackage; + + typedef struct GetCaretLocationPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextRectInfo rTextRectInfo; + } GetCaretLocationPackage; + + typedef struct GetAccessibleTextLineBoundsPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + jint rLineStart; + jint rLineEnd; + } GetAccessibleTextLineBoundsPackage; + + typedef struct GetAccessibleTextRangePackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint start; + jint end; + wchar_t rText[MAX_BUFFER_SIZE]; + } GetAccessibleTextRangePackage; + + /** +****************************************************** +* +* Utility method packages +****************************************************** +*/ + + typedef struct SetTextContentsPackageTag { + long vmID; + JOBJECT64 accessibleContext; // the text field + wchar_t text[MAX_STRING_SIZE]; // the text + BOOL rResult; + } SetTextContentsPackage; + + typedef struct GetParentWithRolePackageTag { + long vmID; + JOBJECT64 accessibleContext; + wchar_t role[SHORT_STRING_SIZE]; // one of Accessible Roles above + JOBJECT64 rAccessibleContext; + } GetParentWithRolePackage; + + typedef struct GetTopLevelObjectPackageTag { + long vmID; + JOBJECT64 accessibleContext; + JOBJECT64 rAccessibleContext; + } GetTopLevelObjectPackage; + + typedef struct GetParentWithRoleElseRootPackageTag { + long vmID; + JOBJECT64 accessibleContext; + wchar_t role[SHORT_STRING_SIZE]; // one of Accessible Roles above + JOBJECT64 rAccessibleContext; + } GetParentWithRoleElseRootPackage; + + typedef struct GetObjectDepthPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint rResult; + } GetObjectDepthPackage; + + typedef struct GetActiveDescendentPackageTag { + long vmID; + JOBJECT64 accessibleContext; + JOBJECT64 rAccessibleContext; + } GetActiveDescendentPackage; + + /** +****************************************************** +* AccessibleValue packages +****************************************************** +*/ + + typedef struct GetCurrentAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetCurrentAccessibleValueFromContextPackage; + + typedef struct GetMaximumAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetMaximumAccessibleValueFromContextPackage; + + typedef struct GetMinimumAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetMinimumAccessibleValueFromContextPackage; + + + /** +****************************************************** +* AccessibleSelection packages +****************************************************** +*/ + + typedef struct AddAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + } AddAccessibleSelectionFromContextPackage; + + typedef struct ClearAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + } ClearAccessibleSelectionFromContextPackage; + + typedef struct GetAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + JOBJECT64 rAccessibleContext; + } GetAccessibleSelectionFromContextPackage; + + typedef struct GetAccessibleSelectionCountFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint rCount; + } GetAccessibleSelectionCountFromContextPackage; + + typedef struct IsAccessibleChildSelectedFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + jboolean rResult; + } IsAccessibleChildSelectedFromContextPackage; + + typedef struct RemoveAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + } RemoveAccessibleSelectionFromContextPackage; + + typedef struct SelectAllAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + } SelectAllAccessibleSelectionFromContextPackage; + + + /** +****************************************************** +* Java Event Notification Registration packages +****************************************************** +*/ + + typedef struct AddJavaEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } AddJavaEventNotificationPackage; + + typedef struct RemoveJavaEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } RemoveJavaEventNotificationPackage; + + + /** +****************************************************** +* Accessibility Event Notification Registration packages +****************************************************** +*/ + + typedef struct AddAccessibilityEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } AddAccessibilityEventNotificationPackage; + + typedef struct RemoveAccessibilityEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } RemoveAccessibilityEventNotificationPackage; + + + /** +****************************************************** +* Accessibility Property Change Event packages +****************************************************** +*/ + + typedef struct PropertyCaretChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + jint oldPosition; + jint newPosition; + } PropertyCaretChangePackage; + + typedef struct PropertyDescriptionChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldDescription[SHORT_STRING_SIZE]; + wchar_t newDescription[SHORT_STRING_SIZE]; + } PropertyDescriptionChangePackage; + + typedef struct PropertyNameChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldName[SHORT_STRING_SIZE]; + wchar_t newName[SHORT_STRING_SIZE]; + } PropertyNameChangePackage; + + typedef struct PropertySelectionChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertySelectionChangePackage; + + typedef struct PropertyStateChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldState[SHORT_STRING_SIZE]; + wchar_t newState[SHORT_STRING_SIZE]; + } PropertyStateChangePackage; + + typedef struct PropertyTextChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertyTextChangePackage; + + typedef struct PropertyValueChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldValue[SHORT_STRING_SIZE]; + wchar_t newValue[SHORT_STRING_SIZE]; + } PropertyValueChangePackage; + + typedef struct PropertyVisibleDataChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertyVisibleDataChangePackage; + + typedef struct PropertyChildChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + JOBJECT64 oldChildAccessibleContext; + JOBJECT64 newChildAccessibleContext; + } PropertyChildChangePackage; + + typedef struct PropertyActiveDescendentChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + JOBJECT64 oldActiveDescendentAccessibleContext; + JOBJECT64 newActiveDescendentAccessibleContext; + } PropertyActiveDescendentChangePackage; + + + // String format for newValue is: + // "type" one of "INSERT", "UPDATE" or "DELETE" + // "firstRow" + // "lastRow" + // "firstColumn" + // "lastColumn" + // + // oldValue is currently unused + // + typedef struct PropertyTableModelChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldValue[SHORT_STRING_SIZE]; + wchar_t newValue[SHORT_STRING_SIZE]; + } PropertyTableModelChangePackage; + + + /** +****************************************************** +* Property Change Event packages +****************************************************** +*/ + + /* + typedef struct PropertyChangePackageTag { + long vmID; + jobject Event; + jobject AccessibleContextSource; + char propertyName[SHORT_STRING_SIZE]; + char oldValue[SHORT_STRING_SIZE]; // PropertyChangeEvent().getOldValue().toString() + char newValue[SHORT_STRING_SIZE]; // PropertyChangeEvent().getNewValue().toString() + } PropertyChangePackage; + */ + + /* + * Java shutdown event package + */ + typedef struct JavaShutdownPackageTag { + long vmID; + } JavaShutdownPackage; + + + /** +****************************************************** +* Focus Event packages +****************************************************** +*/ + + typedef struct FocusGainedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } FocusGainedPackage; + + typedef struct FocusLostPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } FocusLostPackage; + + + /** +****************************************************** +* Caret Event packages +****************************************************** +*/ + + typedef struct CaretUpdatePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } CaretUpdatePackage; + + + /** +****************************************************** +* Mouse Event packages +****************************************************** +*/ + + typedef struct MouseClickedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseClickedPackage; + + typedef struct MouseEnteredPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseEnteredPackage; + + typedef struct MouseExitedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseExitedPackage; + + typedef struct MousePressedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MousePressedPackage; + + typedef struct MouseReleasedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseReleasedPackage; + + + /** +****************************************************** +* Menu/PopupMenu Event packages +****************************************************** +*/ + + typedef struct MenuCanceledPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuCanceledPackage; + + typedef struct MenuDeselectedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuDeselectedPackage; + + typedef struct MenuSelectedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuSelectedPackage; + + + typedef struct PopupMenuCanceledPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuCanceledPackage; + + typedef struct PopupMenuWillBecomeInvisiblePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuWillBecomeInvisiblePackage; + + typedef struct PopupMenuWillBecomeVisiblePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuWillBecomeVisiblePackage; + + /** +****************************************************** +* Additional methods for Teton +****************************************************** +*/ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + typedef struct GetVirtualAccessibleNamePackageTag { + long vmID; + AccessibleContext accessibleContext; + wchar_t rName[MAX_STRING_SIZE]; + int len; + } GetVirtualAccessibleNamePackage; + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + typedef struct RequestFocusPackageTag { + long vmID; + AccessibleContext accessibleContext; + } RequestFocusPackage; + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + typedef struct SelectTextRangePackageTag { + long vmID; + AccessibleContext accessibleContext; + jint startIndex; + jint endIndex; + } SelectTextRangePackage; + + /** + * Gets the number of contiguous characters with the same attributes. + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + typedef struct GetTextAttributesInRangePackageTag { + long vmID; + AccessibleContext accessibleContext; + jint startIndex; // start index (inclusive) + jint endIndex; // end index (inclusive) + AccessibleTextAttributesInfo attributes; // character attributes to match + short rLength; // number of contiguous characters with matching attributes + } GetTextAttributesInRangePackage; + +#define MAX_VISIBLE_CHILDREN 256 + + // visible children information + typedef struct VisibleChildenInfoTag { + int returnedChildrenCount; // number of children returned + AccessibleContext children[MAX_VISIBLE_CHILDREN]; // the visible children + } VisibleChildrenInfo; + + // struct for sending a message to get the number of visible children + typedef struct GetVisibleChildrenCountPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext of parent component + jint rChildrenCount; // visible children count return value + } GetVisibleChildrenCountPackage; + + // struct for sending a message to get the hypertext for an AccessibleContext + // starting at a specified index in the document + typedef struct GetVisibleChildrenPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext of parent component + jint startIndex; // start index for retrieving children + VisibleChildrenInfo rVisibleChildrenInfo; // returned info + BOOL rSuccess; // whether call succeeded + } GetVisibleChildrenPackage; + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + typedef struct SetCaretPositionPackageTag { + long vmID; + AccessibleContext accessibleContext; + jint position; + } SetCaretPositionPackage; + + + /** + ****************************************************** + * Wrapping up all of the packages + ****************************************************** + */ + + /** + * What is the type of this package + */ + typedef enum PackageType { + + cMemoryMappedFileCreatedPackage = 0x11000, + + // many of these will go away... + cJavaVMCreatedPackage = 0x10000, + cJavaVMDestroyedPackage, + cWindowsATCreatedPackage, + cWindowsATDestroyedPackage, + cJavaVMPresentNotificationPackage, + cWindowsATPresentNotificationPackage, + + cReleaseJavaObjectPackage = 1, + cGetAccessBridgeVersionPackage = 2, + + cGetAccessibleContextFromHWNDPackage = 0x10, + cIsJavaWindowPackage, + cGetHWNDFromAccessibleContextPackage, + + cGetAccessibleContextAtPackage = 0x100, + cGetAccessibleContextWithFocusPackage, + cGetAccessibleContextInfoPackage, + cGetAccessibleChildFromContextPackage, + cGetAccessibleParentFromContextPackage, + cIsSameObjectPackage, + + cGetAccessibleTextInfoPackage = 0x200, + cGetAccessibleTextItemsPackage, + cGetAccessibleTextSelectionInfoPackage, + cGetAccessibleTextAttributeInfoPackage, + cGetAccessibleTextRectInfoPackage, + cGetAccessibleTextLineBoundsPackage, + cGetAccessibleTextRangePackage, + + cGetCurrentAccessibleValueFromContextPackage = 0x300, + cGetMaximumAccessibleValueFromContextPackage, + cGetMinimumAccessibleValueFromContextPackage, + + cAddAccessibleSelectionFromContextPackage = 0x400, + cClearAccessibleSelectionFromContextPackage, + cGetAccessibleSelectionFromContextPackage, + cGetAccessibleSelectionCountFromContextPackage, + cIsAccessibleChildSelectedFromContextPackage, + cRemoveAccessibleSelectionFromContextPackage, + cSelectAllAccessibleSelectionFromContextPackage, + + cAddJavaEventNotificationPackage = 0x900, + cRemoveJavaEventNotificationPackage, + cAddAccessibilityEventNotificationPackage, + cRemoveAccessibilityEventNotificationPackage, + + cPropertyChangePackage = 0x1000, + + cJavaShutdownPackage = 0x1010, + cFocusGainedPackage, + cFocusLostPackage, + + cCaretUpdatePackage = 0x1020, + + cMouseClickedPackage = 0x1030, + cMouseEnteredPackage, + cMouseExitedPackage, + cMousePressedPackage, + cMouseReleasedPackage, + + cMenuCanceledPackage = 0x1040, + cMenuDeselectedPackage, + cMenuSelectedPackage, + cPopupMenuCanceledPackage, + cPopupMenuWillBecomeInvisiblePackage, + cPopupMenuWillBecomeVisiblePackage, + + cPropertyCaretChangePackage = 0x1100, + cPropertyDescriptionChangePackage, + cPropertyNameChangePackage, + cPropertySelectionChangePackage, + cPropertyStateChangePackage, + cPropertyTextChangePackage, + cPropertyValueChangePackage, + cPropertyVisibleDataChangePackage, + cPropertyChildChangePackage, + cPropertyActiveDescendentChangePackage, + + + // AccessibleTable + cGetAccessibleTableInfoPackage = 0x1200, + cGetAccessibleTableCellInfoPackage, + + cGetAccessibleTableRowHeaderPackage, + cGetAccessibleTableColumnHeaderPackage, + + cGetAccessibleTableRowDescriptionPackage, + cGetAccessibleTableColumnDescriptionPackage, + + cGetAccessibleTableRowSelectionCountPackage, + cIsAccessibleTableRowSelectedPackage, + cGetAccessibleTableRowSelectionsPackage, + + cGetAccessibleTableColumnSelectionCountPackage, + cIsAccessibleTableColumnSelectedPackage, + cGetAccessibleTableColumnSelectionsPackage, + + cGetAccessibleTableRowPackage, + cGetAccessibleTableColumnPackage, + cGetAccessibleTableIndexPackage, + + cPropertyTableModelChangePackage, + + + // AccessibleRelationSet + cGetAccessibleRelationSetPackage = 0x1300, + + // AccessibleHypertext + cGetAccessibleHypertextPackage = 0x1400, + cActivateAccessibleHyperlinkPackage, + cGetAccessibleHyperlinkCountPackage, + cGetAccessibleHypertextExtPackage, + cGetAccessibleHypertextLinkIndexPackage, + cGetAccessibleHyperlinkPackage, + + // Accessible KeyBinding, Icon and Action + cGetAccessibleKeyBindingsPackage = 0x1500, + cGetAccessibleIconsPackage, + cGetAccessibleActionsPackage, + cDoAccessibleActionsPackage, + + // Utility methods + cSetTextContentsPackage = 0x1600, + cGetParentWithRolePackage, + cGetTopLevelObjectPackage, + cGetParentWithRoleElseRootPackage, + cGetObjectDepthPackage, + cGetActiveDescendentPackage, + + // Additional methods for Teton + cGetVirtualAccessibleNamePackage = 0x1700, + cRequestFocusPackage, + cSelectTextRangePackage, + cGetTextAttributesInRangePackage, + cGetSameTextAttributesInRangePackage, + cGetVisibleChildrenCountPackage, + cGetVisibleChildrenPackage, + cSetCaretPositionPackage, + cGetCaretLocationPackage + + + } PackageType; + + + /** + * Union of all package contents + */ + typedef union AllPackagesTag { + + // Initial Rendezvous packages + MemoryMappedFileCreatedPackage memoryMappedFileCreatedPackage; + + JavaVMCreatedPackage javaVMCreatedPackage; + JavaVMDestroyedPackage javaVMDestroyedPackage; + WindowsATCreatedPackage windowsATCreatedPackage; + WindowsATDestroyedPackage windowsATDestroyedPackage; + JavaVMPresentNotificationPackage javaVMPresentNotificationPackage; + WindowsATPresentNotificationPackage windowsATPresentNotificationPackage; + + // Core packages + ReleaseJavaObjectPackage releaseJavaObject; + GetAccessBridgeVersionPackage getAccessBridgeVersion; + + // Window packages + GetAccessibleContextFromHWNDPackage getAccessibleContextFromHWND; + GetHWNDFromAccessibleContextPackage getHWNDFromAccessibleContext; + + // AccessibleContext packages + GetAccessibleContextAtPackage getAccessibleContextAt; + GetAccessibleContextWithFocusPackage getAccessibleContextWithFocus; + GetAccessibleContextInfoPackage getAccessibleContextInfo; + GetAccessibleChildFromContextPackage getAccessibleChildFromContext; + GetAccessibleParentFromContextPackage getAccessibleParentFromContext; + + // AccessibleText packages + GetAccessibleTextInfoPackage getAccessibleTextInfo; + GetAccessibleTextItemsPackage getAccessibleTextItems; + GetAccessibleTextSelectionInfoPackage getAccessibleTextSelectionInfo; + GetAccessibleTextAttributeInfoPackage getAccessibleTextAttributeInfo; + GetAccessibleTextRectInfoPackage getAccessibleTextRectInfo; + GetAccessibleTextLineBoundsPackage getAccessibleTextLineBounds; + GetAccessibleTextRangePackage getAccessibleTextRange; + + // AccessibleValue packages + GetCurrentAccessibleValueFromContextPackage getCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextPackage getMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextPackage getMinimumAccessibleValueFromContext; + + // AccessibleSelection packages + AddAccessibleSelectionFromContextPackage addAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextPackage clearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextPackage getAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextPackage getAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextPackage isAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextPackage removeAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextPackage selectAllAccessibleSelectionFromContext; + + // Event Notification Registration packages + AddJavaEventNotificationPackage addJavaEventNotification; + RemoveJavaEventNotificationPackage removeJavaEventNotification; + AddAccessibilityEventNotificationPackage addAccessibilityEventNotification; + RemoveAccessibilityEventNotificationPackage removeAccessibilityEventNotification; + + // Event contents packages + // PropertyChangePackage propertyChange; + PropertyCaretChangePackage propertyCaretChangePackage; + PropertyDescriptionChangePackage propertyDescriptionChangePackage; + PropertyNameChangePackage propertyNameChangePackage; + PropertySelectionChangePackage propertySelectionChangePackage; + PropertyStateChangePackage propertyStateChangePackage; + PropertyTextChangePackage propertyTextChangePackage; + PropertyValueChangePackage propertyValueChangePackage; + PropertyVisibleDataChangePackage propertyVisibleDataChangePackage; + PropertyChildChangePackage propertyChildChangePackage; + PropertyActiveDescendentChangePackage propertyActiveDescendentChangePackage; + + PropertyTableModelChangePackage propertyTableModelChangePackage; + + JavaShutdownPackage JavaShutdown; + FocusGainedPackage focusGained; + FocusLostPackage focusLost; + + CaretUpdatePackage caretUpdate; + + MouseClickedPackage mouseClicked; + MouseEnteredPackage mouseEntered; + MouseExitedPackage mouseExited; + MousePressedPackage mousePressed; + MouseReleasedPackage mouseReleased; + + MenuCanceledPackage menuCanceled; + MenuDeselectedPackage menuDeselected; + MenuSelectedPackage menuSelected; + PopupMenuCanceledPackage popupMenuCanceled; + PopupMenuWillBecomeInvisiblePackage popupMenuWillBecomeInvisible; + PopupMenuWillBecomeVisiblePackage popupMenuWillBecomeVisible; + + // AccessibleRelationSet + GetAccessibleRelationSetPackage getAccessibleRelationSet; + + // AccessibleHypertext + GetAccessibleHypertextPackage _getAccessibleHypertext; + ActivateAccessibleHyperlinkPackage _activateAccessibleHyperlink; + GetAccessibleHyperlinkCountPackage _getAccessibleHyperlinkCount; + GetAccessibleHypertextExtPackage _getAccessibleHypertextExt; + GetAccessibleHypertextLinkIndexPackage _getAccessibleHypertextLinkIndex; + GetAccessibleHyperlinkPackage _getAccessibleHyperlink; + + // Accessible KeyBinding, Icon and Action + GetAccessibleKeyBindingsPackage getAccessibleKeyBindings; + GetAccessibleIconsPackage getAccessibleIcons; + GetAccessibleActionsPackage getAccessibleActions; + DoAccessibleActionsPackage doAccessibleActions; + + // utility methods + SetTextContentsPackage _setTextContents; + GetParentWithRolePackage _getParentWithRole; + GetTopLevelObjectPackage _getTopLevelObject; + GetParentWithRoleElseRootPackage _getParentWithRoleElseRoot; + GetObjectDepthPackage _getObjectDepth; + GetActiveDescendentPackage _getActiveDescendent; + + // Additional methods for Teton + GetVirtualAccessibleNamePackage _getVirtualAccessibleName; + RequestFocusPackage _requestFocus; + SelectTextRangePackage _selectTextRange; + GetTextAttributesInRangePackage _getTextAttributesInRange; + GetVisibleChildrenCountPackage _getVisibleChildrenCount; + GetVisibleChildrenPackage _getVisibleChildren; + SetCaretPositionPackage _setCaretPosition; + + } AllPackages; + + + /** + * Union of all Java-initiated package contents + */ + typedef union JavaInitiatedPackagesTag { + + // Initial Rendezvous packages + JavaVMCreatedPackage javaVMCreatedPackage; + JavaVMDestroyedPackage javaVMDestroyedPackage; + JavaVMPresentNotificationPackage javaVMPresentNotificationPackage; + + // Event contents packages + PropertyCaretChangePackage propertyCaretChangePackage; + PropertyDescriptionChangePackage propertyDescriptionChangePackage; + PropertyNameChangePackage propertyNameChangePackage; + PropertySelectionChangePackage propertySelectionChangePackage; + PropertyStateChangePackage propertyStateChangePackage; + PropertyTextChangePackage propertyTextChangePackage; + PropertyValueChangePackage propertyValueChangePackage; + PropertyVisibleDataChangePackage propertyVisibleDataChangePackage; + PropertyChildChangePackage propertyChildChangePackage; + PropertyActiveDescendentChangePackage propertyActiveDescendentChangePackage; + + PropertyTableModelChangePackage propertyTableModelChangePackage; + + JavaShutdownPackage JavaShutdown; + FocusGainedPackage focusGained; + FocusLostPackage focusLost; + + CaretUpdatePackage caretUpdate; + + MouseClickedPackage mouseClicked; + MouseEnteredPackage mouseEntered; + MouseExitedPackage mouseExited; + MousePressedPackage mousePressed; + MouseReleasedPackage mouseReleased; + + MenuCanceledPackage menuCanceled; + MenuDeselectedPackage menuDeselected; + MenuSelectedPackage menuSelected; + PopupMenuCanceledPackage popupMenuCanceled; + PopupMenuWillBecomeInvisiblePackage popupMenuWillBecomeInvisible; + PopupMenuWillBecomeVisiblePackage popupMenuWillBecomeVisible; + + } JavaInitiatedPackages; + + + /** + * Union of all Windows-initiated package contents + */ + typedef union WindowsInitiatedPackagesTag { + + // Initial Rendezvous packages + MemoryMappedFileCreatedPackage memoryMappedFileCreatedPackage; + + WindowsATCreatedPackage windowsATCreatedPackage; + WindowsATDestroyedPackage windowsATDestroyedPackage; + WindowsATPresentNotificationPackage windowsATPresentNotificationPackage; + + // Core packages + ReleaseJavaObjectPackage releaseJavaObject; + GetAccessBridgeVersionPackage getAccessBridgeVersion; + + // Window packages + GetAccessibleContextFromHWNDPackage getAccessibleContextFromHWND; + GetHWNDFromAccessibleContextPackage getHWNDFromAccessibleContext; + + // AccessibleContext packages + GetAccessibleContextAtPackage getAccessibleContextAt; + GetAccessibleContextWithFocusPackage getAccessibleContextWithFocus; + GetAccessibleContextInfoPackage getAccessibleContextInfo; + GetAccessibleChildFromContextPackage getAccessibleChildFromContext; + GetAccessibleParentFromContextPackage getAccessibleParentFromContext; + + // AccessibleText packages + GetAccessibleTextInfoPackage getAccessibleTextInfo; + GetAccessibleTextItemsPackage getAccessibleTextItems; + GetAccessibleTextSelectionInfoPackage getAccessibleTextSelectionInfo; + GetAccessibleTextAttributeInfoPackage getAccessibleTextAttributeInfo; + GetAccessibleTextRectInfoPackage getAccessibleTextRectInfo; + GetAccessibleTextLineBoundsPackage getAccessibleTextLineBounds; + GetAccessibleTextRangePackage getAccessibleTextRange; + + // AccessibleValue packages + GetCurrentAccessibleValueFromContextPackage getCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextPackage getMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextPackage getMinimumAccessibleValueFromContext; + + // AccessibleSelection packages + AddAccessibleSelectionFromContextPackage addAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextPackage clearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextPackage getAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextPackage getAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextPackage isAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextPackage removeAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextPackage selectAllAccessibleSelectionFromContext; + + // Event Notification Registration packages + AddJavaEventNotificationPackage addJavaEventNotification; + RemoveJavaEventNotificationPackage removeJavaEventNotification; + AddAccessibilityEventNotificationPackage addAccessibilityEventNotification; + RemoveAccessibilityEventNotificationPackage removeAccessibilityEventNotification; + + // AccessibleTable + GetAccessibleTableInfoPackage _getAccessibleTableInfo; + GetAccessibleTableCellInfoPackage _getAccessibleTableCellInfo; + + GetAccessibleTableRowHeaderPackage _getAccessibleTableRowHeader; + GetAccessibleTableColumnHeaderPackage _getAccessibleTableColumnHeader; + + GetAccessibleTableRowDescriptionPackage _getAccessibleTableRowDescription; + GetAccessibleTableColumnDescriptionPackage _getAccessibleTableColumnDescription; + + GetAccessibleTableRowSelectionCountPackage _getAccessibleTableRowSelectionCount; + IsAccessibleTableRowSelectedPackage _isAccessibleTableRowSelected; + GetAccessibleTableRowSelectionsPackage _getAccessibleTableRowSelections; + + GetAccessibleTableColumnSelectionCountPackage _getAccessibleTableColumnSelectionCount; + IsAccessibleTableColumnSelectedPackage _isAccessibleTableColumnSelected; + GetAccessibleTableColumnSelectionsPackage _getAccessibleTableColumnSelections; + + GetAccessibleTableRowPackage _getAccessibleTableRow; + GetAccessibleTableColumnPackage _getAccessibleTableColumn; + GetAccessibleTableIndexPackage _getAccessibleTableIndex; + + // AccessibleRelationSet + GetAccessibleRelationSetPackage _getAccessibleRelationSet; + + // Accessible KeyBindings, Icons and Actions + GetAccessibleKeyBindingsPackage _getAccessibleKeyBindings; + GetAccessibleIconsPackage _getAccessibleIcons; + GetAccessibleActionsPackage _getAccessibleActions; + DoAccessibleActionsPackage _doAccessibleActions; + + + IsSameObjectPackage _isSameObject; + + // utility methods + SetTextContentsPackage _setTextContents; + GetParentWithRolePackage _getParentWithRole; + GetTopLevelObjectPackage _getTopLevelObject; + GetParentWithRoleElseRootPackage _getParentWithRoleElseRoot; + GetObjectDepthPackage _getObjectDepth; + GetActiveDescendentPackage _getActiveDescendent; + + // Additional methods for Teton + GetVirtualAccessibleNamePackage _getVirtualAccessibleName; + RequestFocusPackage _requestFocus; + SelectTextRangePackage _selectTextRange; + GetTextAttributesInRangePackage _getTextAttributesInRange; + GetVisibleChildrenCountPackage _getVisibleChildrenCount; + GetVisibleChildrenPackage _getVisibleChildren; + SetCaretPositionPackage _setCaretPosition; + + + } WindowsInitiatedPackages; + + +#ifdef __cplusplus +} +#endif + +#endif --- /dev/null 2015-03-30 10:55:49.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeStatusWindow.RC 2015-03-30 10:55:48.866836600 -0500 @@ -0,0 +1,175 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" +#include "accessBridgeResource.h" + +#define XSTR(x) STR(x) +#define STR(x) #x + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +ACCESSBRIDGESTATUSWINDOW DIALOGEX 160, 78, 209, 163 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CLIENTEDGE +CAPTION "Access Bridge status" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + EDITTEXT cVMID,67,23,121,13,ES_READONLY + EDITTEXT cStatusText,40,147,162,13,ES_READONLY + LTEXT "Java VM ID:",IDC_STATIC,23,25,40,8 + LTEXT "Status:",IDC_STATIC,11,149,23,8 + EDITTEXT cWindowsID,67,39,121,13,ES_READONLY + LTEXT "Windows ID:",IDC_STATIC,21,41,42,8 + EDITTEXT cCallInfo,12,65,184,75,ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL + GROUPBOX "Call info",IDC_STATIC,4,55,197,90 + EDITTEXT cInvokedByText,67,1,121,13,ES_READONLY + LTEXT "Invoked by:",IDC_STATIC,25,3,38,8 +END + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "ACCESSBRIDGESTATUSWINDOW", DIALOG + BEGIN + LEFTMARGIN, 4 + RIGHTMARGIN, 202 + BOTTOMMARGIN, 160 + END + + "IDD_DIALOG1", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION JDK_FVER + PRODUCTVERSION JDK_FVER + FILEFLAGSMASK 0x3fL +#ifdef DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE JDK_FTYPE + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "Java Access Bridge\0" + VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" + VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0" + VALUE "FileVersion", XSTR(JDK_VER) "\0" + VALUE "Full Version", XSTR(JDK_BUILD_ID) "\0" + VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" + VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" + VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" + VALUE "ProductName", XSTR(JDK_NAME) "\0" + VALUE "ProductVersion", XSTR(JDK_VER) "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + --- /dev/null 2015-03-30 10:55:53.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp 2015-03-30 10:55:52.030847900 -0500 @@ -0,0 +1,856 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Glue routines called by Windows AT into the WindowsAccessBridge dll + */ + +#include "AccessBridgeDebug.h" +#include "AccessBridgeWindowsEntryPoints.h" +#include "WinAccessBridge.h" +#include "accessBridgeResource.h" + +#include +#include + + +extern WinAccessBridge *theWindowsAccessBridge; +extern HWND theDialogWindow; + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * Windows_run - where Windows executables will load/unload us + * + */ + void Windows_run() { + // open our window + if (theWindowsAccessBridge != (WinAccessBridge *) 0) { + theWindowsAccessBridge->initWindow(); + DEBUG_CODE(SetDlgItemText(theDialogWindow, cInvokedByText, "Windows")); + } + } + + /* + /** + * Windows_shutdown - where Windows executables will load/unload us + * + * + void Windows_shutdown() { + if (theWindowsAccessBridge != (WinAccessBridge *) 0) { + theWindowsAccessBridge->initWindow(); + } + } + */ + + /** + * getTopLevelHWND - returns the top-level window parent of the descendent + * + */ + HWND getTopLevelHWND(HWND descendent) { + HWND hwnd; + if (descendent == NULL) { + return NULL; + } + + if (!IsWindow(descendent)) { + return NULL; + } + + hwnd = descendent; + for(;;) { + LONG style = GetWindowLong(hwnd, GWL_STYLE); + if ( (style & WS_CHILD) == 0 ) { + // found a non-child window so terminate + break; + } + hwnd = GetParent(hwnd); + } + + return hwnd; + } + + void releaseJavaObject(long vmID, JOBJECT64 object) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->releaseJavaObject(vmID, object); + } + } + + void getVersionInfo(long vmID, AccessBridgeVersionInfo *info) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->getVersionInfo(vmID, info); + } + } + + + BOOL isJavaWindow(HWND window) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->isJavaWindow(window); + } + return FALSE; + } + + /* + * Returns whether two object references refer to the same object + */ + BOOL isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) { +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("\r\nAccessBridgeWindowsEntryPoints::isSameObject(%p %p)", obj1, obj2); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("\r\nAccessBridgeWindowsEntryPoints::isSameObject(%016I64X %016I64X)", obj1, obj2); +#endif + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->isSameObject(vmID, obj1, obj2); + } + return FALSE; + } + + /** + * Sets a text field to the specified string. Returns whether successful + */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext,const wchar_t *text) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->setTextContents(vmID, accessibleContext, text); + } + return FALSE; + } + + /** + * Returns the Accessible Context of an object of the specified role that is the + * ancestor of a given object. If the object is of the specified role + * or an ancestor object of the specified role was found, returns the object's + * AccessibleContext. + * If there is no ancestor object of the specified role, + * returns (AccessibleContext)0. + */ + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getParentWithRole(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getTopLevelObject(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + /** + * If there is an Ancestor object of the specified role, + * returns the Accessible Context of the found object. + * Otherwise, returns the top level object for that + * Java Window. Returns (AccessibleContext)0 on error. + */ + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getParentWithRoleElseRoot(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getObjectDepth(vmID, accessibleContext); + } + return -1; + } + + /** + * Returns the Accessible Context of the currently ActiveDescendent of an object. + * Returns (AccessibleContext)0 on error. + */ + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getActiveDescendent(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + // -------- Accessible Context methods ------------- + + BOOL getAccessibleContextFromHWND(HWND window, long *vmID, JOBJECT64 *AccessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleContextFromHWND(window, vmID, AccessibleContext); + } + return FALSE; + } + + HWND getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getHWNDFromAccessibleContext(vmID, accessibleContext); + } + return (HWND)0; + } + + BOOL getAccessibleContextAt(long vmID, JOBJECT64 AccessibleContextParent, + jint x, jint y, JOBJECT64 *AccessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleContextAt(vmID, AccessibleContextParent, + x, y, AccessibleContext); + } + return FALSE; + } + + BOOL getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT64 *AccessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleContextWithFocus(window, vmID, AccessibleContext); + } + return FALSE; + } + + BOOL getAccessibleContextInfo(long vmID, + JOBJECT64 AccessibleContext, + AccessibleContextInfo *info) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleContextInfo( + vmID, + AccessibleContext, + info); + } + return FALSE; + } + + JOBJECT64 getAccessibleChildFromContext(long vmID, + JOBJECT64 AccessibleContext, + jint childIndex) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleChildFromContext( + vmID, + AccessibleContext, + childIndex); + } + return (JOBJECT64) 0; + } + + JOBJECT64 getAccessibleParentFromContext(long vmID, + JOBJECT64 AccessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleParentFromContext( + vmID, + AccessibleContext); + } + return (JOBJECT64) 0; + } + + // -------- begin AccessibleTable routines ------------- + + BOOL getAccessibleTableInfo(long vmID, JOBJECT64 ac, + AccessibleTableInfo *tableInfo) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTableInfo( + vmID, + ac, + tableInfo); + } + return FALSE; + } + + BOOL getAccessibleTableCellInfo(long vmID, JOBJECT64 accessibleTable, + jint row, jint column, AccessibleTableCellInfo *tableCellInfo) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTableCellInfo( + vmID, + accessibleTable, + row, column, tableCellInfo); + } + return FALSE; + } + + BOOL getAccessibleTableRowHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTableRowHeader( + vmID, + acParent, + tableInfo); + } + return FALSE; + } + + BOOL getAccessibleTableColumnHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTableColumnHeader( + vmID, + acParent, + tableInfo); + } + return FALSE; + } + + JOBJECT64 getAccessibleTableRowDescription(long vmID, JOBJECT64 acParent, jint row) { + + if (theWindowsAccessBridge != 0) { + return (JOBJECT64)theWindowsAccessBridge->getAccessibleTableRowDescription( + vmID, + acParent, + row); + } + return (JOBJECT64)0; + } + + JOBJECT64 getAccessibleTableColumnDescription(long vmID, JOBJECT64 acParent, jint column) { + + if (theWindowsAccessBridge != 0) { + return (JOBJECT64)theWindowsAccessBridge->getAccessibleTableColumnDescription( + vmID, + acParent, + column); + } + return (JOBJECT64)0; + } + + jint getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTableRowSelectionCount(vmID, accessibleTable); + } + return -1; + } + + BOOL isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->isAccessibleTableRowSelected(vmID, accessibleTable, row); + } + return FALSE; + } + + BOOL getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, jint *selections) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableRowSelections(vmID, accessibleTable, count, + selections); + } + return FALSE; + } + + + jint getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableColumnSelectionCount(vmID, accessibleTable); + } + return -1; + } + + BOOL isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->isAccessibleTableColumnSelected(vmID, accessibleTable, column); + } + return FALSE; + } + + BOOL getAccessibleTableColumnSelections(long vmID, JOBJECT64 accessibleTable, jint count, jint *selections) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableColumnSelections(vmID, accessibleTable, count, + selections); + } + return FALSE; + } + + jint getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableRow(vmID, accessibleTable, index); + } + return -1; + } + + jint getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableColumn(vmID, accessibleTable, index); + } + return -1; + } + + jint getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableIndex(vmID, accessibleTable, row, column); + } + return -1; + } + + /* --------- end AccessibleTable routines ------- */ + + // --------- AccessibleRelationSet methods + + BOOL getAccessibleRelationSet(long vmID, JOBJECT64 accessibleContext, + AccessibleRelationSetInfo *relationSetInfo) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleRelationSet(vmID, accessibleContext, relationSetInfo); + } + return FALSE; + } + + // --------- AccessibleHypertext methods + + BOOL getAccessibleHypertext(long vmID, JOBJECT64 accessibleContext, + AccessibleHypertextInfo *accessibleHypertextInfo) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleHypertext(vmID, accessibleContext, + accessibleHypertextInfo); + } + return FALSE; + } + + BOOL activateAccessibleHyperlink(long vmID, JOBJECT64 accessibleContext, JOBJECT64 accessibleHyperlink) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->activateAccessibleHyperlink(vmID, accessibleContext, + accessibleHyperlink); + } + return FALSE; + } + + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleHyperlinkCount(vmID, accessibleContext); + } + return -1; + } + + + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleHypertextExt(vmID, + accessibleContext, + nStartIndex, + hypertextInfo); + } + return FALSE; + } + + + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleHypertextLinkIndex(vmID, + hypertext, + nIndex); + } + return -1; + } + + + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleHyperlink(vmID, + hypertext, + nIndex, + hyperlinkInfo); + } + return FALSE; + } + + + /* Accessible KeyBindings, Icons and Actions */ + BOOL getAccessibleKeyBindings(long vmID, JOBJECT64 accessibleContext, AccessibleKeyBindings *keyBindings) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleKeyBindings(vmID, accessibleContext, keyBindings); + } + return FALSE; + } + + BOOL getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, AccessibleIcons *icons) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleIcons(vmID, accessibleContext, icons); + } + return FALSE; + } + + BOOL getAccessibleActions(long vmID, JOBJECT64 accessibleContext, AccessibleActions *actions) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleActions(vmID, accessibleContext, actions); + } + return FALSE; + } + + BOOL doAccessibleActions(long vmID, JOBJECT64 accessibleContext, AccessibleActionsToDo *actionsToDo, + jint *failure) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->doAccessibleActions(vmID, accessibleContext, actionsToDo, + failure); + } + return FALSE; + } + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(long vmID, AccessibleContext accessibleContext, wchar_t *name, int len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getVirtualAccessibleName(vmID, accessibleContext, name, len); + } + return FALSE; + } + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(long vmID, AccessibleContext accessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->requestFocus(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->selectTextRange(vmID, accessibleContext, startIndex, endIndex); + } + return FALSE; + } + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getTextAttributesInRange(vmID, accessibleContext, + startIndex, endIndex, attributes, len); + } + return FALSE; + } + + /** + * Gets the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(long vmID, AccessibleContext accessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getVisibleChildrenCount(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(long vmID, AccessibleContext accessibleContext, int startIndex, + VisibleChildrenInfo *visibleChildrenInfo) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getVisibleChildren(vmID, accessibleContext, startIndex, + visibleChildrenInfo); + } + return FALSE; + } + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const long vmID, const AccessibleContext accessibleContext, + const int position) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->setCaretPosition(vmID, accessibleContext, position); + } + return FALSE; + } + + // -------- Accessible Text methods ------------- + + BOOL getAccessibleTextInfo(long vmID, JOBJECT64 AccessibleContext, + AccessibleTextInfo *textInfo, jint x, jint y) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextInfo( + vmID, + AccessibleContext, + textInfo, x, y); + } + return FALSE; + } + + BOOL getAccessibleTextItems(long vmID, JOBJECT64 AccessibleContext, + AccessibleTextItemsInfo *textItems, jint index) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextItems( + vmID, + AccessibleContext, + textItems, index); + } + return FALSE; + } + + BOOL getAccessibleTextSelectionInfo(long vmID, JOBJECT64 AccessibleContext, + AccessibleTextSelectionInfo *selectionInfo) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextSelectionInfo( + vmID, + AccessibleContext, + selectionInfo); + } + return FALSE; + } + + BOOL getAccessibleTextAttributes(long vmID, JOBJECT64 AccessibleContext, + jint index, AccessibleTextAttributesInfo *attributes) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextAttributes( + vmID, + AccessibleContext, + index, attributes); + } + return FALSE; + } + + BOOL getAccessibleTextRect(long vmID, JOBJECT64 AccessibleContext, + AccessibleTextRectInfo *rectInfo, jint index) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextRect( + vmID, + AccessibleContext, + rectInfo, index); + } + return FALSE; + } + + BOOL getCaretLocation(long vmID, JOBJECT64 AccessibleContext, + AccessibleTextRectInfo *rectInfo, jint index) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getCaretLocation(vmID, + AccessibleContext, + rectInfo, index); + } + return FALSE; + } + + int getEventsWaiting() { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getEventsWaiting(); + } + return FALSE; + } + + BOOL getAccessibleTextLineBounds(long vmID, JOBJECT64 AccessibleContext, + jint index, jint *startIndex, jint *endIndex) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextLineBounds( + vmID, + AccessibleContext, + index, startIndex, endIndex); + } + return FALSE; + } + + BOOL getAccessibleTextRange(long vmID, JOBJECT64 AccessibleContext, + jint start, jint end, wchar_t *text, short len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextRange( + vmID, + AccessibleContext, + start, end, text, len); + } + return FALSE; + } + + + // -------- Accessible Value methods ------------- + + BOOL getCurrentAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getCurrentAccessibleValueFromContext( + vmID, AccessibleContext, value, len); + } + return FALSE; + } + + BOOL getMaximumAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getMaximumAccessibleValueFromContext( + vmID, AccessibleContext, value, len); + } + return FALSE; + } + + BOOL getMinimumAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getMinimumAccessibleValueFromContext( + vmID, AccessibleContext, value, len); + } + return FALSE; + } + + // -------- Accessible Selection methods ------------- + + void addAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->addAccessibleSelectionFromContext( + vmID, AccessibleContext, i); + } + } + + void clearAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->clearAccessibleSelectionFromContext( + vmID, AccessibleContext); + } + } + + JOBJECT64 getAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleSelectionFromContext( + vmID, AccessibleContext, i); + } + return (JOBJECT64) 0; + } + + int getAccessibleSelectionCountFromContext(long vmID, JOBJECT64 AccessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleSelectionCountFromContext( + vmID, AccessibleContext); + } + return -1; + } + + BOOL isAccessibleChildSelectedFromContext(long vmID, JOBJECT64 AccessibleContext, int i) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->isAccessibleChildSelectedFromContext( + vmID, AccessibleContext, i); + } + return FALSE; + } + + void removeAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->removeAccessibleSelectionFromContext( + vmID, AccessibleContext, i); + } + } + + void selectAllAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->selectAllAccessibleSelectionFromContext( + vmID, AccessibleContext); + } + } + + + // -------- Event Handler methods ------------- + +#define SET_EVENT_FP(function, callbackFP) \ + void function(callbackFP fp) { \ + if (theWindowsAccessBridge != 0) { \ + theWindowsAccessBridge->function(fp); \ + } \ +} + + void setJavaShutdownFP(AccessBridge_JavaShutdownFP fp) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->setJavaShutdownFP(fp); + } + } + + SET_EVENT_FP(setPropertyChangeFP, AccessBridge_PropertyChangeFP) + SET_EVENT_FP(setFocusGainedFP, AccessBridge_FocusGainedFP) + SET_EVENT_FP(setFocusLostFP, AccessBridge_FocusLostFP) + SET_EVENT_FP(setCaretUpdateFP, AccessBridge_CaretUpdateFP) + SET_EVENT_FP(setMouseClickedFP, AccessBridge_MouseClickedFP) + SET_EVENT_FP(setMouseEnteredFP, AccessBridge_MouseEnteredFP) + SET_EVENT_FP(setMouseExitedFP, AccessBridge_MouseExitedFP) + SET_EVENT_FP(setMousePressedFP, AccessBridge_MousePressedFP) + SET_EVENT_FP(setMouseReleasedFP, AccessBridge_MouseReleasedFP) + SET_EVENT_FP(setMenuCanceledFP, AccessBridge_MenuCanceledFP) + SET_EVENT_FP(setMenuDeselectedFP, AccessBridge_MenuDeselectedFP) + SET_EVENT_FP(setMenuSelectedFP, AccessBridge_MenuSelectedFP) + SET_EVENT_FP(setPopupMenuCanceledFP, AccessBridge_PopupMenuCanceledFP) + SET_EVENT_FP(setPopupMenuWillBecomeInvisibleFP, AccessBridge_PopupMenuWillBecomeInvisibleFP) + SET_EVENT_FP(setPopupMenuWillBecomeVisibleFP, AccessBridge_PopupMenuWillBecomeVisibleFP) + + SET_EVENT_FP(setPropertyNameChangeFP, AccessBridge_PropertyNameChangeFP) + SET_EVENT_FP(setPropertyDescriptionChangeFP, AccessBridge_PropertyDescriptionChangeFP) + SET_EVENT_FP(setPropertyStateChangeFP, AccessBridge_PropertyStateChangeFP) + SET_EVENT_FP(setPropertyValueChangeFP, AccessBridge_PropertyValueChangeFP) + SET_EVENT_FP(setPropertySelectionChangeFP, AccessBridge_PropertySelectionChangeFP) + SET_EVENT_FP(setPropertyTextChangeFP, AccessBridge_PropertyTextChangeFP) + SET_EVENT_FP(setPropertyCaretChangeFP, AccessBridge_PropertyCaretChangeFP) + SET_EVENT_FP(setPropertyVisibleDataChangeFP, AccessBridge_PropertyVisibleDataChangeFP) + SET_EVENT_FP(setPropertyChildChangeFP, AccessBridge_PropertyChildChangeFP) + SET_EVENT_FP(setPropertyActiveDescendentChangeFP, AccessBridge_PropertyActiveDescendentChangeFP) + + SET_EVENT_FP(setPropertyTableModelChangeFP, AccessBridge_PropertyTableModelChangeFP) + +#ifdef __cplusplus + } +#endif --- /dev/null 2015-03-30 10:55:56.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.h 2015-03-30 10:55:55.218857900 -0500 @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Glue routines called by Windows AT into the WindowsAccessBridge dll + */ + +#ifndef __AccessBridgeWindowsEntryPoints_H__ +#define __AccessBridgeWindowsEntryPoints_H__ + +#include +#include + +#include "AccessBridgePackages.h" +#include "AccessBridgeCallbacks.h" + +#ifdef __cplusplus +extern "C" { +#endif + + void Windows_run(); + + void releaseJavaObject(long vmID, JOBJECT64 object); + void getVersionInfo(long vmID, AccessBridgeVersionInfo *info); + + // Window related functions + HWND getTopLevelHWND(HWND descendent); + BOOL isJavaWindow(HWND window); + BOOL getAccessibleContextFromHWND(HWND window, long *vmID, JOBJECT64 *AccessibleContext); + HWND getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext); + + // returns whether two objects are the same + BOOL isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + + // Accessible Context functions + BOOL getAccessibleContextAt(long vmID, JOBJECT64 AccessibleContextParent, + jint x, jint y, JOBJECT64 *AccessibleContext); + BOOL getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT64 *AccessibleContext); + BOOL getAccessibleContextInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleContextInfo *info); + JOBJECT64 getAccessibleChildFromContext(long vmID, JOBJECT64 AccessibleContext, jint childIndex); + JOBJECT64 getAccessibleParentFromContext(long vmID, JOBJECT64 AccessibleContext); + + /* begin AccessibleTable */ + BOOL getAccessibleTableInfo(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableCellInfo(long vmID, JOBJECT64 accessibleTable, jint row, jint column, + AccessibleTableCellInfo *tableCellInfo); + + BOOL getAccessibleTableRowHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableColumnHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + + JOBJECT64 getAccessibleTableRowDescription(long vmID, JOBJECT64 acParent, jint row); + JOBJECT64 getAccessibleTableColumnDescription(long vmID, JOBJECT64 acParent, jint column); + + jint getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable); + BOOL isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row); + BOOL getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, + jint *selections); + + jint getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable); + BOOL isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column); + BOOL getAccessibleTableColumnSelections(long vmID, JOBJECT64 accessibleTable, jint count, + jint *selections); + + jint getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index); + jint getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index); + jint getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column); + + /* end AccessibleTable */ + + BOOL getAccessibleRelationSet(long vmID, JOBJECT64 accessibleContext, + AccessibleRelationSetInfo *relationSetInfo); + + // AccessibleHypertext methods + BOOL getAccessibleHypertext(long vmID, JOBJECT64 accessibleContext, AccessibleHypertextInfo *hypertextInfo); + + BOOL activateAccessibleHyperlink(long vmID, JOBJECT64 accessibleContext, JOBJECT64 accessibleHyperlink); + + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext); + + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo); + + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + + /* Accessible KeyBindings, Icons and Actions */ + BOOL getAccessibleKeyBindings(long vmID, JOBJECT64 accessibleContext, + AccessibleKeyBindings *keyBindings); + + BOOL getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, + AccessibleIcons *icons); + + BOOL getAccessibleActions(long vmID, JOBJECT64 accessibleContext, + AccessibleActions *actions); + + BOOL doAccessibleActions(long vmID, JOBJECT64 accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + /* ----- Additional AccessibleHypertext methods for Teton */ + + + jint getAccessibleHypertextLinkCount(const long vmID, + const AccessibleContext accessibleContext); + + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo); + + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleContext accessibleContext, + const jint nIndex); + + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleContext accessibleContext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + + /* Additional utility methods */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text); + + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role); + + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext); + + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role); + + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext); + + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext); + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(long vmID, AccessibleContext accessibleContext, wchar_t *name, int len); + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(long vmID, AccessibleContext accessibleContext); + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex); + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + /** + * Returns the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(long vmID, AccessibleContext accessibleContext); + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(long vmID, AccessibleContext accessibleContext, int startIndex, + VisibleChildrenInfo *visibleChildrenInfo); + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(long vmID, AccessibleContext accessibleContext, int position); + + /** + * Gets the text caret bounding rectangle + */ + BOOL getCaretLocation(long vmID, JOBJECT64 AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + + // Accessible Text functions + BOOL getAccessibleTextInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleTextInfo *textInfo, jint x, jint y); + BOOL getAccessibleTextItems(long vmID, JOBJECT64 AccessibleContext, AccessibleTextItemsInfo *textItems, jint index); + BOOL getAccessibleTextSelectionInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleTextSelectionInfo *selectionInfo); + BOOL getAccessibleTextAttributes(long vmID, JOBJECT64 AccessibleContext, jint index, AccessibleTextAttributesInfo *attributes); + BOOL getAccessibleTextRect(long vmID, JOBJECT64 AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + BOOL getAccessibleTextLineBounds(long vmID, JOBJECT64 AccessibleContext, jint index, jint *startIndex, jint *endIndex); + BOOL getAccessibleTextRange(long vmID, JOBJECT64 AccessibleContext, jint start, jint end, wchar_t *text, short len); + + // Accessible Value methods + BOOL getCurrentAccessibleValueFromContext(long vmID,JOBJECT64 AccessibleContext, wchar_t *value, short len); + BOOL getMaximumAccessibleValueFromContext(long vmID,JOBJECT64 AccessibleContext, wchar_t *value, short len); + BOOL getMinimumAccessibleValueFromContext(long vmID,JOBJECT64 AccessibleContext, wchar_t *value, short len); + + // Accessible Selection methods + void addAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext, int i); + void clearAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext); + JOBJECT64 getAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext, int i); + int getAccessibleSelectionCountFromContext(long vmID,JOBJECT64 AccessibleContext); + BOOL isAccessibleChildSelectedFromContext(long vmID,JOBJECT64 AccessibleContext, int i); + void removeAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext, int i); + void selectAllAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext); + + + // PropertyChange Event registry routines + void setPropertyChangeFP(AccessBridge_PropertyChangeFP fp); + + // Java application shutdown + void setJavaShutdownFP(AccessBridge_JavaShutdownFP fp); + + // Focus Event registry routines + void setFocusGainedFP(AccessBridge_FocusGainedFP fp); + void setFocusLostFP(AccessBridge_FocusLostFP fp); + + // Caret Event registry routines + void setCaretUpdateFP(AccessBridge_CaretUpdateFP fp); + + // Mouse Event registry routines + void setMouseClickedFP(AccessBridge_MouseClickedFP fp); + void setMouseEnteredFP(AccessBridge_MouseEnteredFP fp); + void setMouseExitedFP(AccessBridge_MouseExitedFP fp); + void setMousePressedFP(AccessBridge_MousePressedFP fp); + void setMouseReleasedFP(AccessBridge_MouseReleasedFP fp); + + // Menu/PopupMenu Event registry routines + void setMenuCanceledFP(AccessBridge_MenuCanceledFP fp); + void setMenuDeselectedFP(AccessBridge_MenuDeselectedFP fp); + void setMenuSelectedFP(AccessBridge_MenuSelectedFP fp); + void setPopupMenuCanceledFP(AccessBridge_PopupMenuCanceledFP fp); + void setPopupMenuWillBecomeInvisibleFP(AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + void setPopupMenuWillBecomeVisibleFP(AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + // Accessibility PropertyChange Event registry routines + void setPropertyNameChangeFP(AccessBridge_PropertyNameChangeFP fp); + void setPropertyDescriptionChangeFP(AccessBridge_PropertyDescriptionChangeFP fp); + void setPropertyStateChangeFP(AccessBridge_PropertyStateChangeFP fp); + void setPropertyValueChangeFP(AccessBridge_PropertyValueChangeFP fp); + void setPropertySelectionChangeFP(AccessBridge_PropertySelectionChangeFP fp); + void setPropertyTextChangeFP(AccessBridge_PropertyTextChangeFP fp); + void setPropertyCaretChangeFP(AccessBridge_PropertyCaretChangeFP fp); + void setPropertyVisibleDataChangeFP(AccessBridge_PropertyVisibleDataChangeFP fp); + void setPropertyChildChangeFP(AccessBridge_PropertyChildChangeFP fp); + void setPropertyActiveDescendentChangeFP(AccessBridge_PropertyActiveDescendentChangeFP fp); + + void setPropertyTableModelChangeFP(AccessBridge_PropertyTableModelChangeFP fp); + + + +#ifdef __cplusplus +} +#endif + +#endif --- /dev/null 2015-03-30 10:55:59.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/JAWTAccessBridge.cpp 2015-03-30 10:55:58.358867300 -0500 @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A DLL which is loaded by Java applications and used to map + * between Java applications and native Win32 window handles. + */ + +#include "com_sun_java_accessibility_AccessBridge.h" // programatically generated by JNI + +#include +#include + +#include +#include + +// --------------------------------------------------------------------------- + +extern "C" { + /** + * DllMain - where Windows executables will load/unload us + * + */ + BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) { + + return TRUE; + } + + + /* + * Map a HWND to a Java component + * + * Class: com_sun_java_accessibility_AccessBridge + * Method: jawtGetComponentFromNativeWindowHandle + * Signature: (I)Ljava/awt/Component; + */ + JNIEXPORT jobject JNICALL + Java_com_sun_java_accessibility_AccessBridge_jawtGetComponentFromNativeWindowHandle + (JNIEnv *env, jobject callingObj, jint windowHandle) { + + JAWT awt; + jboolean result; + jobject component = (jobject)0; + + // Get the AWT + awt.version = JAWT_VERSION_1_4; + result = JAWT_GetAWT(env, &awt); + if (result == JNI_FALSE) { + return (jobject)0; + } + + // Get the component + return awt.GetComponent(env, (void *)windowHandle); + } + + + /* + * Map a Java component to a HWND + * + * Class: com_sun_java_accessibility_AccessBridge + * Method: jawtGetNativeWindowHandleFromComponent + * Signature: (Ljava/awt/Component;)I + */ + JNIEXPORT jint JNICALL + Java_com_sun_java_accessibility_AccessBridge_jawtGetNativeWindowHandleFromComponent + (JNIEnv *env, jobject callingObj, jobject component) + { + + JAWT awt; + JAWT_DrawingSurface* ds; + JAWT_DrawingSurfaceInfo* dsi; + JAWT_Win32DrawingSurfaceInfo* dsi_win; + jboolean result; + // jint lock; + jint windowHandle = -1; + + // Get the AWT + awt.version = JAWT_VERSION_1_4; + result = JAWT_GetAWT(env, &awt); + if (result == JNI_FALSE) { + return -1; + } + + // Get the drawing surface + ds = awt.GetDrawingSurface(env, component); + if (ds == NULL) { + return -1; + } + + /* + * Should not be necessary. + * + // Lock the drawing surface + lock = ds->Lock(ds); + if ((lock & JAWT_LOCK_ERROR) != 0) { + return -1; + } + */ + + // Get the drawing surface info + dsi = ds->GetDrawingSurfaceInfo(ds); + + // Get the platform-specific drawing info + dsi_win = (JAWT_Win32DrawingSurfaceInfo *)dsi->platformInfo; + + // Get the window handle + windowHandle = (jint)dsi_win->hwnd; + + // Free the drawing surface info + ds->FreeDrawingSurfaceInfo(dsi); + + /* + // Unlock the drawing surface + ds->Unlock(ds); + */ + + // Free the drawing surface + awt.FreeDrawingSurface(ds); + + return windowHandle; + } +} --- /dev/null 2015-03-30 10:56:02.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/JAWTAccessBridge.h 2015-03-30 10:56:01.485878200 -0500 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @(#)JAWTAccessBridge.h 1.9 05/03/21 + */ + +/* + * A DLL which is loaded by Java applications to handle communication + * between Java VMs purposes of Accessbility. + */ + +#include +#include + +#include "AccessBridgePackages.h" + +#ifndef __JAWTAccessBridge_H__ +#define __JAWTAccessBridge_H__ + + +extern "C" { + BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, + LPVOID lpvReserved); +} + +#endif --- /dev/null 2015-03-30 10:56:05.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/JavaAccessBridge.cpp 2015-03-30 10:56:04.602887400 -0500 @@ -0,0 +1,2724 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A DLL which is loaded by Java applications to handle communication + * between Java VMs purposes of Accessbility. + */ + +#include "AccessBridgeDebug.h" +#include "JavaAccessBridge.h" +#include "com_sun_java_accessibility_AccessBridge.h" // programatically generated by JNI +#include "accessBridgeResource.h" +#include "accessBridgeCallbacks.h" +#include "AccessBridgeMessages.h" + + +#include +#include + +// #ifdef JAWT_SUPPORT +#include +#include +// #endif /* JAWT_SUPPORT */ + +JavaAccessBridge *theJavaAccessBridge; +HWND theDialogWindow; + +// re-entrance lock for receiving memory messages +CRITICAL_SECTION receiveMemoryIPCLock; + + +// unique broadcast msg. IDs gotten dymanically +extern UINT theFromJavaHelloMsgID; +extern UINT theFromWindowsHelloMsgID; + + +// --------------------------------------------------------------------------- + +extern "C" { + /** + * DllMain - where Windows executables will load/unload us + * + */ + BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) { + + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + InitializeCriticalSection(&receiveMemoryIPCLock); + theJavaAccessBridge = new JavaAccessBridge(hinstDll); + break; + + case DLL_PROCESS_DETACH: // A Windows executable unloaded us + if (theJavaAccessBridge != (JavaAccessBridge *) 0) { + delete theJavaAccessBridge; + DeleteCriticalSection(&receiveMemoryIPCLock); + } + break; + } + return TRUE; + } + + /** + * Open a native window (and init the wrappers we'll be using) + * + */ + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_runDLL(JNIEnv *env, jobject obj) { + PrintDebugString("\r\nJavaAccessBridge.DLL runDLL() called"); + theJavaAccessBridge->javaRun(env, obj); + } + +#if 0 // SetDlgItemText has caused problems with JAWS + /** + * Append debug info to dialog + * + */ + void AppendToCallInfo(char *s) { + char buffer[4096]; + + PrintDebugString(s); + + GetDlgItemText(theDialogWindow, cCallInfo, buffer, sizeof(buffer)); + if (strlen(buffer) < (sizeof(buffer) - strlen(s))) { + strncat(buffer, s, sizeof(buffer)); + SetDlgItemText(theDialogWindow, cCallInfo, buffer); + } else { + SetDlgItemText(theDialogWindow, cCallInfo, s); + } + } +#endif + + + /** + * Our window proc + * + */ + BOOL APIENTRY AccessBridgeDialogProc (HWND hDlg, UINT message, UINT wParam, LONG lParam) { + int command; + COPYDATASTRUCT *sentToUs; + char *package; + //DEBUG_CODE(char buffer[256]); + + switch (message) { + case WM_INITDIALOG: + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Initializing")); + break; + + case WM_COMMAND: + command = LOWORD (wParam); + break; + + // call from Java with data for us to deliver + case WM_COPYDATA: + if (theDialogWindow == (HWND) wParam) { + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got WM_COPYDATA from ourselves")); + } else { + //DEBUG_CODE(sprintf(buffer, "Got WM_COPYDATA from HWND %p", wParam)); + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, buffer)); + sentToUs = (COPYDATASTRUCT *) lParam; + package = (char *) sentToUs->lpData; + theJavaAccessBridge->processPackage(package, sentToUs->cbData); + } + break; + + // call from Java with data for us retrieve from memory mapped file and deliver + case AB_MESSAGE_WAITING: + // wParam == sourceHwnd + // lParam == buffer size in shared memory + if (theDialogWindow == (HWND) wParam) { + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_MESSAGE_WAITING from ourselves")); + } else { + //DEBUG_CODE(sprintf(buffer, "Got AB_MESSAGE_WAITING from HWND %p", wParam)); + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, buffer)); + LRESULT returnVal = theJavaAccessBridge->receiveMemoryPackage((HWND) wParam, lParam); + } + break; + + // a JavaAccessBridge DLL is going away + case AB_DLL_GOING_AWAY: + // wParam == sourceHwnd + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_DLL_GOING_AWAY message")); + theJavaAccessBridge->WindowsATDestroyed((HWND) wParam); + break; + + default: + // the Windows AT is saying "hi"! + // wParam == sourceHwnc; lParam unused + if (message == theFromWindowsHelloMsgID) { + // A new Windows AT just said "hi"; + // say "hi" back so it can mate up with us + // otherwise don't do anything (e.g. don't set up data structures yet) + theJavaAccessBridge->postHelloToWindowsDLLMsg((HWND) wParam); + } + } + return FALSE; + } + +} + + +// ----------------------------- + + +/** + * Initialize the JavaAccessBridge + * + */ +JavaAccessBridge::JavaAccessBridge(HINSTANCE hInstance) { + windowsInstance = hInstance; + ATs = (AccessBridgeATInstance *) 0; + initBroadcastMessageIDs(); // get the unique to us broadcast msg. IDs +} + +extern DWORD JavaBridgeThreadId; + +/** + * Destroy the JavaAccessBridge + * + */ +JavaAccessBridge::~JavaAccessBridge() { + // inform all other AccessBridges that we're going away + + PrintDebugString("\r\nin JavaAccessBridge::~JavaAccessBridge()"); + + // Send a shutdown message for those applications like StarOffice that do + // send a shutdown message themselves. + javaShutdown(NULL, 0); + + AccessBridgeATInstance *current = ATs; + while (current != (AccessBridgeATInstance *) 0) { + PrintDebugString(" telling %p we're going away", current->winAccessBridgeWindow); + SendMessage(current->winAccessBridgeWindow, + AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0); + current = current->nextATInstance; + } + + PrintDebugString(" finished telling ATs about our demise"); + + if(JavaBridgeThreadId) + { + PostThreadMessage(JavaBridgeThreadId,WM_USER+1,0,0); + Sleep(100); + } + + delete ATs; + + PrintDebugString(" finished deleting ATs"); + PrintDebugString("GOODBYE CRUEL WORLD..."); +} + + +void +JavaAccessBridge::javaRun(JNIEnv *env, jobject obj) { + MSG msg; + + PrintDebugString("JavaAccessBridge::javaRun(%p, %p) called", env, obj); + + if (env->GetJavaVM(&javaVM) != 0) { + return; // huh!?!?! + } + PrintDebugString(" -> javaVM = %p", javaVM); + + if (javaVM->AttachCurrentThread((void **) &windowsThreadJNIEnv, NULL) != 0) { + return; // huh!?!?! + } + PrintDebugString(" -> windowsThreadJNIEnv = %p", windowsThreadJNIEnv); + + javaThreadABObject = env->NewGlobalRef(obj); + windowsThreadABObject = windowsThreadJNIEnv->NewGlobalRef(obj); + + // initialize the Java thread AccessBridge entry points + javaThreadEntryPoints = new AccessBridgeJavaEntryPoints(env, javaThreadABObject); + if (javaThreadEntryPoints->BuildJavaEntryPoints() == FALSE) { + return; // couldn't build our entry points; let's get out of here! + } + PrintDebugString(" all Java thread entry points successfully found."); + + // initialize the Windows thread AccessBridge entry points + windowsThreadEntryPoints = new AccessBridgeJavaEntryPoints(windowsThreadJNIEnv, + windowsThreadABObject); + if (windowsThreadEntryPoints->BuildJavaEntryPoints() == FALSE) { + return; // couldn't build our entry points; let's get out of here! + } + PrintDebugString(" all Windows thread entry points successfully found."); + + + // open our window + if (initWindow() == TRUE) { + PrintDebugString(" Window created. HWND = %p", dialogWindow); + + // post a broadcast msg.; let other AccessBridge DLLs know we exist + postHelloToWindowsDLLMsg(HWND_BROADCAST); + + // do that message loop thing + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } else { + PrintDebugString(" FAILED TO CREATE WINDOW!!!"); + } + + javaVM->DetachCurrentThread(); +} + +/** + * Bring up our window; make a connection to the rest of the world + * + */ +BOOL +JavaAccessBridge::initWindow() { + theDialogWindow = CreateDialog(windowsInstance, + "ACCESSBRIDGESTATUSWINDOW", NULL, + (DLGPROC) AccessBridgeDialogProc); + + // If window could not be created, return "failure". + if (!theDialogWindow) + return FALSE; + + dialogWindow = theDialogWindow; + + // Make the window visible, update its client area, & return "success". + // DEBUG_CODE(ShowWindow (theDialogWindow, SW_SHOWNORMAL)); + // DEBUG_CODE(UpdateWindow (theDialogWindow)); + + return TRUE; +} + + + +// ----------------------- + + +/** + * postHelloToWindowsDLLMsg + * - PostMessage(theFromJavaHelloMsgID) to let one or + * all WindowDLLs we're here and have a vmID + * + * destHwnd is either a single hwnd or HWND_BROADCAST + * (former if a reply, latter if we're just born) + * wParam is our HWND + * lParam is our vmID + * + */ +void +JavaAccessBridge::postHelloToWindowsDLLMsg(HWND destHwnd) { + PrintDebugString("\r\nin JavaAccessBridge::postHelloToWindowsDLLMsg"); + PrintDebugString(" calling PostMessage(%p, %X, %p, %p)", + destHwnd, theFromJavaHelloMsgID, dialogWindow, javaVM); + PostMessage(destHwnd, theFromJavaHelloMsgID, (WPARAM) dialogWindow, (LPARAM) dialogWindow); +} + + +// ----------------------- + +/** + * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging + * with the Java AccessBridge DLL + * + */ +void +JavaAccessBridge::sendPackage(char *buffer, int bufsize, HWND destHwnd) { + COPYDATASTRUCT toCopy; + toCopy.dwData = 0; // 32-bits we could use for something... + toCopy.cbData = bufsize; + toCopy.lpData = buffer; + + SendMessage(destHwnd, WM_COPYDATA, (WPARAM) dialogWindow, (LPARAM) &toCopy); +} + + +/** + * sendJavaEventPackage - walk through ATs, sending event messages to 'em + * + */ +void +JavaAccessBridge::sendJavaEventPackage(char *buffer, int bufsize, long type) { + + PrintDebugString("JavaAccessBridge::sendJavaEventPackage(), type = %X", type); + + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + } + + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + ati->sendJavaEventPackage(buffer, bufsize, type); + ati = ati->nextATInstance; + } +} + +/** + * sendAccessibilityEventPackage - walk through ATs, sending event messages to 'em + * + */ +void +JavaAccessBridge::sendAccessibilityEventPackage(char *buffer, int bufsize, long type) { + + PrintDebugString("JavaAccessBridge::sendAccessibilityEventPackage(), type = %X", type); + + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + } + + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + ati->sendAccessibilityEventPackage(buffer, bufsize, type); + ati = ati->nextATInstance; + } +} + + + + +/** + * receiveMemoryPackage - uses Memory-Mapped files to do IPC messaging + * with the Java AccessBridge DLL, receiving the + * message from Java AccessBridge DLL by reading the + * contents of the shared memory mapped file that + * is used for Java-initiated messages + * + */ +BOOL +JavaAccessBridge::receiveMemoryPackage(HWND srcWindow, long bufsize) { + char *IPCview; + + PrintDebugString("\r\nJavaAccessBridge::receiveMemoryPackage(%p, %d)", srcWindow, bufsize); + + // look-up the appropriate IPCview based on the srcHWND of the Windows AccessBridge DLL + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR! - ATs == 0 (shouldn't happen in receiveMemoryPackage()!"); + return FALSE; + } + AccessBridgeATInstance *ati = ATs->findABATInstanceFromATHWND(srcWindow); + if (ati != (AccessBridgeATInstance *) 0) { + IPCview = (char *) ati->memoryMappedView; + + // wait for the lock if someone else has it (re-entrancy) + EnterCriticalSection(&receiveMemoryIPCLock); + { + // set byte at end of buffer to indicate to caller that we have reached this point + IPCview[bufsize] = 1; + + // process the package + processPackage(IPCview, bufsize); + } + // release re-entrance lock + LeaveCriticalSection(&receiveMemoryIPCLock); + + return TRUE; + + } else { + //DEBUG_CODE(AppendToCallInfo("ERROR receiving memory package: couldn't find srcWindow")); + PrintDebugString("ERROR receiving memory package: couldn't find srcWindow"); + return FALSE; + } +} + +/** + * processPackage - processes the output of SendMessage(WM_COPYDATA) + * to do IPC messaging with the Windows AccessBridge DLL + * + */ +LRESULT +JavaAccessBridge::processPackage(char *buffer, int bufsize) { + PrintDebugString("\r\nProcessing package sent from Windows, bufsize = %d:", bufsize); + + PackageType *type = (PackageType *) buffer; + LRESULT returnVal = 0; + PrintDebugString(" PackageType = %X:", *type); + jobject rAC; + + switch (*type) { + + + case cMemoryMappedFileCreatedPackage: + // Windows is telling us it created a memory mapped file for us to use + // in repsonding to various information querying packages (see below) + PrintDebugString(" type == cMemoryMappedFileCreatedPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage))) { + MemoryMappedFileCreatedPackage *pkg = + (MemoryMappedFileCreatedPackage *) (buffer + sizeof(PackageType)); + returnVal = MemoryMappedFileCreated((HWND)ABLongToHandle(pkg->bridgeWindow), pkg->filename); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage)); + } + break; + + // ------------ information querying packages ------------------ + + case cReleaseJavaObjectPackage: + PrintDebugString(" type == cReleaseJavaObjectPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage))) { + ReleaseJavaObjectPackage *pkg = + (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType)); + releaseJavaObject((jobject)pkg->object); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage)); + } + break; + + case cGetAccessBridgeVersionPackage: + PrintDebugString(" type == cGetAccessBridgeVersionPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage))) { + GetAccessBridgeVersionPackage *pkg = + (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getVersionInfo(&(pkg->rVersionInfo)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage)); + } + break; + + case cIsJavaWindowPackage: + PrintDebugString(" type == cIsJavaWindowPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(IsJavaWindowPackage))) { + IsJavaWindowPackage *pkg = + (IsJavaWindowPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = + windowsThreadEntryPoints->isJavaWindow(pkg->window); + PrintDebugString(" -> returning result = %d", pkg->rResult); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(IsJavaWindowPackage)); + } + break; + + case cIsSameObjectPackage: + PrintDebugString(" type == cIsSameObjectPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(IsSameObjectPackage))) { + IsSameObjectPackage *pkg = + (IsSameObjectPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = + windowsThreadEntryPoints->isSameObject((jobject)pkg->obj1, (jobject)pkg->obj2); + PrintDebugString(" -> returning result = %d", pkg->rResult); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(IsSameObjectPackage)); + } + break; + + + case cGetAccessibleContextFromHWNDPackage: + PrintDebugString(" type == cGetAccessibleContextFromHWNDPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage))) { + GetAccessibleContextFromHWNDPackage *pkg = + (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType)); + rAC = windowsThreadEntryPoints->getAccessibleContextFromHWND(pkg->window); + pkg->rAccessibleContext = (JOBJECT64)rAC; + pkg->rVMID = HandleToLong(dialogWindow); + PrintDebugString(" -> returning AC = %p, vmID = %X", rAC, pkg->rVMID); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage)); + } + break; + + + case cGetHWNDFromAccessibleContextPackage: + PrintDebugString(" type == cGetHWNDFromAccessibleContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage))) { + GetHWNDFromAccessibleContextPackage *pkg = + (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType)); + pkg->rHWND = + ABHandleToLong( windowsThreadEntryPoints->getHWNDFromAccessibleContext((jobject)pkg->accessibleContext) ); + PrintDebugString(" -> returning HWND = %p", pkg->rHWND); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage)); + } + break; + + + /* ===== utility methods ===== */ + + case cSetTextContentsPackage: + PrintDebugString(" type == cSetTextContentsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(SetTextContentsPackage))) { + SetTextContentsPackage *pkg = + (SetTextContentsPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = + windowsThreadEntryPoints->setTextContents((jobject)pkg->accessibleContext, pkg->text); + PrintDebugString(" -> returning result = %d", pkg->rResult); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(SetTextContentsPackage)); + } + break; + + case cGetParentWithRolePackage: + if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRolePackage))) { + GetParentWithRolePackage *pkg = + (GetParentWithRolePackage *) (buffer + sizeof(PackageType)); + rAC = windowsThreadEntryPoints->getParentWithRole((jobject)pkg->accessibleContext, pkg->role); + pkg->rAccessibleContext = (JOBJECT64)rAC; + PrintDebugString(" type == cGetParentWithRolePackage"); + PrintDebugString(" pkg->vmID: %X", pkg->vmID); + PrintDebugString(" pkg->accessibleContext: %p", (jobject)pkg->accessibleContext); + PrintDebugString(" pkg->role: %ls", pkg->role); + PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetParentWithRolePackage)); + } + break; + + case cGetTopLevelObjectPackage: + PrintDebugString(" type == cGetTopLevelObjectPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetTopLevelObjectPackage))) { + GetTopLevelObjectPackage *pkg = + (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType)); + rAC = windowsThreadEntryPoints->getTopLevelObject((jobject)pkg->accessibleContext); + pkg->rAccessibleContext = (JOBJECT64)rAC; + PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetTopLevelObjectPackage)); + } + break; + + case cGetParentWithRoleElseRootPackage: + PrintDebugString(" type == cGetParentWithRoleElseRootPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage))) { + GetParentWithRoleElseRootPackage *pkg = + (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType)); + rAC = windowsThreadEntryPoints->getParentWithRoleElseRoot((jobject)pkg->accessibleContext, pkg->role); + pkg->rAccessibleContext = (JOBJECT64)rAC; + PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage)); + } + break; + + case cGetObjectDepthPackage: + PrintDebugString(" type == cGetObjectDepthPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetObjectDepthPackage))) { + GetObjectDepthPackage *pkg = + (GetObjectDepthPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = + windowsThreadEntryPoints->getObjectDepth((jobject)pkg->accessibleContext); + PrintDebugString(" -> returning rResult = %d", pkg->rResult); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetObjectDepthPackage)); + } + break; + + case cGetActiveDescendentPackage: + PrintDebugString(" type == cGetActiveDescendentPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetActiveDescendentPackage))) { + GetActiveDescendentPackage *pkg = + (GetActiveDescendentPackage *) (buffer + sizeof(PackageType)); + rAC = windowsThreadEntryPoints->getActiveDescendent((jobject)pkg->accessibleContext); + pkg->rAccessibleContext = (JOBJECT64)rAC; + PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetActiveDescendentPackage)); + } + break; + + case cGetAccessibleContextAtPackage: + PrintDebugString(" type == cGetAccessibleContextAtPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage))) { + GetAccessibleContextAtPackage *pkg = + (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64) + windowsThreadEntryPoints->getAccessibleContextAt(pkg->x, pkg->y, + (jobject)pkg->AccessibleContext); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage)); + } + break; + + case cGetAccessibleContextWithFocusPackage: + PrintDebugString(" type == cGetAccessibleContextWithFocusPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage))) { + GetAccessibleContextWithFocusPackage *pkg = + (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64) + windowsThreadEntryPoints->getAccessibleContextWithFocus(); + pkg->rVMID = HandleToLong(dialogWindow); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage)); + } + break; + + case cGetAccessibleContextInfoPackage: + PrintDebugString(" type == cGetAccessibleContextInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage))) { + GetAccessibleContextInfoPackage *pkg = + (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleContextInfo( + (jobject)pkg->AccessibleContext, &(pkg->rAccessibleContextInfo)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage)); + } + break; + + case cGetAccessibleChildFromContextPackage: + PrintDebugString(" type == cGetAccessibleChildFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage))) { + GetAccessibleChildFromContextPackage *pkg = + (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleChildFromContext( + (jobject)pkg->AccessibleContext, pkg->childIndex); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage)); + } + break; + + case cGetAccessibleParentFromContextPackage: + PrintDebugString(" type == cGetAccessibleParentFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage))) { + GetAccessibleParentFromContextPackage *pkg = + (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleParentFromContext( + (jobject)pkg->AccessibleContext); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage)); + } + break; + + // ------------ begin AccessibleTable packages ------------------ + + case cGetAccessibleTableInfoPackage: + PrintDebugString(" ##### type == cGetAccessibleTableInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage))) { + GetAccessibleTableInfoPackage *pkg = + (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTableInfo((jobject)pkg->accessibleContext, + &(pkg->rTableInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage)); + } + break; + + case cGetAccessibleTableCellInfoPackage: + PrintDebugString(" ##### type == cGetAccessibleTableCellInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage))) { + GetAccessibleTableCellInfoPackage *pkg = + (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTableCellInfo((jobject)pkg->accessibleTable, pkg->row, + pkg->column, &(pkg->rTableCellInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage)); + } + break; + + case cGetAccessibleTableRowHeaderPackage: + PrintDebugString(" ##### type == cGetAccessibleTableRowHeaderPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage))) { + GetAccessibleTableRowHeaderPackage *pkg = + (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTableRowHeader((jobject)pkg->accessibleContext, + &(pkg->rTableInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage)); + } + break; + + case cGetAccessibleTableColumnHeaderPackage: + PrintDebugString(" ##### type == cGetAccessibleTableColumnHeaderPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage))) { + GetAccessibleTableColumnHeaderPackage *pkg = + (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTableColumnHeader((jobject)pkg->accessibleContext, + &(pkg->rTableInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage)); + } + break; + + + case cGetAccessibleTableRowDescriptionPackage: + PrintDebugString(" ##### type == cGetAccessibleTableRowDescriptionPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage))) { + GetAccessibleTableRowDescriptionPackage *pkg = + (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableRowDescription( + (jobject)pkg->accessibleContext, pkg->row); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage)); + } + break; + + case cGetAccessibleTableColumnDescriptionPackage: + PrintDebugString(" ##### type == cGetAccessibleTableColumnDescriptionPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage))) { + GetAccessibleTableColumnDescriptionPackage *pkg = + (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableColumnDescription( + (jobject)pkg->accessibleContext, pkg->column); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage)); + } + break; + + case cGetAccessibleTableColumnSelectionCountPackage: + PrintDebugString(" ##### type == cGetAccessibleTableColumnSelectionCountPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage))) { + GetAccessibleTableColumnSelectionCountPackage *pkg = + (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType)); + pkg->rCount = windowsThreadEntryPoints->getAccessibleTableColumnSelectionCount( + (jobject)pkg->accessibleTable); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage)); + } + break; + + case cGetAccessibleTableRowSelectionCountPackage: + PrintDebugString(" ##### type == cGetAccessibleTableRowSelectionCountPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage))) { + GetAccessibleTableRowSelectionCountPackage *pkg = + (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType)); + + pkg->rCount = windowsThreadEntryPoints->getAccessibleTableRowSelectionCount( + (jobject)pkg->accessibleTable); + + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage)); + } + break; + + case cIsAccessibleTableRowSelectedPackage: + PrintDebugString(" ##### type == cIsAccessibleTableRowSelectedPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage))) { + IsAccessibleTableRowSelectedPackage *pkg = + (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = windowsThreadEntryPoints->isAccessibleTableRowSelected( + (jobject)pkg->accessibleTable, pkg->row); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage)); + } + break; + + case cIsAccessibleTableColumnSelectedPackage: + PrintDebugString(" ##### type == cIsAccessibleTableColumnSelectedPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage))) { + IsAccessibleTableColumnSelectedPackage *pkg = + (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = windowsThreadEntryPoints->isAccessibleTableColumnSelected( + (jobject)pkg->accessibleTable, pkg->column); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage)); + } + break; + + case cGetAccessibleTableColumnSelectionsPackage: + PrintDebugString(" ##### type == cGetAccessibleTableColumnSelectionsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage))) { + GetAccessibleTableColumnSelectionsPackage *pkg = + (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType)); + PrintDebugString(" ##### cGetAccessibleTableColumnSelectionsPackage count=%d", pkg->count); + windowsThreadEntryPoints->getAccessibleTableColumnSelections( + (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections); + + for (int i = 0; i < pkg->count; i++) { + PrintDebugString(" ##### cGetAccessibleTableColumnSelectionsPackage(%d)=%d", i, pkg->rSelections[i]); + } + + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage)); + } + break; + + + case cGetAccessibleTableRowSelectionsPackage: + PrintDebugString(" ##### type == cGetAccessibleTableRowSelectionsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage))) { + GetAccessibleTableRowSelectionsPackage *pkg = + (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTableRowSelections( + (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage)); + } + break; + + case cGetAccessibleTableRowPackage: + PrintDebugString(" ##### type == cGetAccessibleTableRowPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage))) { + GetAccessibleTableRowPackage *pkg = + (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType)); + pkg->rRow = windowsThreadEntryPoints->getAccessibleTableRow( + (jobject)pkg->accessibleTable, pkg->index); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage)); + } + break; + + case cGetAccessibleTableColumnPackage: + PrintDebugString(" ##### type == cGetAccessibleTableColumnPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage))) { + GetAccessibleTableColumnPackage *pkg = + (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType)); + pkg->rColumn = windowsThreadEntryPoints->getAccessibleTableColumn( + (jobject)pkg->accessibleTable, pkg->index); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage)); + } + break; + + case cGetAccessibleTableIndexPackage: + PrintDebugString(" ##### type == cGetAccessibleTableIndexPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage))) { + GetAccessibleTableIndexPackage *pkg = + (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType)); + pkg->rIndex = windowsThreadEntryPoints->getAccessibleTableIndex( + (jobject)pkg->accessibleTable, pkg->row, pkg->column); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage)); + } + break; + + // ------------ end AccessibleTable packages ------------------ + + + // ------------ begin AccessibleRelationSet packages ------------------ + + case cGetAccessibleRelationSetPackage: + PrintDebugString(" ##### type == cGetAccessibleRelationSetPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage))) { + GetAccessibleRelationSetPackage *pkg = + (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleRelationSet( + (jobject)pkg->accessibleContext, &(pkg->rAccessibleRelationSetInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage)); + } + break; + + // ------------ end AccessibleRelationSet packages ------------------ + + // ------------ begin AccessibleHypertext packages ------------------ + + case cGetAccessibleHypertextPackage: + PrintDebugString(" ##### type == cGetAccessibleHypertextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage))) { + GetAccessibleHypertextPackage *pkg = + (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleHypertext( + (jobject)pkg->accessibleContext, &(pkg->rAccessibleHypertextInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage)); + } + break; + + case cActivateAccessibleHyperlinkPackage: + PrintDebugString(" ##### type == cActivateAccessibleHyperlinkPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage))) { + ActivateAccessibleHyperlinkPackage *pkg = + (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = windowsThreadEntryPoints->activateAccessibleHyperlink( + (jobject)pkg->accessibleContext, (jobject)pkg->accessibleHyperlink); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage)); + } + break; + + case cGetAccessibleHyperlinkCountPackage: + PrintDebugString(" ##### type == cGetAccessibleHyperlinkCountPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage))) { + GetAccessibleHyperlinkCountPackage *pkg = + (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType)); + pkg->rLinkCount = windowsThreadEntryPoints->getAccessibleHyperlinkCount( + (jobject)pkg->accessibleContext); + PrintDebugString(" ##### processing succeeded: pkg->rLinkCount = %d", pkg->rLinkCount); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage)); + } + break; + + case cGetAccessibleHypertextExtPackage: + PrintDebugString(" ##### type == cGetAccessibleHypertextExtPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage))) { + GetAccessibleHypertextExtPackage *pkg = + (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType)); + pkg->rSuccess = windowsThreadEntryPoints->getAccessibleHypertextExt( + (jobject)pkg->accessibleContext, pkg->startIndex, &(pkg->rAccessibleHypertextInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage)); + } + break; + + case cGetAccessibleHypertextLinkIndexPackage: + PrintDebugString(" ##### type == cGetAccessibleHypertextLinkIndexPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage))) { + GetAccessibleHypertextLinkIndexPackage *pkg = + (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType)); + pkg->rLinkIndex = windowsThreadEntryPoints->getAccessibleHypertextLinkIndex( + (jobject)pkg->hypertext, pkg->charIndex); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage)); + } + break; + + case cGetAccessibleHyperlinkPackage: + PrintDebugString(" ##### type == cGetAccessibleHyperlinkPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage))) { + GetAccessibleHyperlinkPackage *pkg = + (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleHyperlink((jobject)pkg->hypertext, pkg->linkIndex, + &(pkg->rAccessibleHyperlinkInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage)); + } + break; + + // ------------ end AccessibleHypertext packages + + // ------------ begin Accessible KeyBindings, Icons and Actions + + case cGetAccessibleKeyBindingsPackage: + PrintDebugString(" ##### type == cGetAccessibleKeyBindingsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage))) { + GetAccessibleKeyBindingsPackage *pkg = + (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleKeyBindings ( + (jobject)pkg->accessibleContext, &(pkg->rAccessibleKeyBindings)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage)); + } + break; + + case cGetAccessibleIconsPackage: + PrintDebugString(" ##### type == cGetAccessibleIconsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleIconsPackage))) { + GetAccessibleIconsPackage *pkg = + (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleIcons ( + (jobject)pkg->accessibleContext, &(pkg->rAccessibleIcons)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleIconsPackage)); + } + break; + + + case cGetAccessibleActionsPackage: + PrintDebugString(" ##### type == cGetAccessibleActionsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleActionsPackage))) { + GetAccessibleActionsPackage *pkg = + (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleActions ( + (jobject)pkg->accessibleContext, &(pkg->rAccessibleActions)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleActionsPackage)); + } + break; + + case cDoAccessibleActionsPackage: + PrintDebugString(" ##### type == cDoAccessibleActionsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(DoAccessibleActionsPackage))) { + DoAccessibleActionsPackage *pkg = + (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = + windowsThreadEntryPoints->doAccessibleActions((jobject)pkg->accessibleContext, &(pkg->actionsToDo), + &(pkg->failure)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(DoAccessibleActionsPackage)); + } + break; + + // ------------ begin addtional methods for Teton + + case cGetVirtualAccessibleNamePackage: + PrintDebugString(" ##### type == GetVirtualAccessibleNamePackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage))) { + GetVirtualAccessibleNamePackage *pkg = + (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getVirtualAccessibleName ((const jobject)pkg->accessibleContext, + pkg->rName, + pkg->len); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage)); + } + break; + + case cRequestFocusPackage: + PrintDebugString(" ##### type == RequestFocusPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(RequestFocusPackage))) { + RequestFocusPackage *pkg = + (RequestFocusPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->requestFocus ( + (jobject)pkg->accessibleContext); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(RequestFocusPackage)); + } + break; + + case cSelectTextRangePackage: + PrintDebugString(" ##### type == SelectTextRangePackage"); + if (bufsize == (sizeof(PackageType) + sizeof(SelectTextRangePackage))) { + SelectTextRangePackage *pkg = + (SelectTextRangePackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->selectTextRange ( + (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(SelectTextRangePackage)); + } + break; + + case cGetTextAttributesInRangePackage: + PrintDebugString(" ##### type == GetTextAttributesInRangePackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage))) { + GetTextAttributesInRangePackage *pkg = + (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getTextAttributesInRange ( + (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex, + (AccessibleTextAttributesInfo *)&(pkg->attributes), + &(pkg->rLength)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage)); + } + break; + + + case cGetVisibleChildrenCountPackage: + PrintDebugString(" ##### type == GetVisibleChildrenCountPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage))) { + GetVisibleChildrenCountPackage *pkg = + (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType)); + pkg->rChildrenCount = windowsThreadEntryPoints->getVisibleChildrenCount ((jobject)pkg->accessibleContext); + + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage)); + } + break; + + case cGetVisibleChildrenPackage: + PrintDebugString(" ##### type == GetVisibleChildrenPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenPackage))) { + GetVisibleChildrenPackage *pkg = + (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType)); + pkg->rSuccess = windowsThreadEntryPoints->getVisibleChildren ((jobject)pkg->accessibleContext, + pkg->startIndex, + &(pkg->rVisibleChildrenInfo)); + + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenPackage)); + } + break; + + case cSetCaretPositionPackage: + PrintDebugString(" ##### type == SetCaretPositionPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(SetCaretPositionPackage))) { + SetCaretPositionPackage *pkg = + (SetCaretPositionPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->setCaretPosition ( + (jobject)pkg->accessibleContext, pkg->position); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(SetCaretPositionPackage)); + } + break; + + // ------------ end additional methods for Teton + + // ------------ end Accessible KeyBindings, Icons and Actions + + // ------------ Accessible Text packages ------------------ + + case cGetAccessibleTextInfoPackage: + PrintDebugString(" type == cGetAccessibleTextInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage))) { + GetAccessibleTextInfoPackage *pkg = + (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextInfo((jobject)pkg->AccessibleContext, + &(pkg->rTextInfo), pkg->x, pkg->y); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage)); + } + break; + + case cGetAccessibleTextItemsPackage: + PrintDebugString(" type == cGetAccessibleTextItemsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage))) { + GetAccessibleTextItemsPackage *pkg = + (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextItems((jobject)pkg->AccessibleContext, + &(pkg->rTextItemsInfo), pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage)); + } + break; + + case cGetAccessibleTextSelectionInfoPackage: + PrintDebugString(" type == cGetAccessibleTextSelectionInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage))) { + GetAccessibleTextSelectionInfoPackage *pkg = + (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextSelectionInfo( + (jobject)pkg->AccessibleContext, &(pkg->rTextSelectionItemsInfo)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage)); + } + break; + + case cGetAccessibleTextAttributeInfoPackage: + PrintDebugString(" type == cGetAccessibleTextAttributeInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage))) { + GetAccessibleTextAttributeInfoPackage *pkg = + (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextAttributes( + (jobject)pkg->AccessibleContext, pkg->index, (AccessibleTextAttributesInfo *) &(pkg->rAttributeInfo)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage)); + } + break; + + case cGetAccessibleTextRectInfoPackage: + PrintDebugString(" type == cGetAccessibleTextRectInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage))) { + GetAccessibleTextRectInfoPackage *pkg = + (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextRect((jobject)pkg->AccessibleContext, + &(pkg->rTextRectInfo), pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage)); + } + break; + + case cGetCaretLocationPackage: + PrintDebugString(" type == cGetCaretLocationPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetCaretLocationPackage))) { + GetCaretLocationPackage *pkg = + (GetCaretLocationPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getCaretLocation((jobject)pkg->AccessibleContext, + &(pkg->rTextRectInfo), pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetCaretLocationPackage)); + } + break; + + case cGetAccessibleTextLineBoundsPackage: + PrintDebugString(" type == cGetAccessibleTextLineBoundsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage))) { + GetAccessibleTextLineBoundsPackage *pkg = + (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextLineBounds((jobject)pkg->AccessibleContext, + pkg->index, &(pkg->rLineStart), &(pkg->rLineEnd)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage)); + } + break; + + case cGetAccessibleTextRangePackage: + PrintDebugString(" type == cGetAccessibleTextRangePackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage))) { + GetAccessibleTextRangePackage *pkg = + (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextRange((jobject)pkg->AccessibleContext, + pkg->start, pkg->end, (wchar_t *) &(pkg->rText), (sizeof(pkg->rText) / sizeof(wchar_t))); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage)); + } + break; + + + // ------------ Accessible Value packages ------------------ + + case cGetCurrentAccessibleValueFromContextPackage: + PrintDebugString(" type == cGetCurrentAccessibleValueFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage))) { + GetCurrentAccessibleValueFromContextPackage *pkg = + (GetCurrentAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getCurrentAccessibleValueFromContext((jobject)pkg->AccessibleContext, + (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t))); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage)); + } + break; + + case cGetMaximumAccessibleValueFromContextPackage: + PrintDebugString(" type == cGetMaximumAccessibleValueFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage))) { + GetMaximumAccessibleValueFromContextPackage *pkg = + (GetMaximumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getMaximumAccessibleValueFromContext((jobject)pkg->AccessibleContext, + (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t))); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage)); + } + break; + + case cGetMinimumAccessibleValueFromContextPackage: + PrintDebugString(" type == cGetMinimumAccessibleValueFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage))) { + GetMinimumAccessibleValueFromContextPackage *pkg = + (GetMinimumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getMinimumAccessibleValueFromContext((jobject)pkg->AccessibleContext, + (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t))); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage)); + } + break; + + // ------------ Accessible Selection packages ------------------ + + case cAddAccessibleSelectionFromContextPackage: + PrintDebugString(" type == cAddAccessibleSelectionFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage))) { + AddAccessibleSelectionFromContextPackage *pkg = + (AddAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->addAccessibleSelectionFromContext((jobject)pkg->AccessibleContext, + pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage)); + } + break; + + case cClearAccessibleSelectionFromContextPackage: + PrintDebugString(" type == cClearAccessibleSelectionFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage))) { + ClearAccessibleSelectionFromContextPackage *pkg = + (ClearAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->clearAccessibleSelectionFromContext((jobject)pkg->AccessibleContext); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage)); + } + break; + + case cGetAccessibleSelectionFromContextPackage: + PrintDebugString(" type == cGetAccessibleSelectionFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage))) { + GetAccessibleSelectionFromContextPackage *pkg = + (GetAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleSelectionFromContext( + (jobject)pkg->AccessibleContext, pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage)); + } + break; + + case cGetAccessibleSelectionCountFromContextPackage: + PrintDebugString(" type == cGetAccessibleSelectionCountFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage))) { + GetAccessibleSelectionCountFromContextPackage *pkg = + (GetAccessibleSelectionCountFromContextPackage *) (buffer + sizeof(PackageType)); + pkg->rCount = windowsThreadEntryPoints->getAccessibleSelectionCountFromContext( + (jobject)pkg->AccessibleContext); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage)); + } + break; + + case cIsAccessibleChildSelectedFromContextPackage: + PrintDebugString(" type == cIsAccessibleChildSelectedFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage))) { + IsAccessibleChildSelectedFromContextPackage *pkg = + (IsAccessibleChildSelectedFromContextPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = windowsThreadEntryPoints->isAccessibleChildSelectedFromContext( + (jobject)pkg->AccessibleContext, pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage)); + } + break; + + case cRemoveAccessibleSelectionFromContextPackage: + PrintDebugString(" type == cRemoveAccessibleSelectionFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage))) { + RemoveAccessibleSelectionFromContextPackage *pkg = + (RemoveAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->removeAccessibleSelectionFromContext((jobject)pkg->AccessibleContext, + pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage)); + } + break; + + case cSelectAllAccessibleSelectionFromContextPackage: + PrintDebugString(" type == cSelectAllAccessibleSelectionFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage))) { + SelectAllAccessibleSelectionFromContextPackage *pkg = + (SelectAllAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->selectAllAccessibleSelectionFromContext((jobject)pkg->AccessibleContext); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage)); + } + break; + + + // ------------ event notification management packages ------------------ + + case cAddJavaEventNotificationPackage: + PrintDebugString(" type = cAddJavaEventNotificationPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage))) { + AddJavaEventNotificationPackage *pkg = + (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType)); + addJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow ) ); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage)); + } + break; + + case cRemoveJavaEventNotificationPackage: + PrintDebugString(" type = cRemoveJavaEventNotificationPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage))) { + RemoveJavaEventNotificationPackage *pkg = + (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType)); + removeJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow )); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage)); + } + break; + + case cAddAccessibilityEventNotificationPackage: + PrintDebugString(" type = cAddAccessibilityEventNotificationPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage))) { + AddAccessibilityEventNotificationPackage *pkg = + (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType)); + addAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage)); + } + break; + + case cRemoveAccessibilityEventNotificationPackage: + PrintDebugString(" type = cRemoveAccessibilityEventNotificationPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage))) { + RemoveAccessibilityEventNotificationPackage *pkg = + (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType)); + removeAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage)); + } + break; + + default: + PrintDebugString(" processing FAILED!! -> don't know how to handle type = %X", *type); + returnVal = -1; + break; + } + + PrintDebugString(" package processing completed"); + return returnVal; +} + + +// ----------------------------- + + +/** + * MemoryMappedFileCreated + * - WindowsDLL letting us know it's created a memory-mapped file + * for IPC. We need to open it and write a magic string into + * it to let the WindowsDLL know all is OK. Also we need to + * set up our own data structures to communicate with the + * WindowsDLL + * + */ +LRESULT +JavaAccessBridge::MemoryMappedFileCreated(HWND ATBridgeDLLWindow, char *filename) { + PrintDebugString(" in MemoryMappedFileCreated(%p, %s)!", ATBridgeDLLWindow, filename); + AccessBridgeATInstance *newAT = + new AccessBridgeATInstance(dialogWindow, ATBridgeDLLWindow, filename, ATs); + PrintDebugString(" just created a new ATInstance = %p, old = %p", newAT, ATs); + ATs = newAT; + + LRESULT returnVal = ATs->initiateIPC(); + if (returnVal == 0) { + PrintDebugString(" Successfully initiated IPC with AT!!!"); + } else { + PrintDebugString(" ERROR: Failed to initiate IPC with AT!!!"); + } + + return returnVal; +} + + +/** + * WindowsATDestroyed - lets the JavaABDLL know a Windows AT disappeared + * + */ +void +JavaAccessBridge::WindowsATDestroyed(HWND ATBridgeDLLWindow) { + PrintDebugString("\r\nin JavaAccessBridge::WindowsATDestroyed(%p)", ATBridgeDLLWindow); + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! -> ATs == 0! (shouldn't happen here)"); + return; + } + + AccessBridgeATInstance *currentAT = ATs; + AccessBridgeATInstance *previousAT = ATs; + if (ATs->winAccessBridgeWindow == ATBridgeDLLWindow) { + ATs = ATs->nextATInstance; + // remove event notification for this AT + removeJavaEventNotification(currentAT->javaEventMask, ATBridgeDLLWindow); + removeAccessibilityEventNotification(currentAT->accessibilityEventMask, ATBridgeDLLWindow); + delete currentAT; + PrintDebugString(" data structures successfully removed"); + } else { + while (currentAT != (AccessBridgeATInstance *) NULL) { + if (currentAT->winAccessBridgeWindow == ATBridgeDLLWindow) { + previousAT->nextATInstance = currentAT->nextATInstance; + delete currentAT; + PrintDebugString(" data structures successfully removed"); + return; + } else { + previousAT = currentAT; + currentAT = currentAT->nextATInstance; + } + } + PrintDebugString(" ERROR!! couldn't find matching data structures!"); + } +} + + +// ----------------------------- + + +/** + * releaseJavaObject - lets the JavaVM know it can release the Java Object + * + * Note: once you have made this call, the JavaVM will garbage collect + * the jobject you pass in. If you later use that jobject in another + * call, you will cause all maner of havoc! + * + */ +void +JavaAccessBridge::releaseJavaObject(jobject object) { + PrintDebugString("In JavaAccessBridge::releaseJavaObject"); + PrintDebugString(" object X: %p", object); + if (windowsThreadJNIEnv != (JNIEnv *) 0) { + windowsThreadJNIEnv->DeleteGlobalRef(object); + PrintDebugString(" global reference deleted.", object); + } else { + PrintDebugString(" Error! windowsThreadJNIEnv == 0"); + } +} + +// ----------------------------- + +/** + * addJavaEventNotification - this AT now wants this type of events + * + */ +void +JavaAccessBridge::addJavaEventNotification(jlong type, HWND DLLwindow) { + // walk through list of ATs, find this one and add this type + // and, if we weren't listening for these before, ask Java for 'em + PrintDebugString(" adding Java event type %016I64X to HWND %p", type, DLLwindow); + AccessBridgeATInstance *ati = ATs; + long globalEventMask = 0; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->winAccessBridgeWindow == DLLwindow) { + ati->javaEventMask |= type; + PrintDebugString(" found HWND, javaEventMask now is %X", ati->javaEventMask); + } else { + globalEventMask |= ati->javaEventMask; + } + ati = ati->nextATInstance; + } + PrintDebugString(" union of all Java AT event masks: %X", globalEventMask); + if (!(globalEventMask & type)) { + // no other ATs wanted this event; + // start getting them from Java + PrintDebugString(" no other AT wanted this Java event (so not registered); adding to AccessBridge.java"); + windowsThreadEntryPoints->addJavaEventNotification(type); + } +} + +/** + * removeJavaEventNotification - this AT no longer wants this type of events + * + */ +void +JavaAccessBridge::removeJavaEventNotification(jlong type, HWND DLLwindow) { + // walk through list of ATs, find this one and remove this type + // and, if no other AT wants 'em either, tell Java we no longer want 'em + PrintDebugString(" removing Java event type %016I64X from HWND %p", type, DLLwindow); + AccessBridgeATInstance *ati = ATs; + long globalEventMask = 0; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->winAccessBridgeWindow == DLLwindow) { + ati->javaEventMask &= (0xFFFFFFFF - type); + PrintDebugString(" found HWND, javaEventMask now is %X", ati->javaEventMask); + } else { + globalEventMask |= ati->javaEventMask; + } + ati = ati->nextATInstance; + } + PrintDebugString(" union of all Java AT event masks: %X", globalEventMask); + if (!(globalEventMask & type)) { + // no other ATs wanted this event; + // stop getting them from Java + PrintDebugString(" no other AT wanted this Java event (so can remove); removing from AccessBridge.java"); + windowsThreadEntryPoints->removeJavaEventNotification(type); + } +} + + +/** + * addAccesibilityEventNotification - this AT now wants this type of events + * + */ +void +JavaAccessBridge::addAccessibilityEventNotification(jlong type, HWND DLLwindow) { + // walk through list of ATs, find this one and add this type + // and, if we weren't listening for these before, ask Java for 'em + PrintDebugString(" adding Accesibility event type %016I64X to HWND %p", type, DLLwindow); + AccessBridgeATInstance *ati = ATs; + long globalEventMask = 0; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->winAccessBridgeWindow == DLLwindow) { + ati->accessibilityEventMask |= type; + PrintDebugString(" found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask); + } else { + globalEventMask |= ati->accessibilityEventMask; + } + ati = ati->nextATInstance; + } + PrintDebugString(" union of all Accessibility AT event masks: %X", globalEventMask); + if (!(globalEventMask & type)) { + // no other ATs wanted this event; + // start getting them from Java + PrintDebugString(" no other AT wanted this Accesibility event (so not registered); adding to AccessBridge.java"); + windowsThreadEntryPoints->addAccessibilityEventNotification(type); + } +} + +/** + * removeAccesibilityEventNotification - this AT no longer wants this type of events + * + */ +void +JavaAccessBridge::removeAccessibilityEventNotification(jlong type, HWND DLLwindow) { + // walk through list of ATs, find this one and remove this type + // and, if no other AT wants 'em either, tell Java we no longer want 'em + PrintDebugString(" removing Accesibility event type %016I64X from HWND %p", type, DLLwindow); + AccessBridgeATInstance *ati = ATs; + long globalEventMask = 0; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->winAccessBridgeWindow == DLLwindow) { + ati->accessibilityEventMask &= (0xFFFFFFFF - type); + PrintDebugString(" found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask); + } else { + globalEventMask |= ati->accessibilityEventMask; + } + ati = ati->nextATInstance; + } + PrintDebugString(" union of all Accessibility AT event masks: %X", globalEventMask); + if (!(globalEventMask & type)) { + // no other ATs wanted this event; + // stop getting them from Java + PrintDebugString(" no other AT wanted this Accessibility event (so can remove); removing from AccessBridge.java"); + windowsThreadEntryPoints->removeAccessibilityEventNotification(type); + } +} + + + + +/** + * firePropertyCaretChange + * + */ +void +JavaAccessBridge::firePropertyCaretChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jint oldValue, jint newValue) { + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyCaretChanged(%p, %p, %p, %p, %d, %d)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertyCaretChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyCaretChangePackage *pkg = (PropertyCaretChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyCaretChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + pkg->oldPosition = oldValue; + pkg->newPosition = newValue; + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyCaretChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyCaretChange event"); +} + +/** + * firePropertyDescriptionChange + * + */ +void +JavaAccessBridge::firePropertyDescriptionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyDescriptionChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + const wchar_t *stringBytes; + char buffer[sizeof(PackageType) + sizeof(PropertyDescriptionChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyDescriptionChangePackage *pkg = (PropertyDescriptionChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyDescriptionChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + if (oldValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->oldDescription, stringBytes, (sizeof(pkg->oldDescription) / sizeof(wchar_t))); + env->ReleaseStringChars(oldValue, stringBytes); + } else { + wcsncpy(pkg->oldDescription, L"(null)", (sizeof(pkg->oldDescription) / sizeof(wchar_t))); + } + + if (newValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->newDescription, stringBytes, (sizeof(pkg->newDescription) / sizeof(wchar_t))); + env->ReleaseStringChars(newValue, stringBytes); + } else { + wcsncpy(pkg->newDescription, L"(null)", (sizeof(pkg->newDescription) / sizeof(wchar_t))); + } + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyDescriptionChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyDescriptionChange event"); +} + +/** + * firePropertyNameChange + * + */ +void +JavaAccessBridge::firePropertyNameChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyNameChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + const wchar_t *stringBytes; + char buffer[sizeof(PackageType) + sizeof(PropertyNameChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyNameChangePackage *pkg = (PropertyNameChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyNameChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyNameChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + if (oldValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->oldName, stringBytes, (sizeof(pkg->oldName) / sizeof(wchar_t))); + env->ReleaseStringChars(oldValue, stringBytes); + } else { + wcsncpy(pkg->oldName, L"(null)", (sizeof(pkg->oldName) / sizeof(wchar_t))); + } + + if (newValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->newName, stringBytes, (sizeof(pkg->newName) / sizeof(wchar_t))); + env->ReleaseStringChars(newValue, stringBytes); + } else { + wcsncpy(pkg->newName, L"(null)", (sizeof(pkg->newName) / sizeof(wchar_t))); + } + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyNameChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyNameChange event"); +} + + +/** + * firePropertySelectionChange + * + */ +void +JavaAccessBridge::firePropertySelectionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertySelectionChanged(%p, %p, %p, %p)", + env, callingObj, event, source); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertySelectionChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertySelectionChangePackage *pkg = (PropertySelectionChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertySelectionChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertySelectionChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertySelectionChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertySelectionChange event"); +} + + +/** + * firePropertyStateChange + * + */ +void +JavaAccessBridge::firePropertyStateChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyStateChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + const wchar_t *stringBytes; + char buffer[sizeof(PackageType) + sizeof(PropertyStateChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyStateChangePackage *pkg = (PropertyStateChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyStateChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyStateChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + if (oldValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->oldState, stringBytes, (sizeof(pkg->oldState) / sizeof(wchar_t))); + env->ReleaseStringChars(oldValue, stringBytes); + } else { + wcsncpy(pkg->oldState, L"(null)", (sizeof(pkg->oldState) / sizeof(wchar_t))); + } + + if (newValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->newState, stringBytes, (sizeof(pkg->newState) / sizeof(wchar_t))); + env->ReleaseStringChars(newValue, stringBytes); + } else { + wcsncpy(pkg->newState, L"(null)", (sizeof(pkg->newState) / sizeof(wchar_t))); + } + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyStateChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyStateChange event"); +} + + +/** + * firePropertyTextChange + * + */ +void +JavaAccessBridge::firePropertyTextChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTextChanged(%p, %p, %p, %p)", + env, callingObj, event, source); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertyTextChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyTextChangePackage *pkg = (PropertyTextChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyTextChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyTextChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTextChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyTextChange event"); +} + + +/** + * firePropertyValueChange + * + */ +void +JavaAccessBridge::firePropertyValueChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyValueChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + const wchar_t *stringBytes; + char buffer[sizeof(PackageType) + sizeof(PropertyValueChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyValueChangePackage *pkg = (PropertyValueChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyValueChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyValueChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + if (oldValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->oldValue, stringBytes, (sizeof(pkg->oldValue) / sizeof(wchar_t))); + env->ReleaseStringChars(oldValue, stringBytes); + } else { + wcsncpy(pkg->oldValue, L"(null)", (sizeof(pkg->oldValue) / sizeof(wchar_t))); + } + + if (newValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->newValue, stringBytes, (sizeof(pkg->newValue) / sizeof(wchar_t))); + env->ReleaseStringChars(newValue, stringBytes); + } else { + wcsncpy(pkg->newValue, L"(null)", (sizeof(pkg->newValue) / sizeof(wchar_t))); + } + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyValueChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyValueChange event"); +} + +/** + * firePropertyVisibleDataChange + * + */ +void +JavaAccessBridge::firePropertyVisibleDataChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChanged(%p, %p, %p, %p)", + env, callingObj, event, source); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertyVisibleDataChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyVisibleDataChangePackage *pkg = (PropertyVisibleDataChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyVisibleDataChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyVisibleDataChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyVisibleDataChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyVisibleDataChange event"); +} + + +/** + * firePropertyChildChange + * + */ +void +JavaAccessBridge::firePropertyChildChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, jobject newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyChildPropertyChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertyChildChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyChildChangePackage *pkg = (PropertyChildChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyChildChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyChildChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); + pkg->oldChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue); + pkg->newChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString(" GlobalRef'd OldChildAC: %p", pkg->oldChildAccessibleContext); + PrintDebugString(" GlobalRef'd NewChildAC: %p", pkg->newChildAccessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString(" GlobalRef'd OldChildAC: %016I64X", pkg->oldChildAccessibleContext); + PrintDebugString(" GlobalRef'd NewChildAC: %016I64X", pkg->newChildAccessibleContext); +#endif + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyChildChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyChildChange event"); +} + + +/** + * firePropertyActiveDescendentChange + * + */ +void +JavaAccessBridge::firePropertyActiveDescendentChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, jobject newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentPropertyChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertyActiveDescendentChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyActiveDescendentChangePackage *pkg = (PropertyActiveDescendentChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyActiveDescendentChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyActiveDescendentChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); + pkg->oldActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue); + pkg->newActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString(" GlobalRef'd OldActiveDescendentAC: %p", pkg->oldActiveDescendentAccessibleContext); + PrintDebugString(" GlobalRef'd NewActiveDescendentAC: %p", pkg->newActiveDescendentAccessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString(" GlobalRef'd OldActiveDescendentAC: %016I64X", pkg->oldActiveDescendentAccessibleContext); + PrintDebugString(" GlobalRef'd NewActiveDescendentAC: %016I64X", pkg->newActiveDescendentAccessibleContext); +#endif + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyActiveDescendentChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyActiveChange event"); +} + +/** + * firePropertyValueChange + * + */ +void +JavaAccessBridge::firePropertyTableModelChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + const wchar_t *stringBytes; + char buffer[sizeof(PackageType) + sizeof(PropertyTableModelChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyTableModelChangePackage *pkg = (PropertyTableModelChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyTableModelChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyTableModelChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + if (oldValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->oldValue, stringBytes, (sizeof(pkg->oldValue) / sizeof(wchar_t))); + env->ReleaseStringChars(oldValue, stringBytes); + } else { + wcsncpy(pkg->oldValue, L"(null)", (sizeof(pkg->oldValue) / sizeof(wchar_t))); + } + + if (newValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->newValue, stringBytes, (sizeof(pkg->newValue) / sizeof(wchar_t))); + env->ReleaseStringChars(newValue, stringBytes); + } else { + wcsncpy(pkg->newValue, L"(null)", (sizeof(pkg->newValue) / sizeof(wchar_t))); + } + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTableModelChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyTableModelChange event"); +} + + + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +#define PRINT_GLOBALREFS() \ + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); \ + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) +#define PRINT_GLOBALREFS() \ + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); \ + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + +#define FIRE_EVENT(function, packageStruct, packageConstant, eventConstant) \ + void JavaAccessBridge::function(JNIEnv *env, jobject callingObj, \ + jobject eventObj, jobject source) { \ + \ + PrintDebugString("\r\nFiring event id = %d(%p, %p, %p, %p); vmID = %X", \ + eventConstant, env, callingObj, eventObj, source, javaVM); \ + \ + /* sanity check */ \ + if (ATs == (AccessBridgeATInstance *) 0) { \ + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); \ + return; /* panic! */ \ + } \ + \ + /* common setup */ \ + char buffer[sizeof(PackageType) + sizeof(packageStruct)]; \ + PackageType *type = (PackageType *) buffer; \ + packageStruct *pkg = (packageStruct *) (buffer + sizeof(PackageType)); \ + *type = packageConstant; \ + pkg->vmID = (long) dialogWindow; \ + \ + /* make new Global Refs, send events only to those ATs that want 'em */ \ + AccessBridgeATInstance *ati = ATs; \ + while (ati != (AccessBridgeATInstance *) 0) { \ + PrintDebugString("\r\njavaEventMask = %X eventConstant=%d pkg->vmID=%X", \ + ati->javaEventMask, eventConstant, pkg->vmID ); \ + if (ati->javaEventMask & eventConstant) { \ + \ + PrintDebugString(" sending to AT"); \ + /* make new GlobalRefs for this AT */ \ + pkg->Event = (JOBJECT64)env->NewGlobalRef(eventObj); \ + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); \ + PRINT_GLOBALREFS() \ + \ + ati->sendJavaEventPackage(buffer, sizeof(buffer), eventConstant); \ + } \ + ati = ati->nextATInstance; \ + } \ + PrintDebugString(" done with firing AWT event"); \ + } + + void JavaAccessBridge::javaShutdown(JNIEnv *env, jobject callingObj) { + + PrintDebugString("\r\nFiring event id = %d(%p, %p); vmID = %X", + cJavaShutdownEvent, env, callingObj, javaVM); + + /* sanity check */ + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; /* panic! */ + } + + /* common setup */ + char buffer[sizeof(PackageType) + sizeof(JavaShutdownPackage)]; + PackageType *type = (PackageType *) buffer; + JavaShutdownPackage *pkg = (JavaShutdownPackage *) (buffer + sizeof(PackageType)); + *type = cJavaShutdownPackage; + pkg->vmID = (long) dialogWindow; + + /* make new Global Refs, send events only to those ATs that want 'em */ + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->javaEventMask & cJavaShutdownEvent) { + PrintDebugString(" sending to AT"); + ati->sendJavaEventPackage(buffer, sizeof(buffer), cJavaShutdownEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with firing AWT event"); + } + + FIRE_EVENT(fireFocusGained, FocusGainedPackage, cFocusGainedPackage, cFocusGainedEvent) + FIRE_EVENT(fireFocusLost, FocusLostPackage, cFocusLostPackage, cFocusLostEvent) + FIRE_EVENT(fireCaretUpdate, CaretUpdatePackage, cCaretUpdatePackage, cCaretUpdateEvent) + FIRE_EVENT(fireMouseClicked, MouseClickedPackage, cMouseClickedPackage, cMouseClickedEvent) + FIRE_EVENT(fireMouseEntered, MouseEnteredPackage, cMouseEnteredPackage, cMouseEnteredEvent) + FIRE_EVENT(fireMouseExited, MouseExitedPackage, cMouseExitedPackage, cMouseExitedEvent) + FIRE_EVENT(fireMousePressed, MousePressedPackage, cMousePressedPackage, cMousePressedEvent) + FIRE_EVENT(fireMouseReleased, MouseReleasedPackage, cMouseReleasedPackage, cMouseReleasedEvent) + FIRE_EVENT(fireMenuCanceled, MenuCanceledPackage, cMenuCanceledPackage, cMenuCanceledEvent) + FIRE_EVENT(fireMenuDeselected, MenuDeselectedPackage, cMenuDeselectedPackage, cMenuDeselectedEvent) + FIRE_EVENT(fireMenuSelected, MenuSelectedPackage, cMenuSelectedPackage, cMenuSelectedEvent) + FIRE_EVENT(firePopupMenuCanceled, PopupMenuCanceledPackage, cPopupMenuCanceledPackage, cPopupMenuCanceledEvent) + FIRE_EVENT(firePopupMenuWillBecomeInvisible, PopupMenuWillBecomeInvisiblePackage, cPopupMenuWillBecomeInvisiblePackage, cPopupMenuWillBecomeInvisibleEvent) + FIRE_EVENT(firePopupMenuWillBecomeVisible, PopupMenuWillBecomeVisiblePackage, cPopupMenuWillBecomeVisiblePackage, cPopupMenuWillBecomeVisibleEvent) + + + // ----------------------------- + + +extern "C" { // event stuff from AccessBridge.h, generated by JNI + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_sendDebugString(JNIEnv *env, jobject callingObj, jstring debugStr) { + + const wchar_t *stringBytes; + stringBytes = (const wchar_t *) env->GetStringChars(debugStr, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wPrintJavaDebugString(L"AccessBridge.java: %ls", stringBytes); + env->ReleaseStringChars(debugStr, stringBytes); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyCaretChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jint oldValue, jint newValue) { + theJavaAccessBridge->firePropertyCaretChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyDescriptionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue) { + theJavaAccessBridge->firePropertyDescriptionChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyNameChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue) { + theJavaAccessBridge->firePropertyNameChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertySelectionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + theJavaAccessBridge->firePropertySelectionChange(env, callingObj, + event, source); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyStateChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue) { + theJavaAccessBridge->firePropertyStateChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyTextChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + theJavaAccessBridge->firePropertyTextChange(env, callingObj, + event, source); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyValueChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue) { + theJavaAccessBridge->firePropertyValueChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + theJavaAccessBridge->firePropertyVisibleDataChange(env, callingObj, + event, source); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyChildChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, jobject newValue) { + theJavaAccessBridge->firePropertyChildChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, + jobject newValue) { + theJavaAccessBridge->firePropertyActiveDescendentChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue) { + + theJavaAccessBridge->firePropertyTableModelChange(env, callingObj, + event, source, + oldValue, newValue); + } + +#define HANDLE_STANDARD_EVENT_FROM_JAVA(function, method) \ + JNIEXPORT void JNICALL \ + function(JNIEnv *env, jobject callingObj, jobject event, jobject source) { \ + theJavaAccessBridge->method(env, callingObj, event, source); \ + } + + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_javaShutdown(JNIEnv *env, jobject callingObj) { + theJavaAccessBridge->javaShutdown(env, callingObj); + } + + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_focusGained, fireFocusGained) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_focusLost, fireFocusLost) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_caretUpdate, fireCaretUpdate) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseClicked, fireMouseClicked) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseEntered, fireMouseEntered) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseExited, fireMouseExited) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mousePressed, fireMousePressed) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseReleased, fireMouseReleased) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuCanceled, fireMenuCanceled) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuDeselected, fireMenuDeselected) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuSelected, fireMenuSelected) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuCanceled, firePopupMenuCanceled) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuWillBecomeInvisible, firePopupMenuWillBecomeInvisible) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuWillBecomeVisible, firePopupMenuWillBecomeVisible) + + } --- /dev/null 2015-03-30 10:56:08.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/JavaAccessBridge.h 2015-03-30 10:56:07.803901400 -0500 @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A DLL which is loaded by Java applications to handle communication + * between Java VMs purposes of Accessbility. + */ + +#include +#include + +#include "AccessBridgePackages.h" +#include "AccessBridgeATInstance.h" +#include "AccessBridgeJavaEntryPoints.h" + +#ifndef __JavaAccessBridge_H__ +#define __JavaAccessBridge_H__ + + +extern "C" { + BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, + LPVOID lpvReserved); + void AppendToCallOutput(char *s); + BOOL APIENTRY AccessBridgeDialogProc(HWND hDlg, UINT message, + UINT wParam, LONG lParam); +} + +/** + * The JavaAccessBridge class. The core of the Windows AT AccessBridge dll + */ +class JavaAccessBridge { +// for debugging +public: +// for debugging + HINSTANCE windowsInstance; + HWND dialogWindow; + AccessBridgeATInstance *ATs; + JavaVM *javaVM; + JNIEnv *windowsThreadJNIEnv; // for calls initiated from Windows + AccessBridgeJavaEntryPoints *javaThreadEntryPoints; + AccessBridgeJavaEntryPoints *windowsThreadEntryPoints; + jobject javaThreadABObject; // for calls initiated from Java + jobject windowsThreadABObject; // for calls initiated from Windows + +public: + JavaAccessBridge(HINSTANCE hInstance); + ~JavaAccessBridge(); + void javaRun(JNIEnv *env, jobject obj); + BOOL initWindow(); + + // IPC with the Java AccessBridge DLL + void postHelloToWindowsDLLMsg(HWND destHwnd); + LRESULT MemoryMappedFileCreated(HWND srcHwnd, char *filename); + + void sendPackage(char *buffer, int bufsize, HWND destHwnd); + void sendJavaEventPackage(char *buffer, int bufsize, long type); + void sendAccessibilityEventPackage(char *buffer, int bufsize, long type); + BOOL sendMemoryPackage(char *buffer, long bufsize, HWND destWindow); + LRESULT processPackage(char *buffer, int bufsize); + BOOL receiveMemoryPackage(HWND srcWindow, long bufsize); + void WindowsATDestroyed(HWND ATBridgeDLLWindow); + + // Java VM object memory management + void releaseJavaObject(jobject object); + + // Event handling methods + void addJavaEventNotification(jlong type, HWND DLLwindow); + void removeJavaEventNotification(jlong type, HWND DLLwindow); + void addAccessibilityEventNotification(jlong type, HWND DLLwindow); + void removeAccessibilityEventNotification(jlong type, HWND DLLwindow); + + // Event firing methods +/* + void firePropertyChange(JNIEnv *env, jobject callingObj, + jobject propertyChangeEvent, + jobject source, jstring propertyName, + jstring oldValue, jstring newValue); +*/ + + void javaShutdown(JNIEnv *env, jobject callingObj); + + void fireFocusGained(JNIEnv *env, jobject callingObj, + jobject focusEvent, jobject source); + void fireFocusLost(JNIEnv *env, jobject callingObj, + jobject focusEvent,jobject source); + void fireCaretUpdate(JNIEnv *env, jobject callingObj, + jobject caretEvent, jobject source); + void fireMouseClicked(JNIEnv *env, jobject callingObj, + jobject mouseEvent, jobject source); + void fireMouseEntered(JNIEnv *env, jobject callingObj, + jobject mouseEvent, jobject source); + void fireMouseExited(JNIEnv *env, jobject callingObj, + jobject mouseEvent, jobject source); + void fireMousePressed(JNIEnv *env, jobject callingObj, + jobject mouseEvent, jobject source); + void fireMouseReleased(JNIEnv *env, jobject callingObj, + jobject mouseEvent, jobject source); + void fireMenuCanceled(JNIEnv *env, jobject callingObj, + jobject menuEvent, jobject source); + void fireMenuDeselected(JNIEnv *env, jobject callingObj, + jobject menuEvent, jobject source); + void fireMenuSelected(JNIEnv *env, jobject callingObj, + jobject menuEvent, jobject source); + void firePopupMenuCanceled(JNIEnv *env, jobject callingObj, + jobject popupMenuEvent, jobject source); + void firePopupMenuWillBecomeInvisible(JNIEnv *env, jobject callingObj, + jobject popupMenuEvent, jobject source); + void firePopupMenuWillBecomeVisible(JNIEnv *env, jobject callingObj, + jobject popupMenuEvent, jobject source); + + void firePropertyCaretChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jint oldValue, jint newValue); + void firePropertyDescriptionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue); + void firePropertyNameChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue); + void firePropertySelectionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source); + void firePropertyStateChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue); + void firePropertyTextChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source); + void firePropertyValueChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue); + void firePropertyVisibleDataChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source); + void firePropertyChildChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, jobject newValue); + void firePropertyActiveDescendentChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, jobject newValue); + + void firePropertyTableModelChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue); +}; + + +#endif --- /dev/null 2015-03-30 10:56:11.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/WinAccessBridge.DEF 2015-03-30 10:56:10.916908800 -0500 @@ -0,0 +1,134 @@ +; +; Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. +; ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. +; +; +;LIBRARY WINDOWSACCESSBRIDGE + +;DESCRIPTION 'WINDOWSACCESSBRIDGE.DLL' +HEAPSIZE 4096 +EXPORTS + + addJavaEventNotification + removeJavaEventNotification + addAccessibilityEventNotification + removeAccessibilityEventNotification + + Windows_run + + getAccessibleTableInfo + getAccessibleTableCellInfo + + getAccessibleTableRowHeader + getAccessibleTableColumnHeader + + getAccessibleTableRowDescription + getAccessibleTableColumnDescription + + isAccessibleTableRowSelected + isAccessibleTableColumnSelected + + getAccessibleTableColumnSelectionCount + getAccessibleTableRowSelectionCount + + getAccessibleTableColumnSelections + getAccessibleTableRowSelections + + getAccessibleTableRow + getAccessibleTableColumn + getAccessibleTableIndex + + getAccessibleRelationSet + + getAccessibleHypertext + activateAccessibleHyperlink + getAccessibleHyperlinkCount + getAccessibleHypertextExt + getAccessibleHypertextLinkIndex + getAccessibleHyperlink + + getAccessibleKeyBindings + getAccessibleIcons + getAccessibleActions + doAccessibleActions + + setTextContents + getParentWithRole + getParentWithRoleElseRoot + getTopLevelObject + getObjectDepth + getActiveDescendent + + getVirtualAccessibleName + requestFocus + selectTextRange + getTextAttributesInRange + getVisibleChildrenCount + getVisibleChildren + setCaretPosition + getCaretLocation + + getEventsWaiting + + releaseJavaObject + getVersionInfo + + isJavaWindow + isSameObject + getAccessibleContextFromHWND + getHWNDFromAccessibleContext + + getAccessibleContextAt + getAccessibleContextWithFocus + getAccessibleContextInfo + getAccessibleChildFromContext + getAccessibleParentFromContext + + getAccessibleTextInfo + getAccessibleTextItems + getAccessibleTextSelectionInfo + getAccessibleTextAttributes + getAccessibleTextRect + getAccessibleTextLineBounds + getAccessibleTextRange + + getCurrentAccessibleValueFromContext + getMaximumAccessibleValueFromContext + getMinimumAccessibleValueFromContext + + addAccessibleSelectionFromContext + clearAccessibleSelectionFromContext + getAccessibleSelectionFromContext + getAccessibleSelectionCountFromContext + isAccessibleChildSelectedFromContext + removeAccessibleSelectionFromContext + selectAllAccessibleSelectionFromContext + + setPropertyChangeFP + setJavaShutdownFP + setFocusGainedFP + setFocusLostFP + setCaretUpdateFP + setMouseClickedFP + setMouseEnteredFP + setMouseExitedFP + setMousePressedFP + setMouseReleasedFP + setMenuCanceledFP + setMenuDeselectedFP + setMenuSelectedFP + setPopupMenuCanceledFP + setPopupMenuWillBecomeInvisibleFP + setPopupMenuWillBecomeVisibleFP + + setPropertyNameChangeFP + setPropertyDescriptionChangeFP + setPropertyStateChangeFP + setPropertyValueChangeFP + setPropertySelectionChangeFP + setPropertyTextChangeFP + setPropertyCaretChangeFP + setPropertyVisibleDataChangeFP + setPropertyChildChangeFP + setPropertyActiveDescendentChangeFP + setPropertyTableModelChangeFP --- /dev/null 2015-03-30 10:56:14.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/WinAccessBridge.cpp 2015-03-30 10:56:14.005916900 -0500 @@ -0,0 +1,3503 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A DLL which is loaded by Windows executables to handle communication + * between Java VMs purposes of Accessbility. + */ + +#include "AccessBridgeDebug.h" +#include "WinAccessBridge.h" +#include "accessBridgeResource.h" +#include "accessBridgeCallbacks.h" +#include "AccessBridgeMessages.h" +#include "AccessBridgeMessageQueue.h" + +#include +#include +#include + +// send memory lock +// +// This lock is need to serialize access to the buffer used by sendMemoryPackage. +// If a JVM goes away while the associated memory buffer is in use, a thread switch +// allows a call to JavaVMDestroyed and deallocation of the memory buffer. +CRITICAL_SECTION sendMemoryIPCLock; + +// registry paths to newly found JVMs that don't have the bridge installed +char **newJVMs; + +WinAccessBridge *theWindowsAccessBridge; +HWND theDialogWindow; + +// unique broadcast msg. IDs gotten dymanically +extern UINT theFromJavaHelloMsgID; +extern UINT theFromWindowsHelloMsgID; + +// protects the javaVMs chain while in use +bool isVMInstanceChainInUse; + +/* =================================================================================== */ + + + +/** + * Proc for "New JVM Found" dialog + */ +BOOL CALLBACK newJVMFoundDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { + + switch (message) { + case WM_COMMAND: + // PrintDebugString(" newJVMDialogProc: LOWORD(wParam) = %d", LOWORD(wParam)); + + switch (LOWORD(wParam)) { + + // Remind user later that a new JVM was installed + case cRemindThereIsNewJVM: + PrintDebugString(" newJVMDialogProc: cRemindThereIsNewJVM"); + // do nothing + EndDialog(hwndDlg, wParam); + return TRUE; + + // Do not remind user later that a new JVM was installed + /* + case cDoNotRemindThereIsNewJVM: + PrintDebugString(" newJVMDialogProc: cDoNotRemindThereIsNewJVM"); + // remember to not remind the user there are new JVMs + PrintDebugString("theWindowsAccessBridge = %x", theWindowsAccessBridge); + if (theWindowsAccessBridge != NULL) { + dontRemindUser(newJVMs); + } + EndDialog(hwndDlg, wParam); + return TRUE; + */ + + // Run the AccessBridge installer + /* + case cInstallAccessBridge: + PrintDebugString(" newJVMDialogProc: cInstallAccessBridge"); + // start the installer + if (theWindowsAccessBridge != NULL) { + startInstaller(newJVMs); + } + EndDialog(hwndDlg, wParam); + return TRUE; + */ + + default: + ; + } + default: + ; + } + return FALSE; +} + + + +/* =========================================================================== */ + +// --------------------------------------------------------------------------- + +extern "C" { + /** + * DllMain - where Windows executables will load/unload us + * + */ + BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) { + + switch (fdwReason) { + case DLL_PROCESS_ATTACH: // A Windows executable loaded us + PrintDebugString("DLL_PROCESS_ATTACH"); + theWindowsAccessBridge = new WinAccessBridge(hinstDll); + break; + + case DLL_PROCESS_DETACH: // A Windows executable unloaded us + if (theWindowsAccessBridge != (WinAccessBridge *) 0) { + PrintDebugString("*** AccessBridgeDialogProc -> deleting theWindowsAccessBridge"); + delete theWindowsAccessBridge; + } + break; + } + + return(TRUE); + } + + /** + * Append debug info to dialog + * + * replaced with code to send output to debug file + * + */ + void AppendToCallInfo(char *s) { + + /* + _CrtDbgReport(_CRT_WARN, (const char *) NULL, NULL, (const char *) NULL, + (const char *) "WinAccessBridge: %s", s); + */ + + char buf[1024]; + sprintf(buf, "WinAccessBridge: %s", s); + OutputDebugString(buf); + } + + /** + * Our window proc + * + */ + BOOL CALLBACK AccessBridgeDialogProc(HWND hDlg, UINT message, UINT wParam, LONG lParam) { + COPYDATASTRUCT *sentToUs; + char *package; + + switch (message) { + case WM_INITDIALOG: + PrintDebugString("AccessBridgeDialogProc -> Initializing"); + break; + + // call from Java with data for us to deliver + case WM_COPYDATA: + if (theDialogWindow == (HWND) wParam) { + PrintDebugString("AccessBridgeDialogProc -> Got WM_COPYDATA from Java Bridge DLL"); + } else { + PrintDebugString("AccessBridgeDialogProc -> Got WM_COPYDATA from HWND %p", wParam); + sentToUs = (COPYDATASTRUCT *) lParam; + package = (char *) sentToUs->lpData; + theWindowsAccessBridge->preProcessPackage(package, sentToUs->cbData); + } + break; + + // message to ourselves -> de-queue messages and send 'em + case AB_MESSAGE_QUEUED: + PrintDebugString("AccessBridgeDialogProc -> Got AB_MESSAGE_QUEUED from ourselves"); + theWindowsAccessBridge->receiveAQueuedPackage(); + break; + + // a JavaAccessBridge DLL is going away + // + // When JavaVMDestroyed is called a AccessBridgeJavaVMInstance in the + // javaVMs chain will be removed. If that chain is in use this will + // cause a crash. One way AB_DLL_GOING_AWAY can arrive is on any + // outgoing SendMessage call. SendMessage normally spins waiting for + // a response. However, if there is an incoming SendMessage, e.g. for + // AB_DLL_GOING_AWAY Windows will send that request to this DialogProc. + // One seemingly easy way to combat that is to use SendMessageTimeout + // with the SMTO_BLOCK flag set. However, it has been the case that + // even after using that technique AB_DLL_GOING_AWAY can still arrive + // in the middle of processing the javaVMs chain. An alternative that + // was tried was to use a critical section around any access ot the + // javaVMs chain but unfortunately the AB_DLL_GOING_AWAY message arrives + // on the same thread and thus the use of a critical section is ineffective. + // The solution then is to set a flag whenever the javaVMs chain is being + // used and if that flag is set at this point the message will be posted + // to the message queue. That would delay the destruction of the instance + // until the chain is not being traversed. + case AB_DLL_GOING_AWAY: + PrintDebugString("***** AccessBridgeDialogProc -> Got AB_DLL_GOING_AWAY message"); + if (isVMInstanceChainInUse) { + PrintDebugString(" javaVMs chain in use, calling PostMessage"); + PostMessage(hDlg, AB_DLL_GOING_AWAY, wParam, (LPARAM)0); + } else { + PrintDebugString(" calling javaVMDestroyed"); + theWindowsAccessBridge->JavaVMDestroyed((HWND) wParam); + } + break; + + default: + // the JavaVM is saying "hi"! + // wParam == sourceHwnd; lParam == JavaVMID + if (message == theFromJavaHelloMsgID) { + PrintDebugString("AccessBridgeDialogProc -> Got theFromJavaHelloMsgID; wParam = %p, lParam = %p", wParam, lParam); + theWindowsAccessBridge->rendezvousWithNewJavaDLL((HWND) wParam, (long ) lParam); + } + break; + } + + return (FALSE); + } + +} + + + + +// --------------------------------------------------------------------------- + +/** + * Initialize the WinAccessBridge + * + */ +WinAccessBridge::WinAccessBridge(HINSTANCE hInstance) { + + PrintDebugString("WinAccessBridge ctor"); + + // IntializeCriticalSection should only be called once. + InitializeCriticalSection(&sendMemoryIPCLock); + windowsInstance = hInstance; + javaVMs = (AccessBridgeJavaVMInstance *) 0; + eventHandler = new AccessBridgeEventHandler(); + messageQueue = new AccessBridgeMessageQueue(); + initBroadcastMessageIDs(); // get the unique to us broadcast msg. IDs + theWindowsAccessBridge = this; + isVMInstanceChainInUse = false; + + + // notify the user if new JVMs are found + /* + newJVMs = (char **)malloc(MAX_NEW_JVMS_FOUND); + for (int i = 0; i < MAX_NEW_JVMS_FOUND; i++) { + newJVMs[i] = (char *)malloc(SHORT_STRING_SIZE); + newJVMs[i][0] = 0; + } + + BOOL newJ2SEFound = findNewJVMs(J2SE_REG_PATH, newJVMs); + BOOL newJ2REFound = TRUE; // findNewJVMs(J2RE_REG_PATH, newJVMs); + + if (newJ2SEFound || newJ2REFound) { + + int result = DialogBox(windowsInstance, + "FOUNDNEWJVMDIALOG", + NULL, + (DLGPROC)newJVMFoundDialogProc); + if (result < 0) { + printError("DialogBox failed"); + } + + PrintDebugString(" FOUNDNEWJVMDIALOG: result = %d", result); + + ShowWindow((HWND)result, SW_SHOW); + } + */ + + ShowWindow(theDialogWindow, SW_SHOW); +} + + + +/** + * Destroy the WinAccessBridge + * + */ +WinAccessBridge::~WinAccessBridge() { + // inform all other AccessBridges that we're going away + // -> shut down all event listening + // -> release all objects held in the JVM by us + + PrintDebugString("*****in WinAccessBridge::~WinAccessBridge()"); + + // send a broadcast msg.; let other AccessBridge DLLs know we're going away + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + PrintDebugString(" telling %p we're going away", current->javaAccessBridgeWindow); + SendMessage(current->javaAccessBridgeWindow, + AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0); + current = current->nextJVMInstance; + } + + PrintDebugString(" finished telling JVMs about our demise"); + + delete eventHandler; + delete messageQueue; + delete javaVMs; + + PrintDebugString(" finished deleting eventHandler, messageQueue, and javaVMs"); + PrintDebugString("GOODBYE CRUEL WORLD..."); + + DestroyWindow(theDialogWindow); +} + + +/** + * Bring up our window; make a connection to the rest of the world + * + */ +BOOL +WinAccessBridge::initWindow() { + theDialogWindow = CreateDialog(windowsInstance, + "ACCESSBRIDGESTATUSWINDOW", NULL, + (DLGPROC) AccessBridgeDialogProc); + + // If window could not be created, return "failure". + if (!theDialogWindow) + return (FALSE); + + dialogWindow = theDialogWindow; + + // Make the window visible, update its client area, & return "success". + // DEBUG_CODE(ShowWindow (theDialogWindow, SW_SHOWNORMAL)); + // DEBUG_CODE(UpdateWindow (theDialogWindow)); + + // post a broadcast msg.; let other AccessBridge DLLs know we exist + PostMessage(HWND_BROADCAST, theFromWindowsHelloMsgID, (WPARAM) dialogWindow, (LPARAM) 0); + + return (TRUE); +} + +// ----------------------- + +/** + * rendezvousWithNewJavaDLL + * - Build AccessBridgeJavaVMInstance data structure + * (including setting up Memory-Mapped file info) + * + */ +LRESULT +WinAccessBridge::rendezvousWithNewJavaDLL(HWND JavaBridgeDLLwindow, long vmID) { + LRESULT returnVal; + + PrintDebugString("in JavaAccessBridge::rendezvousWithNewJavaDLL(%p, %X)", + JavaBridgeDLLwindow, vmID); + + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *newVM = + new AccessBridgeJavaVMInstance(dialogWindow, JavaBridgeDLLwindow, vmID, javaVMs); + javaVMs = newVM; + isVMInstanceChainInUse = false; + + returnVal = javaVMs->initiateIPC(); + if (returnVal == 0) { + + // tell the newly created JavaVM what events we're interested in, if any + long javaEventMask = eventHandler->getJavaEventMask(); + long accessibilityEventMask = eventHandler->getAccessibilityEventMask(); + + PrintDebugString(" Setting Java event mask to: %X", javaEventMask); + + if (javaEventMask != 0) { + addJavaEventNotification(javaEventMask); + } + + PrintDebugString(" Setting Accessibility event mask to: %X", accessibilityEventMask); + + if (accessibilityEventMask != 0) { + addAccessibilityEventNotification(accessibilityEventMask); + } + } else { + PrintDebugString(" ERROR: Failed to initiate IPC with newly created JavaVM!!!"); + return FALSE; + } + + PrintDebugString(" Success!! We rendezvoused with the JavaDLL"); + return returnVal; +} + +// ----------------------- + +/** + * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging + * with the Java AccessBridge DLL + * + * NOTE: WM_COPYDATA is only for one-way IPC; there + * is now way to return parameters (especially big ones) + * Use sendMemoryPackage() to do that! + */ +void +WinAccessBridge::sendPackage(char *buffer, long bufsize, HWND destWindow) { + COPYDATASTRUCT toCopy; + toCopy.dwData = 0; // 32-bits we could use for something... + toCopy.cbData = bufsize; + toCopy.lpData = buffer; + + SendMessage(destWindow, WM_COPYDATA, (WPARAM) dialogWindow, (LPARAM) &toCopy); +} + + +/** + * sendMemoryPackage - uses Memory-Mapped files to do IPC messaging + * with the Java AccessBridge DLL, informing the + * Java AccessBridge DLL via SendMessage that something + * is waiting for it in the shared file... + * + * In the SendMessage call, the third param (WPARAM) is + * the source HWND (theDialogWindow in this case), and + * the fourth param (LPARAM) is the size in bytes of + * the package put into shared memory. + * + */ +BOOL +WinAccessBridge::sendMemoryPackage(char *buffer, long bufsize, HWND destWindow) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + AccessBridgeJavaVMInstance *ourABJavaVMInstance; + ourABJavaVMInstance = javaVMs->findABJavaVMInstanceFromJavaHWND(destWindow); + if (ourABJavaVMInstance != (AccessBridgeJavaVMInstance *) 0) { + if (!ourABJavaVMInstance->sendMemoryPackage(buffer, bufsize)) { + // return falue to the caller + memset(buffer, 0, bufsize); + return FALSE; + } + } else { + PrintDebugString("ERROR sending memory package: couldn't find destWindow"); + return FALSE; + } + return TRUE; +} + + +/** + * queuePackage - put a package onto the queue for latter processing + * + */ +BOOL +WinAccessBridge::queuePackage(char *buffer, long bufsize) { + PrintDebugString(" in WinAccessBridge::queuePackage(%p, %d)", buffer, bufsize); + + AccessBridgeQueueElement *element = new AccessBridgeQueueElement(buffer, bufsize); + + messageQueue->add(element); + PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); + return TRUE; +} + + +/** + * receiveAQueuedPackage - remove a pending packge from the queue and + * handle it. If the queue is busy, post a + * message to self to retrieve it later + * + */ +BOOL +WinAccessBridge::receiveAQueuedPackage() { + AccessBridgeQueueElement *element; + + PrintDebugString("in WinAccessBridge::receiveAQueuedPackage()"); + + // ensure against re-entrancy problems... + if (messageQueue->getRemoveLockSetting() == FALSE) { + messageQueue->setRemoveLock(TRUE); + + PrintDebugString(" dequeueing message"); + + QueueReturns result = messageQueue->remove(&element); + + PrintDebugString(" 'element->buffer' contains:"); + DEBUG_CODE(PackageType *type = (PackageType *) element->buffer); + DEBUG_CODE(FocusGainedPackageTag *pkg = (FocusGainedPackageTag *) (((char *) element->buffer) + sizeof(PackageType))); + DEBUG_CODE(PrintDebugString(" PackageType = %X", *type)); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + DEBUG_CODE(PrintDebugString(" EventPackage: vmID = %X, event = %p, source = %p", pkg->vmID, pkg->Event, pkg->AccessibleContextSource)); +#else // JOBJECT64 is jlong (64 bit) + DEBUG_CODE(PrintDebugString(" EventPackage: vmID = %X, event = %016I64X, source = %016I64X", pkg->vmID, pkg->Event, pkg->AccessibleContextSource)); +#endif + switch (result) { + + case cQueueBroken: + PrintDebugString(" ERROR!!! Queue seems to be broken!"); + messageQueue->setRemoveLock(FALSE); + return FALSE; + + case cMoreMessages: + case cQueueEmpty: + if (element != (AccessBridgeQueueElement *) 0) { + PrintDebugString(" found one; sending it!"); + processPackage(element->buffer, element->bufsize); + delete element; + } else { + PrintDebugString(" ODD... element == 0!"); + return FALSE; + } + break; + + case cQueueInUse: + PrintDebugString(" Queue in use, will try again later..."); + PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); + break; + + default: + messageQueue->setRemoveLock(FALSE); + return FALSE; // should never get something we don't recognize! + } + } else { + PrintDebugString(" unable to dequeue message; remove lock is set"); + PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); // Fix for 6995891 + } + + messageQueue->setRemoveLock(FALSE); + return TRUE; +} + +// ----------------------- + +/** + * preProcessPackage + * - do triage on incoming packages; queue some, deal with others + * + */ +void +WinAccessBridge::preProcessPackage(char *buffer, long bufsize) { + PrintDebugString("PreProcessing package sent from Java:"); + + PackageType *type = (PackageType *) buffer; + + switch (*type) { + + PrintDebugString(" type == %X", *type); + + // event packages all get queued for later handling + //case cPropertyChangePackage: + case cJavaShutdownPackage: + case cFocusGainedPackage: + case cFocusLostPackage: + case cCaretUpdatePackage: + case cMouseClickedPackage: + case cMouseEnteredPackage: + case cMouseExitedPackage: + case cMousePressedPackage: + case cMouseReleasedPackage: + case cMenuCanceledPackage: + case cMenuDeselectedPackage: + case cMenuSelectedPackage: + case cPopupMenuCanceledPackage: + case cPopupMenuWillBecomeInvisiblePackage: + case cPopupMenuWillBecomeVisiblePackage: + + case cPropertyCaretChangePackage: + case cPropertyDescriptionChangePackage: + case cPropertyNameChangePackage: + case cPropertySelectionChangePackage: + case cPropertyStateChangePackage: + case cPropertyTextChangePackage: + case cPropertyValueChangePackage: + case cPropertyVisibleDataChangePackage: + case cPropertyChildChangePackage: + case cPropertyActiveDescendentChangePackage: + + case cPropertyTableModelChangePackage: + + queuePackage(buffer, bufsize); + break; + + // perhaps there will be some other packages to process at some point... // + + default: + PrintDebugString(" processing FAILED!! -> don't know how to handle type = %X", *type); + break; + } + + PrintDebugString(" package preprocessing completed"); +} + + +#define DISPATCH_EVENT_PACKAGE(packageID, eventPackage, fireEventMethod) \ + case packageID: \ + if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) { \ + eventPackage *pkg = \ + (eventPackage *) (buffer + sizeof(PackageType)); \ + PrintDebugString(" begin callback to AT, type == %X", *type); \ + theWindowsAccessBridge->eventHandler->fireEventMethod( \ + pkg->vmID, pkg->Event, pkg->AccessibleContextSource); \ + PrintDebugString(" event callback complete!"); \ + } else { \ + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", \ + bufsize, sizeof(PackageType) + sizeof(eventPackage)); \ + } \ + break; + +#define DISPATCH_PROPERTY_CHANGE_PACKAGE(packageID, eventPackage, fireEventMethod, oldValue, newValue) \ + case packageID: \ + if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) { \ + eventPackage *pkg = \ + (eventPackage *) (buffer + sizeof(PackageType)); \ + PrintDebugString(" begin callback to AT, type == %X", *type); \ + theWindowsAccessBridge->eventHandler->fireEventMethod( \ + pkg->vmID, pkg->Event, pkg->AccessibleContextSource, \ + pkg->oldValue, pkg->newValue); \ + PrintDebugString(" event callback complete!"); \ + } else { \ + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", \ + bufsize, sizeof(PackageType) + sizeof(eventPackage)); \ + } \ + break; + +#define DISPATCH_PROPERTY_TABLE_MODEL_CHANGE_PACKAGE(packageID, eventPackage, fireEventMethod, oldValue, newValue) \ + case packageID: \ + if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) { \ + eventPackage *pkg = \ + (eventPackage *) (buffer + sizeof(PackageType)); \ + PrintDebugString(" begin callback to AT, type == %X", *type); \ + theWindowsAccessBridge->eventHandler->fireEventMethod( \ + pkg->vmID, pkg->Event, pkg->AccessibleContextSource, \ + pkg->oldValue, pkg->newValue); \ + PrintDebugString(" event callback complete!"); \ + } else { \ + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", \ + bufsize, sizeof(PackageType) + sizeof(eventPackage)); \ + } \ + break; + +/** + * processPackage - processes the output of SendMessage(WM_COPYDATA) + * to do IPC messaging with the Java AccessBridge DLL + * + */ +void +WinAccessBridge::processPackage(char *buffer, long bufsize) { + PrintDebugString("WinAccessBridge::Processing package sent from Java:"); + + PackageType *type = (PackageType *) buffer; + + switch (*type) { + + PrintDebugString(" type == %X", *type); + + case cJavaShutdownPackage: + PrintDebugString(" type == cJavaShutdownPackage"); + if (bufsize == sizeof(PackageType) + sizeof(JavaShutdownPackage)) { + JavaShutdownPackage *pkg = + (JavaShutdownPackage *) (buffer + sizeof(PackageType)); + theWindowsAccessBridge->eventHandler->fireJavaShutdown(pkg->vmID); + PrintDebugString(" event callback complete!"); + PrintDebugString(" event fired!"); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(JavaShutdownPackage)); + } + break; + + + DISPATCH_EVENT_PACKAGE(cFocusGainedPackage, FocusGainedPackage, fireFocusGained); + DISPATCH_EVENT_PACKAGE(cFocusLostPackage, FocusLostPackage, fireFocusLost); + + DISPATCH_EVENT_PACKAGE(cCaretUpdatePackage, CaretUpdatePackage, fireCaretUpdate); + + DISPATCH_EVENT_PACKAGE(cMouseClickedPackage, MouseClickedPackage, fireMouseClicked); + DISPATCH_EVENT_PACKAGE(cMouseEnteredPackage, MouseEnteredPackage, fireMouseEntered); + DISPATCH_EVENT_PACKAGE(cMouseExitedPackage, MouseExitedPackage, fireMouseExited); + DISPATCH_EVENT_PACKAGE(cMousePressedPackage, MousePressedPackage, fireMousePressed); + DISPATCH_EVENT_PACKAGE(cMouseReleasedPackage, MouseReleasedPackage, fireMouseReleased); + + DISPATCH_EVENT_PACKAGE(cMenuCanceledPackage, MenuCanceledPackage, fireMenuCanceled); + DISPATCH_EVENT_PACKAGE(cMenuDeselectedPackage, MenuDeselectedPackage, fireMenuDeselected); + DISPATCH_EVENT_PACKAGE(cMenuSelectedPackage, MenuSelectedPackage, fireMenuSelected); + DISPATCH_EVENT_PACKAGE(cPopupMenuCanceledPackage, PopupMenuCanceledPackage, firePopupMenuCanceled); + DISPATCH_EVENT_PACKAGE(cPopupMenuWillBecomeInvisiblePackage, PopupMenuWillBecomeInvisiblePackage, firePopupMenuWillBecomeInvisible); + DISPATCH_EVENT_PACKAGE(cPopupMenuWillBecomeVisiblePackage, PopupMenuWillBecomeVisiblePackage, firePopupMenuWillBecomeVisible); + + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyNameChangePackage, + PropertyNameChangePackage, + firePropertyNameChange, oldName, newName) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyDescriptionChangePackage, + PropertyDescriptionChangePackage, + firePropertyDescriptionChange, + oldDescription, newDescription) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyStateChangePackage, + PropertyStateChangePackage, + firePropertyStateChange, oldState, newState) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyValueChangePackage, + PropertyValueChangePackage, + firePropertyValueChange, oldValue, newValue) + DISPATCH_EVENT_PACKAGE(cPropertySelectionChangePackage, + PropertySelectionChangePackage, firePropertySelectionChange) + DISPATCH_EVENT_PACKAGE(cPropertyTextChangePackage, + PropertyTextChangePackage, firePropertyTextChange) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyCaretChangePackage, + PropertyCaretChangePackage, + firePropertyCaretChange, oldPosition, newPosition) + DISPATCH_EVENT_PACKAGE(cPropertyVisibleDataChangePackage, + PropertyVisibleDataChangePackage, firePropertyVisibleDataChange) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyChildChangePackage, + PropertyChildChangePackage, + firePropertyChildChange, + oldChildAccessibleContext, + newChildAccessibleContext) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyActiveDescendentChangePackage, + PropertyActiveDescendentChangePackage, + firePropertyActiveDescendentChange, + oldActiveDescendentAccessibleContext, + newActiveDescendentAccessibleContext) + + DISPATCH_PROPERTY_TABLE_MODEL_CHANGE_PACKAGE(cPropertyTableModelChangePackage, + PropertyTableModelChangePackage, + firePropertyTableModelChange, + oldValue, newValue) + + + default: + PrintDebugString(" processing FAILED!! -> don't know how to handle type = %X", *type); + break; + } + + PrintDebugString(" package processing completed"); +} + + +// ----------------------------- + +void +WinAccessBridge::JavaVMDestroyed(HWND VMBridgeDLLWindow) { + PrintDebugString("***** WinAccessBridge::JavaVMDestroyed(%p)", VMBridgeDLLWindow); + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *currentVM = javaVMs; + AccessBridgeJavaVMInstance *previousVM = javaVMs; + if (javaVMs->javaAccessBridgeWindow == VMBridgeDLLWindow) { + javaVMs = javaVMs->nextJVMInstance; + delete currentVM; + + PrintDebugString(" data structures successfully removed"); + + // [[[FIXME]]] inform Windows AT that a JVM went away, + // and that any jobjects it's got lying around for that JVM + // are now invalid + + } else { + while (currentVM != (AccessBridgeJavaVMInstance *) 0) { + if (currentVM->javaAccessBridgeWindow == VMBridgeDLLWindow) { + previousVM->nextJVMInstance = currentVM->nextJVMInstance; + delete currentVM; + + PrintDebugString(" data structures successfully removed"); + + // [[[FIXME]]] inform Windows AT that a JVM went away, + // and that any jobjects it's got lying around for that JVM + // are now invalid + isVMInstanceChainInUse = false; + return; + } else { + previousVM = currentVM; + currentVM = currentVM->nextJVMInstance; + } + } + PrintDebugString(" ERROR!! couldn't find matching data structures!"); + } + isVMInstanceChainInUse = false; +} + +// ----------------------- + +/** + * releaseJavaObject - lets the JavaVM know it can release the Java Object + * + * Note: once you have made this call, the JavaVM will garbage collect + * the jobject you pass in. If you later use that jobject in another + * call, you will cause all maner of havoc! + * + */ +void +WinAccessBridge::releaseJavaObject(long vmID, JOBJECT64 object) { +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::releaseJavaObject(%X, %p)", vmID, object); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::releaseJavaObject(%X, %016I64X)", vmID, object); +#endif + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage)]; + PackageType *type = (PackageType *) buffer; + ReleaseJavaObjectPackage *pkg = (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType)); + *type = cReleaseJavaObjectPackage; + pkg->vmID = vmID; + pkg->object = object; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + sendPackage(buffer, sizeof(buffer), destABWindow); // no return values! + } +} + +// ----------------------- + +/** + * getVersionInfo - fill the AccessBridgeVersionInfo struct + * + */ +BOOL +WinAccessBridge::getVersionInfo(long vmID, AccessBridgeVersionInfo *info) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessBridgeVersionPackage *pkg = (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessBridgeVersionPackage; + pkg->vmID = vmID; + + PrintDebugString("WinAccessBridge::getVersionInfo(%X, )", vmID); + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(info, &(pkg->rVersionInfo), sizeof(AccessBridgeVersionInfo)); + PrintDebugString(" VMversion: %ls", info->VMversion); + PrintDebugString(" bridgeJavaClassVersion: %ls", info->bridgeJavaClassVersion); + PrintDebugString(" bridgeJavaDLLVersion: %ls", info->bridgeJavaDLLVersion); + PrintDebugString(" bridgeWinDLLVersion: %ls", info->bridgeWinDLLVersion); + return TRUE; + } + } + return FALSE; +} + + +/********** Window-related routines ***********************************/ + +/** + * isJavaWindow - returns TRUE if the HWND is a top-level Java Window + * + * Note: just because the Windnow is a top-level Java window, that doesn't + * mean that it is accessible. Call getAccessibleContextFromHWND(HWND) to get the + * AccessibleContext, if any, for an HWND that is a Java Window. + * + */ +BOOL +WinAccessBridge::isJavaWindow(HWND window) { + HWND hwnd; + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + // quick check to see if 'window' is top-level; if not, it's not interesting... + // [[[FIXME]]] is this for sure an OK optimization? + hwnd = getTopLevelHWND(window); + if (hwnd == (HWND) NULL) { + return FALSE; + } + + PrintDebugString(" in WinAccessBridge::isJavaWindow"); + + + + char buffer[sizeof(PackageType) + sizeof(IsJavaWindowPackage)]; + PackageType *type = (PackageType *) buffer; + IsJavaWindowPackage *pkg = (IsJavaWindowPackage *) (buffer + sizeof(PackageType)); + *type = cIsJavaWindowPackage; + pkg->window = (jint) window; + + PrintDebugString("WinAccessBridge::isJavaWindow(%p)", window); + + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), current->javaAccessBridgeWindow) == TRUE) { + if (pkg->rResult != 0) { + isVMInstanceChainInUse = false; + return TRUE; + } + } + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; + return FALSE; + + + /* + char classname[256]; + HWND hwnd; + + hwnd = getTopLevelHWND(window); + if (hwnd == (HWND) NULL) { + return FALSE; + } + GetClassName(hwnd, classname, 256); + + if (strstr(classname, "AwtFrame") != 0) { + return TRUE; + } else if (strstr(classname, "AwtWindow") != 0) { + return TRUE; + } else if (strstr(classname, "AwtDialog") != 0) { + return TRUE; + } + */ + // JDK 1.4 introduces new (and changes old) classnames + /* + else if (strstr(classname, "SunAwtToolkit") != 0) { + return TRUE; + } else if (strstr(classname, "javax.swing.JFrame") != 0) { + return TRUE; + } + */ + + return FALSE; +} + +/** + * isSameObject - returns TRUE if the two object references refer to + * the same object. Otherwise, this method returns FALSE: + */ +BOOL +WinAccessBridge::isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::isSameObject(%p %p)", obj1, obj2); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::isSameObject(%016I64X %016I64X)", obj1, obj2); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(IsSameObjectPackage)]; + PackageType *type = (PackageType *) buffer; + IsSameObjectPackage *pkg = (IsSameObjectPackage *) (buffer + sizeof(PackageType)); + *type = cIsSameObjectPackage; + pkg->vmID = vmID; + pkg->obj1 = obj1; + pkg->obj2 = obj2; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID); + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + if (pkg->rResult != 0) { + PrintDebugString(" WinAccessBridge::isSameObject returning TRUE (same object)"); + return TRUE; + } else { + PrintDebugString(" WinAccessBridge::isSameObject returning FALSE (different object)"); + return FALSE; + } + } + PrintDebugString(" WinAccessBridge::isSameObject returning FALSE (sendMemoryPackage failed)"); + return FALSE; +} + +/** + * FromHWND - returns the AccessibleContext jobject for the HWND + * + * Note: this routine can return null, even if the HWND is a Java Window, + * because the Java Window may not be accessible. + * + */ +BOOL +WinAccessBridge::getAccessibleContextFromHWND(HWND window, long *vmID, JOBJECT64 *AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleContextFromHWNDPackage *pkg = (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleContextFromHWNDPackage; + pkg->window = (jint) window; + + PrintDebugString("WinAccessBridge::getAccessibleContextFromHWND(%p, )", window); + + DEBUG_CODE(pkg->rVMID = (long ) 0x01010101); + DEBUG_CODE(pkg->rAccessibleContext = (JOBJECT64) 0x01010101); + + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + + if (sendMemoryPackage(buffer, sizeof(buffer), current->javaAccessBridgeWindow) == TRUE) { + if (pkg->rAccessibleContext != 0) { + *vmID = pkg->rVMID; + *AccessibleContext = (JOBJECT64)pkg->rAccessibleContext; + PrintDebugString(" current->vmID = %X", current->vmID); + PrintDebugString(" pkg->rVMID = %X", pkg->rVMID); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" pkg->rAccessibleContext = %p", pkg->rAccessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" pkg->rAccessibleContext = %016I64X", pkg->rAccessibleContext); +#endif + if (pkg->rVMID != current->vmID) { + PrintDebugString(" ERROR! getAccessibleContextFromHWND vmIDs don't match!"); + isVMInstanceChainInUse = false; + return FALSE; + } + isVMInstanceChainInUse = false; + return TRUE; + } + } + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; + + // This isn't really an error; it just means that the HWND was for a non-Java + // window. It's also possible the HWND was for a Java window but the JVM has + // since been shut down and sendMemoryPackage returned FALSE. + PrintDebugString(" ERROR! getAccessibleContextFromHWND no matching HWND found!"); + return FALSE; +} + +/** + * Returns the HWND for an AccessibleContext. Returns (HWND)0 on error. + */ +HWND +WinAccessBridge::getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext) { + PrintDebugString(" in WinAccessBridge::getHWNDFromAccessibleContext"); + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (HWND)0; + } + + char buffer[sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetHWNDFromAccessibleContextPackage *pkg = (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetHWNDFromAccessibleContextPackage; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getHWNDFromAccessibleContext(%p)", accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getHWNDFromAccessibleContext(%016I64X)", accessibleContext); +#endif + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return ((HWND)ABLongToHandle(pkg->rHWND)); + } + } + return (HWND)0; +} + +/********** AccessibleContext routines ***********************************/ + +/** + * Walk through Java Windows, in front-to-back Z-order. + * If NULL is passed it, this function starts at the top. + * + */ +HWND +WinAccessBridge::getNextJavaWindow(HWND previous) { + HWND current = previous; + if (current == NULL) { + current = GetTopWindow(NULL); + } else { + current = GetNextWindow(current, GW_HWNDNEXT); + } + while (current != NULL) { + if (isJavaWindow(current)) { + return current; + } + current = GetNextWindow(current, GW_HWNDNEXT); + } + return NULL; +} + + +/** + * getAccessibleContextAt - performs the Java code: + * Accessible a = EventQueueMonitor.getAccessibleAt(x, y); + * return a.getAccessibleContext(); + * + * Note: this call explicitly goes through the AccessBridge, + * so that the AccessBridge can hide expected changes in how this functions + * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some + * of this functionality may be built into the platform + * + */ +BOOL +WinAccessBridge::getAccessibleContextAt(long vmID, JOBJECT64 AccessibleContextParent, + jint x, jint y, JOBJECT64 *AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleContextAtPackage *pkg = (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleContextAtPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContextParent; + pkg->x = x; + pkg->y = y; + + PrintDebugString("WinAccessBridge::getAccessibleContextAt(%X, %p, %d, %c)", vmID, AccessibleContextParent, x, y); + HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID); + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + *AccessibleContext = pkg->rAccessibleContext; + return TRUE; + } + + return FALSE; +} + + +/** + * getAccessibleContextWithFocus - performs the Java code: + * Accessible a = Translator.getAccessible(SwingEventMonitor.getComponentWithFocus()); + * return a.getAccessibleContext(); + * + * Note: this call explicitly goes through the AccessBridge, + * so that the AccessBridge can hide expected changes in how this functions + * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some + * of this functionality may be built into the platform + * + */ +BOOL +WinAccessBridge::getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT64 *AccessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleContextWithFocusPackage *pkg = (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleContextWithFocusPackage; + + PrintDebugString("WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID); + // find vmID, etc. from HWND; ask that VM for the AC w/Focus + HWND pkgVMID = (HWND)ABLongToHandle( pkg->rVMID ) ; + if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) { + HWND destABWindow = javaVMs->findAccessBridgeWindow((long)pkgVMID); // ineffecient [[[FIXME]]] + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + *vmID = pkg->rVMID; + *AccessibleContext = pkg->rAccessibleContext; + return TRUE; + } + } + + return FALSE; +} + +/** + * getAccessibleContextInfo - fills a struct with a bunch of information + * contained in the Java Accessibility API + * + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleContextInfo(long vmID, + JOBJECT64 accessibleContext, + AccessibleContextInfo *info) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleContextInfoPackage *pkg = (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleContextInfoPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleContextInfo(%X, %p, )", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleContextInfo(%X, %016I64X, )", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(info, &(pkg->rAccessibleContextInfo), sizeof(AccessibleContextInfo)); + PrintDebugString(" name: %ls", info->name); + PrintDebugString(" description: %ls", info->description); + PrintDebugString(" role: %ls", info->role); + PrintDebugString(" role_en_US: %ls", info->role_en_US); + PrintDebugString(" states: %ls", info->states); + PrintDebugString(" states_en_US: %ls", info->states_en_US); + return TRUE; + } + } + + return FALSE; +} + +/** + * getAccessibleChildFromContext - performs the Java code: + * Accessible child = ac.getAccessibleChild(i); + * return child.getAccessibleContext(); + * + * Note: this call explicitly goes through the AccessBridge, + * so that the AccessBridge can hide expected changes in how this functions + * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some + * of this functionality may be built into the platform + * + */ +JOBJECT64 +WinAccessBridge::getAccessibleChildFromContext(long vmID, + JOBJECT64 AccessibleContext, + jint childIndex) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleChildFromContextPackage *pkg = (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleChildFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->childIndex = childIndex; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleChildFromContext(%X, %p, %d)", vmID, AccessibleContext, childIndex); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleChildFromContext(%X, %016I64X, %d)", vmID, AccessibleContext, childIndex); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + + return (JOBJECT64) 0; +} + +/** + * getAccessibleParentFromContext - returns the parent AccessibleContext jobject + * + * Note: this may be null, if the AccessibleContext passed in is a top-level + * window, then it has no parent. + * + */ +JOBJECT64 +WinAccessBridge::getAccessibleParentFromContext(long vmID, + JOBJECT64 AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleParentFromContextPackage *pkg = (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleParentFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + PrintDebugString("WinAccessBridge::getAccessibleParentFromContext(%X, %p)", vmID, AccessibleContext); + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + + return (JOBJECT64) 0; +} + +/********** AccessibleTable routines ***********************************/ + +BOOL +WinAccessBridge::getAccessibleTableInfo(long vmID, + JOBJECT64 accessibleContext, + AccessibleTableInfo *tableInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableInfo(%X, %p, %p)", vmID, accessibleContext, + tableInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableInfo(%X, %016I64X, %p)", vmID, accessibleContext, + tableInfo); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableInfoPackage *pkg = (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableInfoPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo)); + if (pkg->rTableInfo.rowCount != -1) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableInfo succeeded"); + return TRUE; + } + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableInfo failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleTableCellInfo(long vmID, JOBJECT64 accessibleTable, + jint row, jint column, + AccessibleTableCellInfo *tableCellInfo) { + + PrintDebugString("##### WinAccessBridge::getAccessibleTableCellInfo(%X, %p, %d, %d, %p)", vmID, + accessibleTable, row, column, tableCellInfo); + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableCellInfoPackage *pkg = (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableCellInfoPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->row = row; + pkg->column = column; + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" XXXX pkg->rTableCellInfo.accessibleContext = %p", pkg->rTableCellInfo.accessibleContext); + memcpy(tableCellInfo, &(pkg->rTableCellInfo), sizeof(AccessibleTableCellInfo)); + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableCellInfo succeeded"); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableCellInfo failed"); + return FALSE; +} + + +BOOL +WinAccessBridge::getAccessibleTableRowHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowHeader(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowHeader(%X, %016I64X)", vmID, accessibleContext); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableRowHeaderPackage *pkg = (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableRowHeaderPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowHeader succeeded"); + memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo)); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowHeader failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleTableColumnHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %016I64X)", vmID, accessibleContext); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableColumnHeaderPackage *pkg = (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableColumnHeaderPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnHeader succeeded"); + memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo)); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnHeader failed"); + return FALSE; +} + +JOBJECT64 +WinAccessBridge::getAccessibleTableRowDescription(long vmID, + JOBJECT64 accessibleContext, + jint row) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowDescription(%X, %p, %d)", vmID, accessibleContext, + row); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowDescription(%X, %016I64X, %d)", vmID, accessibleContext, + row); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableRowDescriptionPackage *pkg = (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableRowDescriptionPackage; + pkg->vmID = vmID; + pkg->row = row; + pkg->accessibleContext = accessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowDescription succeeded"); + return pkg->rAccessibleContext; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowDescription failed"); + return (JOBJECT64)0; +} + +JOBJECT64 +WinAccessBridge::getAccessibleTableColumnDescription(long vmID, + JOBJECT64 accessibleContext, + jint column) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %p, %d)", vmID, accessibleContext, + column); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %016I64X, %d)", vmID, accessibleContext, + column); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableColumnDescriptionPackage *pkg = + (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableColumnDescriptionPackage; + pkg->vmID = vmID; + pkg->column = column; + pkg->accessibleContext = accessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnDescription succeeded"); + return pkg->rAccessibleContext; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnDescription failed"); + return (JOBJECT64)0; +} + +jint +WinAccessBridge::getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %p)", vmID, accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %016I64X)", vmID, accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return 0; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableRowSelectionCountPackage *pkg = + (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableRowSelectionCountPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelectionCount succeeded"); + return pkg->rCount; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelectionCount failed"); + return 0; +} + +BOOL +WinAccessBridge::isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::isAccessibleTableRowSelected(%X, %p)", vmID, accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::isAccessibleTableRowSelected(%X, %016I64X)", vmID, accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage)]; + PackageType *type = (PackageType *) buffer; + IsAccessibleTableRowSelectedPackage *pkg = (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType)); + *type = cIsAccessibleTableRowSelectedPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->row = row; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::isAccessibleTableRowSelected succeeded"); + return pkg->rResult; + } + } + PrintDebugString(" ##### WinAccessBridge::isAccessibleTableRowSelected failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, jint *selections) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelections(%X, %p)", vmID, accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelections(%X, %016I64X)", vmID, accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableRowSelectionsPackage *pkg = + (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableRowSelectionsPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->count = count; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelections succeeded"); + memcpy(selections, pkg->rSelections, count * sizeof(jint)); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelections failed"); + return FALSE; +} + + +jint +WinAccessBridge::getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %p)", vmID, + accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %016I64X)", vmID, + accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableColumnSelectionCountPackage *pkg = + (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableColumnSelectionCountPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelectionCount succeeded"); + return pkg->rCount; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelectionCount failed"); + return 0; +} + +BOOL +WinAccessBridge::isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column) { +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %p)", vmID, accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %016I64X)", vmID, accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage)]; + PackageType *type = (PackageType *) buffer; + IsAccessibleTableColumnSelectedPackage *pkg = (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType)); + *type = cIsAccessibleTableColumnSelectedPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->column = column; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::isAccessibleTableColumnSelected succeeded"); + return pkg->rResult; + } + } + PrintDebugString(" ##### WinAccessBridge::isAccessibleTableColumnSelected failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleTableColumnSelections(long vmID, JOBJECT64 accessibleTable, jint count, + jint *selections) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %p)", vmID, accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %016I64X)", vmID, accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableColumnSelectionsPackage *pkg = + (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableColumnSelectionsPackage; + pkg->vmID = vmID; + pkg->count = count; + pkg->accessibleTable = accessibleTable; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelections succeeded"); + memcpy(selections, pkg->rSelections, count * sizeof(jint)); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelections failed"); + return FALSE; +} + +jint +WinAccessBridge::getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRow(%X, %p, index=%d)", vmID, + accessibleTable, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRow(%X, %016I64X, index=%d)", vmID, + accessibleTable, index); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableRowPackage *pkg = + (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableRowPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->index = index; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRow succeeded"); + return pkg->rRow; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRow failed"); + return 0; +} + +jint +WinAccessBridge::getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumn(%X, %p, index=%d)", vmID, + accessibleTable, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumn(%X, %016I64X, index=%d)", vmID, + accessibleTable, index); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableColumnPackage *pkg = + (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableColumnPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->index = index; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumn succeeded"); + return pkg->rColumn; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumn failed"); + return 0; +} + +jint +WinAccessBridge::getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableIndex(%X, %p, row=%d, col=%d)", vmID, + accessibleTable, row, column); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableIndex(%X, %016I64X, row=%d, col=%d)", vmID, + accessibleTable, row, column); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableIndexPackage *pkg = + (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableIndexPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->row = row; + pkg->column = column; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableIndex succeeded"); + return pkg->rIndex; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableIndex failed"); + return 0; +} + +/********** end AccessibleTable routines ******************************/ + +BOOL +WinAccessBridge::getAccessibleRelationSet(long vmID, JOBJECT64 accessibleContext, + AccessibleRelationSetInfo *relationSetInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleRelationSet(%X, %p, %X)", vmID, + accessibleContext, relationSetInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleRelationSet(%X, %016I64X, %X)", vmID, + accessibleContext, relationSetInfo); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleRelationSetPackage *pkg = (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleRelationSetPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### pkg->rAccessibleRelationSetInfo.relationCount = %X", + pkg->rAccessibleRelationSetInfo.relationCount); + memcpy(relationSetInfo, &(pkg->rAccessibleRelationSetInfo), sizeof(AccessibleRelationSetInfo)); + PrintDebugString(" ##### WinAccessBridge::getAccessibleRelationSet succeeded"); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleRelationSet failed"); + return FALSE; +} + + +/********** AccessibleHypertext routines ***********/ + +BOOL +WinAccessBridge::getAccessibleHypertext(long vmID, JOBJECT64 accessibleContext, + AccessibleHypertextInfo *hypertextInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertext(%X, %p, %X)", vmID, + accessibleContext, hypertextInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertext(%X, %016I64X, %X)", vmID, + accessibleContext, hypertextInfo); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleHypertextPackage *pkg = (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleHypertextPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo)); + + PrintDebugString(" ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount); + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext succeeded"); + + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext failed"); + return FALSE; +} + + +BOOL +WinAccessBridge::activateAccessibleHyperlink(long vmID, JOBJECT64 accessibleContext, + JOBJECT64 accessibleHyperlink) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::activateAccessibleHyperlink(%p %p)", accessibleContext, + accessibleHyperlink); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::activateAccessibleHyperlink(%016I64X %016I64X)", accessibleContext, + accessibleHyperlink); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage)]; + PackageType *type = (PackageType *) buffer; + ActivateAccessibleHyperlinkPackage *pkg = (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType)); + *type = cActivateAccessibleHyperlinkPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->accessibleHyperlink = accessibleHyperlink; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID); + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rResult; + } + PrintDebugString(" WinAccessBridge::activateAccessibleHyperlink returning FALSE (sendMemoryPackage failed)"); + return FALSE; +} + +/* + * Returns the number of hyperlinks in a component + * Maps to AccessibleHypertext.getLinkCount. + * Returns -1 on error. + */ +jint +WinAccessBridge::getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %p)", + vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %016I64X)", + vmID, accessibleContext); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleHyperlinkCountPackage *pkg = (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleHyperlinkCountPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### hypetext link count = %d", pkg->rLinkCount); + PrintDebugString(" ##### WinAccessBridge::getAccessibleHyperlinkCount succeeded"); + return pkg->rLinkCount; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleHyperlinkCount failed"); + return -1; +} + +/* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * returns FALSE on error. + */ +BOOL +WinAccessBridge::getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint startIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertextExt(%X, %p %p)", vmID, + accessibleContext, hypertextInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertextExt(%X, %016I64X %p)", vmID, + accessibleContext, hypertextInfo); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleHypertextExtPackage *pkg = (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleHypertextExtPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->startIndex = startIndex; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### pkg->rSuccess = %d", pkg->rSuccess); + + memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo)); + if (pkg->rSuccess == TRUE) { + PrintDebugString(" ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount); + PrintDebugString(" ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount); + } else { + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextExt failed"); + } + return pkg->rSuccess;; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextExt failed"); + return FALSE; +} + + +/* + * Returns the index into an array of hyperlinks that is associated with + * a character index in document; + * Maps to AccessibleHypertext.getLinkIndex. + * Returns -1 on error. + */ +jint +WinAccessBridge::getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHyperlink hypertext, + const jint charIndex) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %p)", + vmID, hypertext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %016I64X)", + vmID, hypertext); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleHypertextLinkIndexPackage *pkg = (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleHypertextLinkIndexPackage; + pkg->vmID = vmID; + pkg->hypertext = hypertext; + pkg->charIndex = charIndex; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### hypetext link index = %d", pkg->rLinkIndex); + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextLinkIndex succeeded"); + return pkg->rLinkIndex; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextLinkIndex failed"); + return -1; +} + +/* + * Returns the nth hyperlink in a document. + * Maps to AccessibleHypertext.getLink. + * Returns -1 on error + */ +BOOL +WinAccessBridge::getAccessibleHyperlink(const long vmID, + const AccessibleHyperlink hypertext, + const jint linkIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleHyperlink(%X, %p, %p)", vmID, + hypertext, hyperlinkInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleHyperlink(%X, %016I64X, %p)", vmID, + hypertext, hyperlinkInfo); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleHyperlinkPackage *pkg = (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleHyperlinkPackage; + pkg->vmID = vmID; + pkg->hypertext = hypertext; + pkg->linkIndex = linkIndex; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(hyperlinkInfo, &(pkg->rAccessibleHyperlinkInfo), + sizeof(AccessibleHyperlinkInfo)); + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext succeeded"); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext failed"); + return FALSE; +} + + +/********** AccessibleKeyBinding routines ***********/ + +BOOL +WinAccessBridge::getAccessibleKeyBindings(long vmID, JOBJECT64 accessibleContext, + AccessibleKeyBindings *keyBindings) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleKeyBindings(%X, %p, %p)", vmID, + accessibleContext, keyBindings); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleKeyBindings(%X, %016I64X, %p)", vmID, + accessibleContext, keyBindings); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleKeyBindingsPackage *pkg = (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleKeyBindingsPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(keyBindings, &(pkg->rAccessibleKeyBindings), sizeof(AccessibleKeyBindings)); + + PrintDebugString(" ##### keyBindings.keyBindingsCount = %d", keyBindings->keyBindingsCount); + for (int i = 0; i < keyBindings->keyBindingsCount; ++i) { + PrintDebugString(" Key Binding # %d", i+1); + PrintDebugString(" Modifiers: 0x%x", keyBindings->keyBindingInfo[i].modifiers); + PrintDebugString(" Character (hex): 0x%x", keyBindings->keyBindingInfo[i].character); + PrintDebugString(" Character (wide char): %lc", keyBindings->keyBindingInfo[i].character); + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleKeyBindings succeeded"); + + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleKeyBindings failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, AccessibleIcons *icons) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleIcons(%X, %p, %p)", vmID, + accessibleContext, icons); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleIcons(%X, %016I64X, %p)", vmID, + accessibleContext, icons); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleIconsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleIconsPackage *pkg = (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleIconsPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(icons, &(pkg->rAccessibleIcons), sizeof(AccessibleIcons)); + + PrintDebugString(" ##### icons.iconsCount = %d", icons->iconsCount); + PrintDebugString(" ##### WinAccessBridge::getAccessibleIcons succeeded"); + + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleIcons failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleActions(long vmID, JOBJECT64 accessibleContext, AccessibleActions *actions) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleActions(%X, %p, %p)", vmID, + accessibleContext, actions); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleActions(%X, %016I64X, %p)", vmID, + accessibleContext, actions); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleActionsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleActionsPackage *pkg = (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleActionsPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(actions, &(pkg->rAccessibleActions), sizeof(AccessibleActions)); + + PrintDebugString(" ##### actions.actionsCount = %d", actions->actionsCount); + PrintDebugString(" ##### WinAccessBridge::getAccessibleActions succeeded"); + + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleActions failed"); + return FALSE; +} + +BOOL +WinAccessBridge::doAccessibleActions(long vmID, JOBJECT64 accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::doAccessibleActions(%p #actions %d %ls)", accessibleContext, + actionsToDo->actionsCount, + actionsToDo->actions[0].name); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::doAccessibleActions(%016I64X #actions %d %ls)", accessibleContext, + actionsToDo->actionsCount, + actionsToDo->actions[0].name); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(DoAccessibleActionsPackage)]; + PackageType *type = (PackageType *) buffer; + DoAccessibleActionsPackage *pkg = (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType)); + *type = cDoAccessibleActionsPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + memcpy((void *)(&(pkg->actionsToDo)), (void *)actionsToDo, sizeof(AccessibleActionsToDo)); + pkg->failure = -1; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID); + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + *failure = pkg->failure; + return pkg->rResult; + } + PrintDebugString(" WinAccessBridge::doAccessibleActions returning FALSE (sendMemoryPackage failed)"); + return FALSE; +} + +/* ====== Utility methods ====== */ + +/** + * Sets a text field to the specified string. Returns whether successful. + */ +BOOL +WinAccessBridge::setTextContents (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *text) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(SetTextContentsPackage)]; + PackageType *type = (PackageType *) buffer; + SetTextContentsPackage *pkg = (SetTextContentsPackage *) (buffer + sizeof(PackageType)); + *type = cSetTextContentsPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + wcsncpy(pkg->text, text, sizeof(pkg->text)/sizeof(wchar_t)); // wide character copy + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::setTextContents(%X, %016I64X %ls)", vmID, accessibleContext, text); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::setTextContents(%X, %p %ls)", vmID, accessibleContext, text); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rResult; + } + } + return FALSE; +} + +/** + * Returns the Accessible Context of a Page Tab object that is the + * ancestor of a given object. If the object is a Page Tab object + * or a Page Tab ancestor object was found, returns the object + * AccessibleContext. + * If there is no ancestor object that has an Accessible Role of Page Tab, + * returns (AccessibleContext)0. + */ +AccessibleContext +WinAccessBridge::getParentWithRole (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetParentWithRolePackage)]; + PackageType *type = (PackageType *) buffer; + GetParentWithRolePackage *pkg = (GetParentWithRolePackage *) (buffer + sizeof(PackageType)); + *type = cGetParentWithRolePackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role)); + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getParentWithRole(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getParentWithRole(%X, %016I64X)", vmID, accessibleContext); +#endif + PrintDebugString(" pkg->vmID: %X", pkg->vmID); + PrintDebugString(" pkg->accessibleContext: %p", pkg->accessibleContext); + PrintDebugString(" pkg->role: %ls", pkg->role); + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" pkg->rAccessibleContext: %p", pkg->rAccessibleContext); + return pkg->rAccessibleContext; + } + } + return (JOBJECT64) 0; +} + + +/** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ +AccessibleContext +WinAccessBridge::getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetTopLevelObjectPackage)]; + PackageType *type = (PackageType *) buffer; + GetTopLevelObjectPackage *pkg = (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType)); + *type = cGetTopLevelObjectPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getTopLevelObject(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getTopLevelObject(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + return (JOBJECT64) 0; +} + +/** + * If there is an Ancestor object that has an Accessible Role of + * Internal Frame, returns the Accessible Context of the Internal + * Frame object. Otherwise, returns the top level object for that + * Java Window. Returns (AccessibleContext)0 on error. + */ +AccessibleContext +WinAccessBridge::getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage)]; + PackageType *type = (PackageType *) buffer; + GetParentWithRoleElseRootPackage *pkg = (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType)); + *type = cGetParentWithRoleElseRootPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role)); + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getParentWithRoleElseRoot(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getParentWithRoleElseRoot(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + return (JOBJECT64) 0; +} + +/** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ +int +WinAccessBridge::getObjectDepth (const long vmID, const AccessibleContext accessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return -1; + } + char buffer[sizeof(PackageType) + sizeof(GetObjectDepthPackage)]; + PackageType *type = (PackageType *) buffer; + GetObjectDepthPackage *pkg = (GetObjectDepthPackage *) (buffer + sizeof(PackageType)); + *type = cGetObjectDepthPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getObjectDepth(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getObjectDepth(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rResult; + } + } + return -1; +} + +/** + * Returns the Accessible Context of the currently ActiveDescendent of an object. + * Returns (AccessibleContext)0 on error. + */ +AccessibleContext +WinAccessBridge::getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetActiveDescendentPackage)]; + PackageType *type = (PackageType *) buffer; + GetActiveDescendentPackage *pkg = (GetActiveDescendentPackage *) (buffer + sizeof(PackageType)); + *type = cGetActiveDescendentPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getActiveDescendent(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getActiveDescendent(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + return (JOBJECT64) 0; +} + +/** + * Additional methods for Teton + */ + +/** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ +BOOL +WinAccessBridge::getVirtualAccessibleName(long vmID, AccessibleContext accessibleContext, + wchar_t *name, int len) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage)]; + PackageType *type = (PackageType *) buffer; + GetVirtualAccessibleNamePackage *pkg = (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType)); + *type = cGetVirtualAccessibleNamePackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + size_t max = (len > sizeof(pkg->rName)) ? sizeof(pkg->rName) : len; + pkg->len = (int)max; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getVirtualAccessibleName(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getVirtualAccessibleName(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + wcsncpy(name, pkg->rName, max); + PrintDebugString(" WinAccessBridge::getVirtualAccessibleName: Virtual name = %ls", name); + return TRUE; + } + } + return FALSE; +} + +/** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ +BOOL +WinAccessBridge::requestFocus(long vmID, AccessibleContext accessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(RequestFocusPackage)]; + PackageType *type = (PackageType *) buffer; + RequestFocusPackage *pkg = (RequestFocusPackage *) (buffer + sizeof(PackageType)); + *type = cRequestFocusPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::requestFocus(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::requestFocus(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return TRUE; + } + } + return FALSE; +} + +/** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ +BOOL +WinAccessBridge::selectTextRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(SelectTextRangePackage)]; + PackageType *type = (PackageType *) buffer; + SelectTextRangePackage *pkg = (SelectTextRangePackage *) (buffer + sizeof(PackageType)); + *type = cSelectTextRangePackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->startIndex = startIndex; + pkg->endIndex = endIndex; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" WinAccessBridge::selectTextRange(%X, %p %d %d)", vmID, accessibleContext, + startIndex, endIndex); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" WinAccessBridge::selectTextRange(%X, %016I64X %d %d)", vmID, accessibleContext, + startIndex, endIndex); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return TRUE; + } + } + return FALSE; +} + +/** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ +BOOL +WinAccessBridge::getTextAttributesInRange(long vmID, AccessibleContext accessibleContext, + int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage)]; + PackageType *type = (PackageType *) buffer; + GetTextAttributesInRangePackage *pkg = (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType)); + *type = cGetTextAttributesInRangePackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->startIndex = startIndex; + pkg->endIndex = endIndex; + memcpy(&(pkg->attributes), attributes, sizeof(AccessibleTextAttributesInfo)); + + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" WinAccessBridge::getTextAttributesInRange(%X, %p %d %d)", vmID, accessibleContext, + startIndex, endIndex); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" WinAccessBridge::getTextAttributesInRange(%X, %016I64X %d %d)", vmID, accessibleContext, + startIndex, endIndex); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + *attributes = pkg->attributes; + *len = pkg->rLength; + return TRUE; + } + } + return FALSE; +} + +/** + * Gets the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ +int +WinAccessBridge::getVisibleChildrenCount(long vmID, AccessibleContext accessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return -1; + } + char buffer[sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage)]; + PackageType *type = (PackageType *) buffer; + GetVisibleChildrenCountPackage *pkg = (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType)); + *type = cGetVisibleChildrenCountPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getVisibleChildrenCount(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getVisibleChildrenCount(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rChildrenCount; + } + } + return -1; +} + +/** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ +BOOL +WinAccessBridge::getVisibleChildren(long vmID, AccessibleContext accessibleContext, int startIndex, + VisibleChildrenInfo *visibleChildrenInfo) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetVisibleChildrenPackage)]; + PackageType *type = (PackageType *) buffer; + GetVisibleChildrenPackage *pkg = (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType)); + *type = cGetVisibleChildrenPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->startIndex = startIndex; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getVisibleChildren(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getVisibleChildren(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(visibleChildrenInfo, &(pkg->rVisibleChildrenInfo), sizeof(pkg->rVisibleChildrenInfo)); + return pkg->rSuccess; + } + } + return FALSE; +} + +/** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ +BOOL +WinAccessBridge::setCaretPosition(long vmID, AccessibleContext accessibleContext, int position) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(SetCaretPositionPackage)]; + PackageType *type = (PackageType *) buffer; + SetCaretPositionPackage *pkg = (SetCaretPositionPackage *) (buffer + sizeof(PackageType)); + *type = cSetCaretPositionPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->position = position; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::setCaretPosition(%X, %p %ls)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::setCaretPosition(%X, %016I64X %ls)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return TRUE; + } + } + return FALSE; +} + + +/********** AccessibleText routines ***********************************/ + +/** + * getAccessibleTextInfo - fills a struct with a bunch of information + * contained in the Java Accessibility AccessibleText API + * + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextInfo(long vmID, + JOBJECT64 AccessibleContext, + AccessibleTextInfo *textInfo, + jint x, jint y) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextInfoPackage *pkg = (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextInfoPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->x = x; + pkg->y = y; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextInfo(%X, %p, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextInfo(%X, %016I64X, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(textInfo, &(pkg->rTextInfo), sizeof(AccessibleTextInfo)); + if (pkg->rTextInfo.charCount != -1) { + PrintDebugString(" charCount: %d", textInfo->charCount); + PrintDebugString(" caretIndex: %d", textInfo->caretIndex); + PrintDebugString(" indexAtPoint: %d", textInfo->indexAtPoint); + return TRUE; + } + } + } + + return FALSE; +} + +/** + * getAccessibleTextItems - fills a struct with letter, word, and sentence info + * of the AccessibleText interface at a given index + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextItems(long vmID, + JOBJECT64 AccessibleContext, + AccessibleTextItemsInfo *textItems, + jint index) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextItemsPackage *pkg = (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextItemsPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = index; + // zero things out, in case the call fails + pkg->rTextItemsInfo.letter = '\0'; + pkg->rTextItemsInfo.word[0] = '\0'; + pkg->rTextItemsInfo.sentence[0] = '\0'; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextItems(%X, %p, %p, %d)", vmID, AccessibleContext, textItems, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextItems(%X, %016I64X, %p, %d)", vmID, AccessibleContext, textItems, index); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(textItems, &(pkg->rTextItemsInfo), sizeof(AccessibleTextItemsInfo)); + if (pkg->rTextItemsInfo.letter != '/0') { + return TRUE; + } + } + } + + return FALSE; +} + +/** + * getAccessibleTextSelectionInfo - returns information about the selected + * text of the object implementing AccessibleText + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextSelectionInfo(long vmID, + JOBJECT64 AccessibleContext, + AccessibleTextSelectionInfo *selectionInfo) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextSelectionInfoPackage *pkg = (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextSelectionInfoPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextSelectionInfo(%X, %p, %p)", vmID, AccessibleContext, selectionInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextSelectionInfo(%X, %016I64X, %p)", vmID, AccessibleContext, selectionInfo); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(selectionInfo, &(pkg->rTextSelectionItemsInfo), sizeof(AccessibleTextSelectionInfo)); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + +/** + * getAccessibleTextAttributes - performs the Java code: + * ...[[[FIXME]]] fill in this comment... + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextAttributes(long vmID, + JOBJECT64 AccessibleContext, + jint index, + AccessibleTextAttributesInfo *attributes) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextAttributeInfoPackage *pkg = (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextAttributeInfoPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = index; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextAttributes(%X, %p, %d, %p)", vmID, AccessibleContext, index, attributes); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextAttributes(%X, %016I64X, %d, %p)", vmID, AccessibleContext, index, attributes); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(attributes, &(pkg->rAttributeInfo), sizeof(AccessibleTextAttributesInfo)); + return TRUE; + } + } + + return FALSE; +} + +/** + * getAccessibleTextRect - gets the text bounding rectangle + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextRect(long vmID, + JOBJECT64 AccessibleContext, + AccessibleTextRectInfo *rectInfo, + jint index) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextRectInfoPackage *pkg = (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextRectInfoPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = index; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextRect(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextRect(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(rectInfo, (&pkg->rTextRectInfo), sizeof(AccessibleTextRectInfo)); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + + +/** + * getAccessibleTextRect - gets the text bounding rectangle + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getCaretLocation(long vmID, + JOBJECT64 AccessibleContext, + AccessibleTextRectInfo *rectInfo, + jint index) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetCaretLocationPackage)]; + PackageType *type = (PackageType *) buffer; + GetCaretLocationPackage *pkg = (GetCaretLocationPackage *) (buffer + sizeof(PackageType)); + *type = cGetCaretLocationPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = index; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getCaretLocation(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getCaretLocation(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(rectInfo, (&pkg->rTextRectInfo), sizeof(AccessibleTextRectInfo)); + return TRUE; + } + } + + return FALSE; +} + + +/** + * getEventsWaiting - gets the number of events waiting to fire + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +int +WinAccessBridge::getEventsWaiting() { + if(messageQueue) { + return(messageQueue->getEventsWaiting()); + } + return(0); +} + + +/** + * getAccessibleTextLineBounds - gets the bounding rectangle for the text line + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextLineBounds(long vmID, + JOBJECT64 AccessibleContext, + jint index, jint *startIndex, jint *endIndex) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextLineBoundsPackage *pkg = (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextLineBoundsPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = index; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextLineBounds(%X, %p, %d, )", vmID, AccessibleContext, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextLineBounds(%X, %016I64X, %d, )", vmID, AccessibleContext, index); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + *startIndex = pkg->rLineStart; + *endIndex = pkg->rLineEnd; + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + + +/** + * getAccessibleTextLineBounds - performs the Java code: + * ...[[[FIXME]]] fill in this comment... + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextRange(long vmID, + JOBJECT64 AccessibleContext, + jint start, jint end, wchar_t *text, short len) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextRangePackage *pkg = (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextRangePackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->start = start; + pkg->end = end; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextRange(%X, %p, %d, %d, )", vmID, AccessibleContext, start, end); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextRange(%X, %016I64X, %d, %d, )", vmID, AccessibleContext, start, end); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + wcsncpy(text, pkg->rText, len); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + + + + +/********** AccessibleValue routines ***************/ + +BOOL +WinAccessBridge::getCurrentAccessibleValueFromContext(long vmID, + JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetCurrentAccessibleValueFromContextPackage *pkg = (GetCurrentAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetCurrentAccessibleValueFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + wcsncpy(value, pkg->rValue, len); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + +BOOL +WinAccessBridge::getMaximumAccessibleValueFromContext(long vmID, + JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetMaximumAccessibleValueFromContextPackage *pkg = (GetMaximumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetMaximumAccessibleValueFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + wcsncpy(value, pkg->rValue, len); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + +BOOL +WinAccessBridge::getMinimumAccessibleValueFromContext(long vmID, + JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetMinimumAccessibleValueFromContextPackage *pkg = (GetMinimumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetMinimumAccessibleValueFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + wcsncpy(value, pkg->rValue, len); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + + +/********** AccessibleSelection routines ***************/ + +void +WinAccessBridge::addAccessibleSelectionFromContext(long vmID, + JOBJECT64 AccessibleContext, int i) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + AddAccessibleSelectionFromContextPackage *pkg = (AddAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cAddAccessibleSelectionFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = i; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + sendMemoryPackage(buffer, sizeof(buffer), destABWindow); + } +} + +void +WinAccessBridge::clearAccessibleSelectionFromContext(long vmID, + JOBJECT64 AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + ClearAccessibleSelectionFromContextPackage *pkg = (ClearAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cClearAccessibleSelectionFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + sendMemoryPackage(buffer, sizeof(buffer), destABWindow); + } +} + +JOBJECT64 +WinAccessBridge::getAccessibleSelectionFromContext(long vmID, + JOBJECT64 AccessibleContext, int i) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleSelectionFromContextPackage *pkg = (GetAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleSelectionFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = i; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + + return (JOBJECT64) 0; +} + +int +WinAccessBridge::getAccessibleSelectionCountFromContext(long vmID, + JOBJECT64 AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return -1; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleSelectionCountFromContextPackage *pkg = (GetAccessibleSelectionCountFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleSelectionCountFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return (int) pkg->rCount; + } + } + + return -1; +} + +BOOL +WinAccessBridge::isAccessibleChildSelectedFromContext(long vmID, + JOBJECT64 AccessibleContext, int i) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + IsAccessibleChildSelectedFromContextPackage *pkg = (IsAccessibleChildSelectedFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cIsAccessibleChildSelectedFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = i; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + if (pkg->rResult != 0) { + return TRUE; + } + } + } + + return FALSE; +} + + +void +WinAccessBridge::removeAccessibleSelectionFromContext(long vmID, + JOBJECT64 AccessibleContext, int i) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + RemoveAccessibleSelectionFromContextPackage *pkg = (RemoveAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cRemoveAccessibleSelectionFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = i; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + sendMemoryPackage(buffer, sizeof(buffer), destABWindow); + } +} + +void +WinAccessBridge::selectAllAccessibleSelectionFromContext(long vmID, + JOBJECT64 AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + SelectAllAccessibleSelectionFromContextPackage *pkg = (SelectAllAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cSelectAllAccessibleSelectionFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + sendMemoryPackage(buffer, sizeof(buffer), destABWindow); + } +} + + +/*********** Event handling methods **********************************/ + +/** + * addEventNotification - tell all Java-launched AccessBridge DLLs + * that we want events of the specified type + * + * [[[FIXME]]] since we're just sending a long & a source window, + * we could use a private message rather than WM_COPYDATA + * (though we still may want it to be synchronous; dunno...) + * + */ +void +WinAccessBridge::addJavaEventNotification(jlong type) { + PrintDebugString("WinAccessBridge::addJavaEventNotification(%016I64X)", type); + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + + char buffer[sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage)]; + PackageType *pkgType = (PackageType *) buffer; + AddJavaEventNotificationPackage *pkg = (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType)); + *pkgType = cAddJavaEventNotificationPackage; + pkg->type = type; + pkg->DLLwindow = ABHandleToLong(dialogWindow); + + PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %p", + *pkgType, pkg->type, pkg->DLLwindow); + + // send addEventNotification message to all JVMs + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + current->sendPackage(buffer, sizeof(buffer)); // no return values! + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; +} + +/** + * removeEventNotification - tell all Java-launched AccessBridge DLLs + * that we no longer want events of the + * specified type + * + * [[[FIXME]]] since we're just sending a long & a source window, + * we could use a private message rather than WM_COPYDATA + * (though we still may want it to be synchronous; dunno...) + * + */ +void +WinAccessBridge::removeJavaEventNotification(jlong type) { + PrintDebugString("in WinAccessBridge::removeJavaEventNotification(%016I64X)", type); + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage)]; + PackageType *pkgType = (PackageType *) buffer; + RemoveJavaEventNotificationPackage *pkg = (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType)); + *pkgType = cRemoveJavaEventNotificationPackage; + pkg->type = type; + pkg->DLLwindow = ABHandleToLong(dialogWindow); + + PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %p", + *pkgType, pkg->type, pkg->DLLwindow); + + // send removeEventNotification message to all JVMs + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + current->sendPackage(buffer, sizeof(buffer)); // no return values! + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; +} + + +/*********** Event handling methods **********************************/ + +/** + * addAccessibilityEventNotification - tell all Java-launched AccessBridge DLLs + * that we want events of the specified type + * + * [[[FIXME]]] since we're just sending a long & a source window, + * we could use a private message rather than WM_COPYDATA + * (though we still may want it to be synchronous; dunno...) + * + */ +void +WinAccessBridge::addAccessibilityEventNotification(jlong type) { + PrintDebugString("in WinAccessBridge::addAccessibilityEventNotification(%016I64X)", type); + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage)]; + PackageType *pkgType = (PackageType *) buffer; + AddAccessibilityEventNotificationPackage *pkg = (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType)); + *pkgType = cAddAccessibilityEventNotificationPackage; + pkg->type = type; + pkg->DLLwindow = ABHandleToLong(dialogWindow); + + PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %X", + *pkgType, pkg->type, pkg->DLLwindow); + + // send addEventNotification message to all JVMs + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + current->sendPackage(buffer, sizeof(buffer)); // no return values! + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; +} + +/** + * removeAccessibilityEventNotification - tell all Java-launched AccessBridge DLLs + * that we no longer want events of the + * specified type + * + * [[[FIXME]]] since we're just sending a long & a source window, + * we could use a private message rather than WM_COPYDATA + * (though we still may want it to be synchronous; dunno...) + * + */ +void +WinAccessBridge::removeAccessibilityEventNotification(jlong type) { + PrintDebugString("in WinAccessBridge::removeAccessibilityEventNotification(%016I64X)", type); + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage)]; + PackageType *pkgType = (PackageType *) buffer; + RemoveAccessibilityEventNotificationPackage *pkg = (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType)); + *pkgType = cRemoveAccessibilityEventNotificationPackage; + pkg->type = type; + pkg->DLLwindow = ABHandleToLong(dialogWindow); + + PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %X", + *pkgType, pkg->type, pkg->DLLwindow); + + // send removeEventNotification message to all JVMs + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + current->sendPackage(buffer, sizeof(buffer)); // no return values! + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; +} + + +#define CALL_SET_EVENT_FP(function, callbackFP) \ + void WinAccessBridge::function(callbackFP fp) { \ + eventHandler->function(fp, this); \ + /* eventHandler calls back to winAccessBridgeDLL to set eventMask */ \ + } + + void WinAccessBridge::setJavaShutdownFP(AccessBridge_JavaShutdownFP fp) { + eventHandler->setJavaShutdownFP(fp, this); + } + + CALL_SET_EVENT_FP(setPropertyChangeFP, AccessBridge_PropertyChangeFP) + CALL_SET_EVENT_FP(setFocusGainedFP, AccessBridge_FocusGainedFP) + CALL_SET_EVENT_FP(setFocusLostFP, AccessBridge_FocusLostFP) + CALL_SET_EVENT_FP(setCaretUpdateFP, AccessBridge_CaretUpdateFP) + CALL_SET_EVENT_FP(setMouseClickedFP, AccessBridge_MouseClickedFP) + CALL_SET_EVENT_FP(setMouseEnteredFP, AccessBridge_MouseEnteredFP) + CALL_SET_EVENT_FP(setMouseExitedFP, AccessBridge_MouseExitedFP) + CALL_SET_EVENT_FP(setMousePressedFP, AccessBridge_MousePressedFP) + CALL_SET_EVENT_FP(setMouseReleasedFP, AccessBridge_MouseReleasedFP) + CALL_SET_EVENT_FP(setMenuCanceledFP, AccessBridge_MenuCanceledFP) + CALL_SET_EVENT_FP(setMenuDeselectedFP, AccessBridge_MenuDeselectedFP) + CALL_SET_EVENT_FP(setMenuSelectedFP, AccessBridge_MenuSelectedFP) + CALL_SET_EVENT_FP(setPopupMenuCanceledFP, AccessBridge_PopupMenuCanceledFP) + CALL_SET_EVENT_FP(setPopupMenuWillBecomeInvisibleFP, AccessBridge_PopupMenuWillBecomeInvisibleFP) + CALL_SET_EVENT_FP(setPopupMenuWillBecomeVisibleFP, AccessBridge_PopupMenuWillBecomeVisibleFP) + + CALL_SET_EVENT_FP(setPropertyNameChangeFP, AccessBridge_PropertyNameChangeFP) + CALL_SET_EVENT_FP(setPropertyDescriptionChangeFP, AccessBridge_PropertyDescriptionChangeFP) + CALL_SET_EVENT_FP(setPropertyStateChangeFP, AccessBridge_PropertyStateChangeFP) + CALL_SET_EVENT_FP(setPropertyValueChangeFP, AccessBridge_PropertyValueChangeFP) + CALL_SET_EVENT_FP(setPropertySelectionChangeFP, AccessBridge_PropertySelectionChangeFP) + CALL_SET_EVENT_FP(setPropertyTextChangeFP, AccessBridge_PropertyTextChangeFP) + CALL_SET_EVENT_FP(setPropertyCaretChangeFP, AccessBridge_PropertyCaretChangeFP) + CALL_SET_EVENT_FP(setPropertyVisibleDataChangeFP, AccessBridge_PropertyVisibleDataChangeFP) + CALL_SET_EVENT_FP(setPropertyChildChangeFP, AccessBridge_PropertyChildChangeFP) + CALL_SET_EVENT_FP(setPropertyActiveDescendentChangeFP, AccessBridge_PropertyActiveDescendentChangeFP) + + CALL_SET_EVENT_FP(setPropertyTableModelChangeFP, AccessBridge_PropertyTableModelChangeFP) --- /dev/null 2015-03-30 10:56:18.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/WinAccessBridge.h 2015-03-30 10:56:17.171932900 -0500 @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A DLL which is loaded by Windows executables to handle communication + * between Java VMs purposes of Accessbility. + */ + +#ifndef __WinAccessBridge_H__ +#define __WinAccessBridge_H__ + +#include +#include "AccessBridgePackages.h" +#include "AccessBridgeEventHandler.h" +#include "AccessBridgeJavaVMInstance.h" +#include "AccessBridgeMessageQueue.h" + + +extern "C" { + BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, + LPVOID lpvReserved); + void AppendToCallOutput(char *s); + BOOL CALLBACK AccessBridgeDialogProc(HWND hDlg, UINT message, + UINT wParam, LONG lParam); + HWND getTopLevelHWND(HWND descendent); +} + +LRESULT CALLBACK WinAccessBridgeWindowProc(HWND hWnd, UINT message, + UINT wParam, LONG lParam); + +BOOL CALLBACK DeleteItemProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam); + +/** + * The WinAccessBridge class. The core of the Windows AT AccessBridge dll + */ +class WinAccessBridge { + HINSTANCE windowsInstance; + HWND dialogWindow; + AccessBridgeJavaVMInstance *javaVMs; + AccessBridgeEventHandler *eventHandler; + AccessBridgeMessageQueue *messageQueue; + +public: + WinAccessBridge(HINSTANCE hInstance); + ~WinAccessBridge(); + BOOL initWindow(); + + HWND showWinAccessBridgeGUI(int showCommand); + + // IPC with the Java AccessBridge DLL + LRESULT rendezvousWithNewJavaDLL(HWND JavaBridgeDLLwindow, long vmID); + + void sendPackage(char *buffer, long bufsize, HWND destWindow); + BOOL sendMemoryPackage(char *buffer, long bufsize, HWND destWindow); + BOOL queuePackage(char *buffer, long bufsize); + BOOL receiveAQueuedPackage(); + void preProcessPackage(char *buffer, long bufsize); + void processPackage(char *buffer, long bufsize); + void JavaVMDestroyed(HWND VMBridgeDLLWindow); + + // Java VM object memory management + void releaseJavaObject(long vmID, JOBJECT64 object); + + // Version info + BOOL getVersionInfo(long vmID, AccessBridgeVersionInfo *info); + + // HWND management methods + HWND getNextJavaWindow(HWND previous); + BOOL isJavaWindow(HWND window); + BOOL getAccessibleContextFromHWND(HWND window, long *vmID, JOBJECT64 *AccessibleContext); + HWND getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext); + + /* Additional utility methods */ + BOOL isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text); + + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext); + + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext); + + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext); + + + // Accessible Context methods + BOOL getAccessibleContextAt(long vmID, JOBJECT64 AccessibleContextParent, + jint x, jint y, JOBJECT64 *AccessibleContext); + BOOL getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT64 *AccessibleContext); + BOOL getAccessibleContextInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleContextInfo *info); + JOBJECT64 getAccessibleChildFromContext(long vmID, JOBJECT64 AccessibleContext, jint childIndex); + JOBJECT64 getAccessibleParentFromContext(long vmID, JOBJECT64 AccessibleContext); + + /* begin AccessibleTable methods */ + BOOL getAccessibleTableInfo(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableCellInfo(long vmID, JOBJECT64 accessibleTable, jint row, jint column, + AccessibleTableCellInfo *tableCellInfo); + + BOOL getAccessibleTableRowHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableColumnHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + + JOBJECT64 getAccessibleTableRowDescription(long vmID, JOBJECT64 acParent, jint row); + JOBJECT64 getAccessibleTableColumnDescription(long vmID, JOBJECT64 acParent, jint column); + + jint getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable); + BOOL isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row); + BOOL getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, + jint *selections); + + jint getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable); + BOOL isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column); + BOOL getAccessibleTableColumnSelections(long vmID, JOBJECT64 accessibleTable, jint count, + jint *selections); + + jint getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index); + jint getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index); + jint getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column); + + /* end AccessibleTable methods */ + + // --------- AccessibleRelationSet methods + BOOL getAccessibleRelationSet(long vmID, JOBJECT64 accessibleContext, AccessibleRelationSetInfo *relationSet); + + // --------- AccessibleHypertext methods + BOOL getAccessibleHypertext(long vmID, JOBJECT64 accessibleContext, AccessibleHypertextInfo *hypertextInfo); + BOOL activateAccessibleHyperlink(long vmID, JOBJECT64 accessibleContext, JOBJECT64 accessibleHyperlink); + + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext); + + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo); + + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + + /* Accessible KeyBindings, Icons and Actions */ + BOOL getAccessibleKeyBindings(long vmID, JOBJECT64 accessibleContext, + AccessibleKeyBindings *keyBindings); + + BOOL getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, + AccessibleIcons *icons); + + BOOL getAccessibleActions(long vmID, JOBJECT64 accessibleContext, + AccessibleActions *actions); + + BOOL doAccessibleActions(long vmID, JOBJECT64 accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + + // Accessible Text methods + BOOL getAccessibleTextInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleTextInfo *textInfo, jint x, jint y); + BOOL getAccessibleTextItems(long vmID, JOBJECT64 AccessibleContext, AccessibleTextItemsInfo *textItems, jint index); + BOOL getAccessibleTextSelectionInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleTextSelectionInfo *selectionInfo); + BOOL getAccessibleTextAttributes(long vmID, JOBJECT64 AccessibleContext, jint index, AccessibleTextAttributesInfo *attributes); + BOOL getAccessibleTextRect(long vmID, JOBJECT64 AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + BOOL getAccessibleTextLineBounds(long vmID, JOBJECT64 AccessibleContext, jint index, jint *startIndex, jint *endIndex); + BOOL getAccessibleTextRange(long vmID, JOBJECT64 AccessibleContext, jint start, jint end, wchar_t *text, short len); + + // Accessible Value methods + BOOL getCurrentAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, wchar_t *value, short len); + BOOL getMaximumAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, wchar_t *value, short len); + BOOL getMinimumAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, wchar_t *value, short len); + + // Accessible Selection methods + void addAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i); + void clearAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext); + JOBJECT64 getAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i); + int getAccessibleSelectionCountFromContext(long vmID, JOBJECT64 AccessibleContext); + BOOL isAccessibleChildSelectedFromContext(long vmID, JOBJECT64 AccessibleContext, int i); + void removeAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i); + void selectAllAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext); + + // Event handling methods + void addJavaEventNotification(jlong type); + void removeJavaEventNotification(jlong type); + void addAccessibilityEventNotification(jlong type); + void removeAccessibilityEventNotification(jlong type); + + void setPropertyChangeFP(AccessBridge_PropertyChangeFP fp); + void setJavaShutdownFP(AccessBridge_JavaShutdownFP fp); + void setFocusGainedFP(AccessBridge_FocusGainedFP fp); + void setFocusLostFP(AccessBridge_FocusLostFP fp); + void setCaretUpdateFP(AccessBridge_CaretUpdateFP fp); + void setMouseClickedFP(AccessBridge_MouseClickedFP fp); + void setMouseEnteredFP(AccessBridge_MouseEnteredFP fp); + void setMouseExitedFP(AccessBridge_MouseExitedFP fp); + void setMousePressedFP(AccessBridge_MousePressedFP fp); + void setMouseReleasedFP(AccessBridge_MouseReleasedFP fp); + void setMenuCanceledFP(AccessBridge_MenuCanceledFP fp); + void setMenuDeselectedFP(AccessBridge_MenuDeselectedFP fp); + void setMenuSelectedFP(AccessBridge_MenuSelectedFP fp); + void setPopupMenuCanceledFP(AccessBridge_PopupMenuCanceledFP fp); + void setPopupMenuWillBecomeInvisibleFP(AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + void setPopupMenuWillBecomeVisibleFP(AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + void setPropertyNameChangeFP(AccessBridge_PropertyNameChangeFP fp); + void setPropertyDescriptionChangeFP(AccessBridge_PropertyDescriptionChangeFP fp); + void setPropertyStateChangeFP(AccessBridge_PropertyStateChangeFP fp); + void setPropertyValueChangeFP(AccessBridge_PropertyValueChangeFP fp); + void setPropertySelectionChangeFP(AccessBridge_PropertySelectionChangeFP fp); + void setPropertyTextChangeFP(AccessBridge_PropertyTextChangeFP fp); + void setPropertyCaretChangeFP(AccessBridge_PropertyCaretChangeFP fp); + void setPropertyVisibleDataChangeFP(AccessBridge_PropertyVisibleDataChangeFP fp); + void setPropertyChildChangeFP(AccessBridge_PropertyChildChangeFP fp); + void setPropertyActiveDescendentChangeFP(AccessBridge_PropertyActiveDescendentChangeFP fp); + + void setPropertyTableModelChangeFP(AccessBridge_PropertyTableModelChangeFP fp); + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(long vmID, AccessibleContext accessibleContext, wchar_t *name, int len); + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(long vmID, AccessibleContext accessibleContext); + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex); + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + /** + * Gets number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(long vmID, AccessibleContext accessibleContext); + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(long vmID, AccessibleContext accessibleContext, int startIndex, + VisibleChildrenInfo *visibleChildrenInfo); + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(long vmID, AccessibleContext accessibleContext, int position); + + + /** + * Gets the text caret bounding rectangle + */ + BOOL getCaretLocation(long vmID, JOBJECT64 AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + + /** + * Gets number of events waiting in the message queue + */ + int getEventsWaiting(); + +}; + +#endif --- /dev/null 2015-03-30 10:56:21.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/accessBridgeResource.h 2015-03-30 10:56:20.262944500 -0500 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#define cVMID 1001 +#define cWindowsID 1002 +#define cStatusText 1003 +#define cCallInfo 1004 +#define cInvokedByText 1005 +#define IDC_STATIC -1 + +#define cInstallAccessBridge 2001 +#define cRemindThereIsNewJVM 2005 +#define cDoNotRemindThereIsNewJVM 2005 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1032 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif --- /dev/null 2015-03-30 10:56:24.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/accessibility.properties 2015-03-30 10:56:23.368952000 -0500 @@ -0,0 +1,6 @@ +# +# Load the Java Access Bridge class into the JVM +# +#assistive_technologies=com.sun.java.accessibility.AccessBridge +#screen_magnifier_present=true + --- /dev/null 2015-03-30 10:56:27.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/jabswitch.cpp 2015-03-30 10:56:26.536959100 -0500 @@ -0,0 +1,475 @@ +/* + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include +#include +#include +#include +#include + +// This is the default buffer size used for RegQueryValue values. +#define DEFAULT_ALLOC MAX_PATH +// only allocate a buffer as big as MAX_ALLOC for RegQueryValue values. +#define MAX_ALLOC 262144 + +static LPCTSTR ACCESSIBILITY_USER_KEY = + _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Accessibility"); +static LPCTSTR ACCESSIBILITY_SYSTEM_KEY = + _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Accessibility\\Session"); +static LPCTSTR ACCESSIBILITY_CONFIG = + _T("Configuration"); +static LPCTSTR STR_ACCESSBRIDGE = + _T("oracle_javaaccessbridge"); + +// Note: There are senarios where more than one extension can be specified on the +// asssistive_technologies= +// line but this code only deals with the case of +// assistive_technologies=com.sun.java.accessibility.AccessBridge +// assuming that if additional extensions are desired the user knows how edit the file. + +FILE* origFile; +FILE* tempFile; + +bool isXP() +{ + static bool isXPFlag = false; + OSVERSIONINFO osvi; + + // Initialize the OSVERSIONINFO structure. + ZeroMemory( &osvi, sizeof( osvi ) ); + osvi.dwOSVersionInfoSize = sizeof( osvi ); + + GetVersionEx( &osvi ); + + if ( osvi.dwMajorVersion == 5 ) // For Windows XP and Windows 2000 + isXPFlag = true; + + return isXPFlag ; +} + +void enableJAB() { + // Copy lines from orig to temp modifying the line containing + // assistive_technologies= + // There are various scenarios: + // 1) If the line exists exactly as + // #assistive_technologies=com.sun.java.accessibility.AccessBridge + // replace it with + // assistive_technologies=com.sun.java.accessibility.AccessBridge + // 2) else if the line exists exactly as + // assistive_technologies=com.sun.java.accessibility.AccessBridge + // use it as is + // 3) else if a line containing "assistive_technologies" exits + // a) if it's already commented out, us it as is (jab will be enabled in step 4) + // b) else if it's not commented out, comment it out and add a new line with + // assistive_technologies=com.sun.java.accessibility.AccessBridge + // 4) If the line doesn't exist (or case 3a), add + // assistive_technologies=com.sun.java.accessibility.AccessBridge + // Do the same for screen_magnifier_present= + char line[512]; + char commentLine[512] = "#"; + char jabLine[] = "assistive_technologies=com.sun.java.accessibility.AccessBridge\n"; + char magLine[] = "screen_magnifier_present=true\n"; + bool foundJabLine = false; + bool foundMagLine = false; + while (!feof(origFile)) { + if (fgets(line, 512, origFile) != NULL) { + if (_stricmp(line, "#assistive_technologies=com.sun.java.accessibility.AccessBridge\n") == 0) { + fputs(jabLine, tempFile); + foundJabLine = true; + } else if (_stricmp(line, jabLine) == 0) { + fputs(line, tempFile); + foundJabLine = true; + } else if (strstr(line, "assistive_technologies") != NULL) { + char* context; + char* firstNonSpaceChar = strtok_s(line, " ", &context); + if (*firstNonSpaceChar == '#') { + fputs(line, tempFile); + } else { + strcat_s(commentLine, line); + fputs(commentLine, tempFile); + fputs(jabLine, tempFile); + foundJabLine = true; + } + } else if (_stricmp(line, "#screen_magnifier_present=true\n") == 0) { + fputs(magLine, tempFile); + foundMagLine = true; + } else if (_stricmp(line, magLine) == 0) { + fputs(line, tempFile); + foundMagLine = true; + } else if (strstr(line, "screen_magnifier_present") != NULL) { + char* context; + char* firstNonSpaceChar = strtok_s(line, " ", &context); + if (*firstNonSpaceChar == '#') { + fputs(line, tempFile); + } else { + strcat_s(commentLine, line); + fputs(commentLine, tempFile); + fputs(magLine, tempFile); + foundMagLine = true; + } + } else { + fputs(line, tempFile); + } + } + } + if (!foundJabLine) { + fputs(jabLine, tempFile); + } + if (!foundMagLine) { + fputs(magLine, tempFile); + } +} + +void disableJAB() { + // Copy lines from orig to temp modifying the line containing + // assistive_technologies= + // There are various scenarios: + // 1) If the uncommented line exists, comment it out + // 2) If the line exists but is preceeded by a #, nothing to do + // 3) If the line doesn't exist, nothing to do + // Do the same for screen_magnifier_present= + char line[512]; + char commentLine[512]; + while (!feof(origFile)) { + if (fgets(line, 512, origFile) != NULL) { + if (strstr(line, "assistive_technologies") != NULL) { + char* context; + char* firstNonSpaceChar = strtok_s(line, " ", &context); + if (*firstNonSpaceChar != '#') { + strcpy_s(commentLine, "#"); + strcat_s(commentLine, line); + fputs(commentLine, tempFile); + } else { + fputs(line, tempFile); + } + } else if (strstr(line, "screen_magnifier_present") != NULL) { + char* context; + char* firstNonSpaceChar = strtok_s(line, " ", &context); + if (*firstNonSpaceChar != '#') { + strcpy_s(commentLine, "#"); + strcat_s(commentLine, line); + fputs(commentLine, tempFile); + } else { + fputs(line, tempFile); + } + } else { + fputs(line, tempFile); + } + } + } +} + +int modify(bool enable) { + errno_t error = 0; + char path[512]; + char tempPath[512]; + // Get the path for %USERPROFILE% + char *profilePath; + size_t len; + error = _dupenv_s(&profilePath, &len, "USERPROFILE" ); + if (error) { + printf("Error fetching USERPROFILE.\n"); + perror("Error"); + return error; + } + strcpy_s(path, profilePath); + strcat_s(path, "\\.accessibility.properties"); + strcpy_s(tempPath, profilePath); + strcat_s(tempPath, "\\.acce$$ibility.properties"); + free(profilePath); + // Open the original file. If it doesn't exist and this is an enable request then create it. + error = fopen_s(&origFile, path, "r"); + if (error) { + if (enable) { + error = fopen_s(&origFile, path, "w"); + if (error) { + printf("Couldn't create file: %s\n", path); + perror("Error"); + } else { + char str[100] = "assistive_technologies=com.sun.java.accessibility.AccessBridge\n"; + strcat_s(str, "screen_magnifier_present=true\n"); + fprintf(origFile, str); + fclose(origFile); + } + } else { + // It's OK if the file isn't there for a -disable + error = 0; + } + } else { + // open a temp file + error = fopen_s(&tempFile, tempPath, "w"); + if (error) { + printf("Couldn't open temp file: %s\n", tempPath); + perror("Error"); + return error; + } + if (enable) { + enableJAB(); + } else { + disableJAB(); + } + fclose(origFile); + fclose(tempFile); + // delete the orig file and rename the temp file + if (remove(path) != 0) { + printf("Couldn't remove file: %s\n", path); + perror("Error"); + return errno; + } + if (rename(tempPath, path) != 0) { + printf("Couldn't rename %s to %s.\n", tempPath, path); + perror("Error"); + return errno; + } + } + return error; +} + +void printUsage() { + printf("\njabswitch [/enable | /disable | /version | /?]\n\n"); + printf("Description:\n"); + printf(" jabswitch enables or disables the Java Access Bridge.\n\n"); + printf("Parameters:\n"); + printf(" /enable Enable the Java Accessibility Bridge.\n"); + printf(" /disable Disable the Java Accessibility Bridge.\n"); + printf(" /version Display the version.\n"); + printf(" /? Display this usage information.\n"); + printf("\nNote:\n"); + printf(" The Java Access Bridge can also be enabled with the\n"); + printf(" Windows Ease of Access control panel (which can be\n"); + printf(" activated by pressing Windows + U). The Ease of Access\n"); + printf(" control panel has a Java Access Bridge checkbox. Please\n"); + printf(" be aware that unchecking the checkbox has no effect and\n"); + printf(" in order to disable the Java Access Bridge you must run\n"); + printf(" jabswitch.exe from the command line.\n"); +} + +void printVersion() { + TCHAR executableFileName[_MAX_PATH]; + if (!GetModuleFileName(0, executableFileName, _MAX_PATH)) { + printf("Unable to get executable file name.\n"); + return; + } + DWORD nParam; + DWORD nVersionSize = GetFileVersionInfoSize(executableFileName, &nParam); + if (!nVersionSize) { + printf("Unable to get version info size.\n"); + return; + } + char* pVersionData = new char[nVersionSize]; + if (!GetFileVersionInfo(executableFileName, 0, nVersionSize, pVersionData)) { + printf("Unable to get version info.\n"); + return; + } + LPVOID pVersionInfo; + UINT nSize; + if (!VerQueryValue(pVersionData, _T("\\"), &pVersionInfo, &nSize)) { + printf("Unable to query version value.\n"); + return; + } + VS_FIXEDFILEINFO *pVSInfo = (VS_FIXEDFILEINFO *)pVersionInfo; + char versionString[100]; + sprintf_s( versionString, "version %i.%i.%i.%i", + pVSInfo->dwProductVersionMS >> 16, + pVSInfo->dwProductVersionMS & 0xFFFF, + pVSInfo->dwProductVersionLS >> 16, + pVSInfo->dwProductVersionLS & 0xFFFF ); + char outputString[100]; + strcpy_s(outputString, "jabswitch "); + strcat_s(outputString, versionString); + strcat_s(outputString, "\njabswitch enables or disables the Java Access Bridge.\n"); + printf(outputString); +} + +int regEnable() { + HKEY hKey; + DWORD retval = -1; + LSTATUS err; + err = RegOpenKeyEx(HKEY_CURRENT_USER, ACCESSIBILITY_USER_KEY, NULL, KEY_READ|KEY_WRITE, &hKey); + if (err == ERROR_SUCCESS) { + DWORD dataType = REG_SZ; + DWORD dataLength = DEFAULT_ALLOC; + TCHAR dataBuffer[DEFAULT_ALLOC]; + TCHAR *data = dataBuffer; + bool freeData = false; + err = RegQueryValueEx(hKey, ACCESSIBILITY_CONFIG, 0, &dataType, (BYTE *)data, &dataLength); + if (err == ERROR_MORE_DATA) { + if (dataLength > 0 && dataLength < MAX_ALLOC) { + data = new TCHAR[dataLength]; + err = RegQueryValueEx(hKey, ACCESSIBILITY_CONFIG, 0, &dataType, (BYTE *)data, &dataLength); + } + } + if (err == ERROR_SUCCESS) { + err = _tcslwr_s(dataBuffer, DEFAULT_ALLOC); + if (err) { + return -1; + } + if (_tcsstr(dataBuffer, STR_ACCESSBRIDGE) != NULL) { + return 0; // This is OK, e.g. ran enable twice and the value is there. + } else { + // add oracle_javaaccessbridge to Config key for HKCU + dataLength = dataLength + (_tcslen(STR_ACCESSBRIDGE) + 1) * sizeof(TCHAR); + TCHAR *newStr = new TCHAR[dataLength]; + if (newStr != NULL) { + wsprintf(newStr, L"%s,%s", dataBuffer, STR_ACCESSBRIDGE); + RegSetValueEx(hKey, ACCESSIBILITY_CONFIG, 0, REG_SZ, (BYTE *)newStr, dataLength); + } + } + } + RegCloseKey(hKey); + } + return err; +} + +int regDeleteValue(HKEY hFamilyKey, LPCWSTR lpSubKey) +{ + HKEY hKey; + DWORD retval = -1; + LSTATUS err; + err = RegOpenKeyEx(hFamilyKey, lpSubKey, NULL, KEY_READ|KEY_WRITE|KEY_WOW64_64KEY, &hKey); + if (err != ERROR_SUCCESS) + err = RegOpenKeyEx(hFamilyKey, lpSubKey, NULL, KEY_READ|KEY_WRITE, &hKey); + + if (err == ERROR_SUCCESS) { + DWORD dataType = REG_SZ; + DWORD dataLength = DEFAULT_ALLOC; + TCHAR dataBuffer[DEFAULT_ALLOC]; + TCHAR searchBuffer[DEFAULT_ALLOC]; + TCHAR *data = dataBuffer; + bool freeData = false; + err = RegQueryValueEx(hKey, ACCESSIBILITY_CONFIG, 0, &dataType, (BYTE *)data, &dataLength); + if (err == ERROR_MORE_DATA) { + if (dataLength > 0 && dataLength < MAX_ALLOC) { + data = new TCHAR[dataLength]; + err = RegQueryValueEx(hKey, ACCESSIBILITY_CONFIG, 0, &dataType, (BYTE *)data, &dataLength); + } + } + if (err == ERROR_SUCCESS) { + err = _tcslwr_s(dataBuffer, DEFAULT_ALLOC); + if (err) { + return -1; + } + if (_tcsstr(dataBuffer, STR_ACCESSBRIDGE) == NULL) { + return 0; // This is OK, e.g. ran disable twice and the value is not there. + } else { + // remove oracle_javaaccessbridge from Config key + TCHAR *newStr = new TCHAR[dataLength]; + TCHAR *nextToken; + LPTSTR tok, beg1 = dataBuffer; + bool first = true; + _tcscpy_s(newStr, dataLength, L""); + tok = _tcstok_s(beg1, L",", &nextToken); + while (tok != NULL) { + _tcscpy_s(searchBuffer, DEFAULT_ALLOC, tok); + err = _tcslwr_s(searchBuffer, DEFAULT_ALLOC); + if (err) { + return -1; + } + if (_tcsstr(searchBuffer, STR_ACCESSBRIDGE) == NULL) { + if (!first) { + _tcscat_s(newStr, dataLength, L","); + } + first = false; + _tcscat_s(newStr, dataLength, tok); + } + tok = _tcstok_s(NULL, L",", &nextToken); + } + dataLength = (_tcslen(newStr) + 1) * sizeof(TCHAR); + RegSetValueEx(hKey, ACCESSIBILITY_CONFIG, 0, REG_SZ, (BYTE *)newStr, dataLength); + } + } + RegCloseKey(hKey); + } + return err; +} + +int regDisable() +{ + LSTATUS err; + // Update value for HKCU + err=regDeleteValue(HKEY_CURRENT_USER, ACCESSIBILITY_USER_KEY); + // Update value for HKLM for Session + TCHAR dataBuffer[DEFAULT_ALLOC]; + DWORD dwSessionId ; + ProcessIdToSessionId(GetCurrentProcessId(),&dwSessionId ) ; + if( dwSessionId >= 0 ) + { + wsprintf(dataBuffer, L"%s%d", ACCESSIBILITY_SYSTEM_KEY, dwSessionId); + err=regDeleteValue(HKEY_LOCAL_MACHINE, dataBuffer); + } + return err; +} + +void main(int argc, char* argv[]) { + bool enableWasRequested = false; + bool disableWasRequested = false; + bool badParams = true; + int error = 0; + if (argc == 2) { + if (_stricmp(argv[1], "-?") == 0 || _stricmp(argv[1], "/?") == 0) { + printUsage(); + badParams = false; + } else if (_stricmp(argv[1], "-version") == 0 || _stricmp(argv[1], "/version") == 0) { + printVersion(); + badParams = false; + } else { + if (_stricmp(argv[1], "-enable") == 0 || _stricmp(argv[1], "/enable") == 0) { + badParams = false; + enableWasRequested = true; + error = modify(true); + if (error == 0) { + if( !isXP() ) + regEnable(); + } + } else if (_stricmp(argv[1], "-disable") == 0 || _stricmp(argv[1], "/disable") == 0) { + badParams = false; + disableWasRequested = true; + error = modify(false); + if (error == 0) { + if( !isXP() ) + regDisable(); + } + } + } + } + if (badParams) { + printUsage(); + } else if (enableWasRequested || disableWasRequested) { + if (error != 0) { + printf("There was an error.\n\n"); + } + printf("The Java Access Bridge has "); + if (error != 0) { + printf("not "); + } + printf("been "); + if (enableWasRequested) { + printf("enabled.\n"); + } else { + printf("disabled.\n"); + } + } +} --- /dev/null 2015-03-30 10:56:30.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/jabswitch.manifest 2015-03-30 10:56:29.684967800 -0500 @@ -0,0 +1,10 @@ + + + + + + + + + + --- /dev/null 2015-03-30 10:56:33.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/jabswitch_manifest.rc 2015-03-30 10:56:32.803976600 -0500 @@ -0,0 +1,4 @@ +#define XSTR(x) STR(x) +#define STR(x) #x + +1 /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 24 /* RT_MANIFEST */ XSTR(JAB_MANIFEST_EMBED) --- /dev/null 2015-03-30 10:56:36.000000000 -0500 +++ new/jdk/src/windows/native/sun/bridge/resource.h 2015-03-30 10:56:35.925987800 -0500 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by AccessBridgeStatusWindow.RC +// +//#define IDB_BITMAP1 102 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1032 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif