Merge
diff --git a/.hgtags b/.hgtags
index 8f9a20b..8bfbeae 100644
--- a/.hgtags
+++ b/.hgtags
@@ -421,3 +421,21 @@
0010682d9a2b81daf7c08239161f7c2a91977299 jdk8u51-b12
217fa7205549d196c60f814bf3fc9795d756f493 jdk8u51-b13
b7403e15864dc0c1f9740d66af91bddb3e2215e8 jdk8u51-b14
+5c31204d19e5976f025026db3d5c17331e8c44db jdk8u60-b00
+c46daef6edb5385d11876ed40f292a4b62e96867 jdk8u60-b01
+c10fd784956cc7099657181029ac3e790267b678 jdk8u60-b02
+87c95759b92b9c2933e439f0f7e4897635af16e0 jdk8u60-b03
+81e87652146b74c4ffeb1862e3e0eb3ace2374e4 jdk8u60-b04
+433942aab113e7eeecbe086b346219536738b0b6 jdk8u60-b05
+3a8ecea921f65bc1aef108b657c718348e152b9a jdk8u60-b06
+e48ca20d8943854c878e3b8d86d6d5387b047996 jdk8u60-b07
+478602cc17e212571cd0bec8979d5adc6d5c456e jdk8u60-b08
+fc3f69854e7d28416168eee07859c06fe90fa6f5 jdk8u60-b09
+ae448eca6b545670656c505bdc830b6dabaf1be3 jdk8u60-b10
+bdcb84f205482c7aea48a1403e843f5fd689d849 jdk8u60-b11
+87d4b7551d321c473d97afd75c1b71f6cedda4e2 jdk8u60-b12
+4e2206aa336c312ee180421387b7a6e7cdd0a3ca jdk8u60-b13
+3ad03712ea43feb5d4cd8cb216e6d295d09b8457 jdk8u60-b14
+a006fa0a9e8f18dee6daf8984bd11625c4c4860c jdk8u60-b15
+6ed3821c212a93ffc6bfcc292ef7aca3b7165139 jdk8u60-b16
+c30db4c968f63dce1bf2f9df240fb75a8f27f922 jdk8u60-b17
diff --git a/make/CompileJavaClasses.gmk b/make/CompileJavaClasses.gmk
index 865eb24..9fc1198 100644
--- a/make/CompileJavaClasses.gmk
+++ b/make/CompileJavaClasses.gmk
@@ -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
@@ -64,7 +64,10 @@
# This gets built on unix platforms implicitly in the old build even though
# it's excluded in the closed build.
EXCLUDES += sun/java2d/pisces
+ endif
+endif
+ifeq ($(OPENJDK_TARGET_OS), windows)
# AccessBridge is compiled separately below.
EXFILES += AccessBridge.java \
AccessBridgeLoader.java \
@@ -73,8 +76,6 @@
EXCLUDES += com/sun/java/accessibility/extensions
endif
-endif
-
ifneq ($(OPENJDK_TARGET_OS), solaris)
# Exclude Solaris nio and two security related files in src/share/classes
EXFILES += SolarisAclFileAttributeView.java \
@@ -272,7 +273,7 @@
ifndef OPENJDK
CLOSED_SRC_DIRS := $(JDK_TOPDIR)/src/closed/share/classes \
- $(JDK_TOPDIR)/src/closed/$(OPENJDK_TARGET_OS_API_DIR)/classes
+ $(wildcard $(JDK_TOPDIR)/src/closed/$(OPENJDK_TARGET_OS_API_DIR)/classes)
endif
MACOSX_SRC_DIRS :=
@@ -379,7 +380,6 @@
##########################################################################################
-ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS), windows)
ifeq ($(OPENJDK_TARGET_CPU_BITS), 32)
$(eval $(call SetupJavaCompilation,BUILD_ACCESSBRIDGE_32, \
@@ -413,7 +413,6 @@
endif
endif
-endif
##########################################################################################
diff --git a/make/CompileLaunchers.gmk b/make/CompileLaunchers.gmk
index b9a7597..b69b5b4 100644
--- a/make/CompileLaunchers.gmk
+++ b/make/CompileLaunchers.gmk
@@ -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)
$(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,17 +674,16 @@
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
##########################################################################################
diff --git a/make/CopyFiles.gmk b/make/CopyFiles.gmk
index e2ff9c9..9c7e7bc 100644
--- a/make/CopyFiles.gmk
+++ b/make/CopyFiles.gmk
@@ -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,7 +55,6 @@
##########################################################################################
-ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS), windows)
COPY_FILES += $(OPENJDK_TARGET_OS_INCLUDE)/bridge/AccessBridgeCallbacks.h \
$(OPENJDK_TARGET_OS_INCLUDE)/bridge/AccessBridgeCalls.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
##########################################################################################
@@ -285,7 +282,10 @@
ifeq ($(OPENJDK_TARGET_OS), macosx)
JVMCFG_SRC := $(JDK_TOPDIR)/src/macosx/bin/$(JVMCFG_ARCH)/jvm.cfg
else
- JVMCFG_SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/bin/$(JVMCFG_ARCH)/jvm.cfg
+ JVMCFG_BASE := $(OPENJDK_TARGET_OS_API_DIR)/bin/$(JVMCFG_ARCH)/jvm.cfg
+ ALT_JVMCFG_SRC := $(JDK_TOPDIR)/src/closed/$(JVMCFG_BASE)
+ # Use the ALT file if it exists
+ JVMCFG_SRC := $(if $(wildcard $(ALT_JVMCFG_SRC)),$(ALT_JVMCFG_SRC),$(JDK_TOPDIR)/src/$(JVMCFG_BASE))
endif
JVMCFG_DIR := $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_LIBDIR)
JVMCFG := $(JVMCFG_DIR)/jvm.cfg
diff --git a/make/CreateJars.gmk b/make/CreateJars.gmk
index 91532ad..bfbb10e 100644
--- a/make/CreateJars.gmk
+++ b/make/CreateJars.gmk
@@ -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
@@ -267,10 +267,12 @@
$(RM) $@ $@.tmp
$(GREP) -e '\.class$$' $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.jars.contents > $@.tmp
ifneq ($(PROFILE), )
- # # Add back classes from excluded packages (fixing the $ substitution in the process)
- for type in $(subst \$$,\, $(RT_JAR_INCLUDE_TYPES)) ; do \
- $(ECHO) $$type >> $@.tmp ; \
- done
+ ifneq ($(strip $(RT_JAR_INCLUDE_TYPES)), )
+ # Add back classes from excluded packages (fixing the $ substitution in the process)
+ for type in $(subst \$$,\, $(RT_JAR_INCLUDE_TYPES)) ; do \
+ $(ECHO) $$type >> $@.tmp ; \
+ done
+ endif
endif
$(MV) $@.tmp $@
@@ -281,15 +283,15 @@
-e '/_the\.*' -e '^_the\.*' -e '\\_the\.*' -e 'javac_state' \
$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.jars.contents > $@.tmp
ifneq ($(PROFILE), )
- # # Strip out all META-INF/services/ entries
- $(GREP) -v -e 'META-INF/services/' $@.tmp > $@.tmp2
- # # Add back the required services
- # # FIXME: On Solaris if PROFILE_INCLUDE_METAINF_SERVICES is not defined
- # # we get a syntax error from sh. That doesn't happen on linux
- for service in $(PROFILE_INCLUDE_METAINF_SERVICES) ; do \
- $(ECHO) $$service >> $@.tmp2; \
- done
- $(MV) $@.tmp2 $@.tmp
+ ifneq ($(strip $(PROFILE_INCLUDE_METAINF_SERVICES)), )
+ # Strip out all META-INF/services/ entries
+ $(GREP) -v -e 'META-INF/services/' $@.tmp > $@.tmp2
+ # Add back the required services
+ for service in $(PROFILE_INCLUDE_METAINF_SERVICES) ; do \
+ $(ECHO) $$service >> $@.tmp2; \
+ done
+ $(MV) $@.tmp2 $@.tmp
+ endif
endif
$(MV) $@.tmp $@
@@ -309,6 +311,15 @@
$(MKDIR) -p $(@D)
$(TOOL_REMOVEMETHODS) '$<' $@ addPropertyChangeListener removePropertyChangeListener
+# Code these targets explicitly because the target "%" expansion does
+# not work with the inline "$" in the file name.
+$(BEANLESS_CLASSES)/java/util/jar/Pack200\$$Packer.class: $(JDK_OUTPUTDIR)/classes/java/util/jar/Pack200$$Packer.class
+ $(MKDIR) -p $(@D)
+ $(TOOL_REMOVEMETHODS) '$<' $@ addPropertyChangeListener removePropertyChangeListener
+$(BEANLESS_CLASSES)/java/util/jar/Pack200\$$Unpacker.class: $(JDK_OUTPUTDIR)/classes/java/util/jar/Pack200$$Unpacker.class
+ $(MKDIR) -p $(@D)
+ $(TOOL_REMOVEMETHODS) '$<' $@ addPropertyChangeListener removePropertyChangeListener
+
CLASSES_TO_DEBEAN = \
java/util/logging/LogManager.class \
java/util/jar/Pack200\$$Packer.class \
@@ -639,7 +650,6 @@
##########################################################################################
-ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS), windows)
$(eval $(call SetupArchive,BUILD_JACCESS_JAR, , \
@@ -675,7 +685,6 @@
JARS += $(IMAGES_OUTPUTDIR)/lib/ext/access-bridge-64.jar
endif
endif
-endif
##########################################################################################
diff --git a/make/Images.gmk b/make/Images.gmk
index 51d0c14..3560f8c 100644
--- a/make/Images.gmk
+++ b/make/Images.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -161,11 +161,13 @@
ifeq ($(OPENJDK_TARGET_OS), windows)
JDK_BIN_LIST := $(filter $(addprefix %, $(WINDOWS_JDK_BIN_FILES)), $(ALL_BIN_LIST))
- # On windows x86, the server jvm is filtered out from the j2re image. This could possibly
- # be handled by profiles in the future. If no client jvm is built, leave server in.
+ # On windows x86, the server jvm is filtered out from the j2re image. This is historical
+ # and is not applied to compact profiles. If no client jvm is built, leave server in.
ifeq ($(OPENJDK_TARGET_CPU), x86)
ifeq ($(JVM_VARIANT_CLIENT), true)
- JRE_BIN_LIST := $(filter-out $(JDK_OUTPUTDIR)/bin/server/%, $(JRE_BIN_LIST))
+ ifeq ($(PROFILE), )
+ JRE_BIN_LIST := $(filter-out $(JDK_OUTPUTDIR)/bin/server/%, $(JRE_BIN_LIST))
+ endif
endif
endif
else
diff --git a/make/Import.gmk b/make/Import.gmk
index 92d4d1d..b115fa7 100644
--- a/make/Import.gmk
+++ b/make/Import.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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
@@ -116,6 +116,12 @@
#
HOTSPOT_IMPORT_FILES := $(addprefix $(LIBRARY_PREFIX), jvm.* saproc.* jsig.* sawindbg.* jvm_db.* jvm_dtrace.*) \
Xusage.txt sa-jdi.jar
+
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # additional debug file
+ HOTSPOT_IMPORT_FILES += Info.plist
+endif
+
$(eval $(call CopyDir,HOTSPOT0, $(HOTSPOT_LIB_DIR), $(INSTALL_LIBRARIES_HERE), $(HOTSPOT_IMPORT_FILES)))
$(eval $(call CopyDir,HOTSPOT1, $(HOTSPOT_DIST)/lib, $(JDK_OUTPUTDIR)/lib, $(HOTSPOT_IMPORT_FILES)))
diff --git a/make/Profiles.gmk b/make/Profiles.gmk
index dc4ea59..4b005a1 100644
--- a/make/Profiles.gmk
+++ b/make/Profiles.gmk
@@ -47,7 +47,6 @@
# Note that some jars may be optional depending on the type of build (jdk vs.
# openjdk) and the platform.
#
-# WARNING: incoming lists are currently validated for linux only!
###############################################################################
# These are jar files for which the contents vary depending on the profile
diff --git a/make/Tools.gmk b/make/Tools.gmk
index 7ef8698..b45d5dc 100644
--- a/make/Tools.gmk
+++ b/make/Tools.gmk
@@ -124,11 +124,11 @@
build.tools.cldrconverter.CLDRConverter
TOOL_REMOVEMETHODS = $(JAVA_SMALL) -Xbootclasspath/p:$(LANGTOOLS_OUTPUTDIR)/dist/bootstrap/lib/javac.jar \
- -cp $(JDK_OUTPUTDIR)/btclasses:$(JDK_OUTPUTDIR) \
+ -cp '$(JDK_OUTPUTDIR)/btclasses$(PATH_SEP)$(JDK_OUTPUTDIR)' \
build.tools.classfile.RemoveMethods
TOOL_CHECKDEPS = $(JAVA_SMALL) -Xbootclasspath/p:$(LANGTOOLS_OUTPUTDIR)/dist/bootstrap/lib/javac.jar \
- -cp $(JDK_OUTPUTDIR)/btclasses:$(JDK_OUTPUTDIR) \
+ -cp '$(JDK_OUTPUTDIR)/btclasses$(PATH_SEP)$(JDK_OUTPUTDIR)' \
build.tools.deps.CheckDeps
TOOL_ADDTORESTRICTEDPKGS=$(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
diff --git a/make/data/charsetmapping/IBM1166.c2b b/make/data/charsetmapping/IBM1166.c2b
new file mode 100644
index 0000000..6cb3802
--- /dev/null
+++ b/make/data/charsetmapping/IBM1166.c2b
@@ -0,0 +1 @@
+0x15 U+0085
diff --git a/make/data/charsetmapping/IBM1166.map b/make/data/charsetmapping/IBM1166.map
new file mode 100644
index 0000000..daaf83e
--- /dev/null
+++ b/make/data/charsetmapping/IBM1166.map
@@ -0,0 +1,256 @@
+0x00 U+0000
+0x01 U+0001
+0x02 U+0002
+0x03 U+0003
+0x04 U+009c
+0x05 U+0009
+0x06 U+0086
+0x07 U+007f
+0x08 U+0097
+0x09 U+008d
+0x0a U+008e
+0x0b U+000b
+0x0c U+000c
+0x0d U+000d
+0x0e U+000e
+0x0f U+000f
+0x10 U+0010
+0x11 U+0011
+0x12 U+0012
+0x13 U+0013
+0x14 U+009d
+0x15 U+000a
+0x16 U+0008
+0x17 U+0087
+0x18 U+0018
+0x19 U+0019
+0x1a U+0092
+0x1b U+008f
+0x1c U+001c
+0x1d U+001d
+0x1e U+001e
+0x1f U+001f
+0x20 U+0080
+0x21 U+0081
+0x22 U+0082
+0x23 U+0083
+0x24 U+0084
+0x25 U+000a
+0x26 U+0017
+0x27 U+001b
+0x28 U+0088
+0x29 U+0089
+0x2a U+008a
+0x2b U+008b
+0x2c U+008c
+0x2d U+0005
+0x2e U+0006
+0x2f U+0007
+0x30 U+0090
+0x31 U+0091
+0x32 U+0016
+0x33 U+0093
+0x34 U+0094
+0x35 U+0095
+0x36 U+0096
+0x37 U+0004
+0x38 U+0098
+0x39 U+0099
+0x3a U+009a
+0x3b U+009b
+0x3c U+0014
+0x3d U+0015
+0x3e U+009e
+0x3f U+001a
+0x40 U+0020
+0x41 U+00a0
+0x42 U+04d9
+0x43 U+0493
+0x44 U+0451
+0x45 U+0454
+0x46 U+0455
+0x47 U+0456
+0x48 U+049b
+0x49 U+0458
+0x4a U+005b
+0x4b U+002e
+0x4c U+003c
+0x4d U+0028
+0x4e U+002b
+0x4f U+0021
+0x50 U+0026
+0x51 U+04a3
+0x52 U+04e9
+0x53 U+04b1
+0x54 U+04af
+0x55 U+045e
+0x56 U+04bb
+0x57 U+042a
+0x58 U+2116
+0x59 U+04d8
+0x5a U+005d
+0x5b U+0024
+0x5c U+002a
+0x5d U+0029
+0x5e U+003b
+0x5f U+005e
+0x60 U+002d
+0x61 U+002f
+0x62 U+0492
+0x63 U+0401
+0x64 U+0404
+0x65 U+0405
+0x66 U+0406
+0x67 U+049a
+0x68 U+0408
+0x69 U+04a2
+0x6a U+007c
+0x6b U+002c
+0x6c U+0025
+0x6d U+005f
+0x6e U+003e
+0x6f U+003f
+0x70 U+04e8
+0x71 U+04b0
+0x72 U+04ae
+0x73 U+00ad
+0x74 U+040e
+0x75 U+04ba
+0x76 U+044e
+0x77 U+0430
+0x78 U+0431
+0x79 U+0060
+0x7a U+003a
+0x7b U+0023
+0x7c U+0040
+0x7d U+0027
+0x7e U+003d
+0x7f U+0022
+0x80 U+0446
+0x81 U+0061
+0x82 U+0062
+0x83 U+0063
+0x84 U+0064
+0x85 U+0065
+0x86 U+0066
+0x87 U+0067
+0x88 U+0068
+0x89 U+0069
+0x8a U+0434
+0x8b U+0435
+0x8c U+0444
+0x8d U+0433
+0x8e U+0445
+0x8f U+0438
+0x90 U+0439
+0x91 U+006a
+0x92 U+006b
+0x93 U+006c
+0x94 U+006d
+0x95 U+006e
+0x96 U+006f
+0x97 U+0070
+0x98 U+0071
+0x99 U+0072
+0x9a U+043a
+0x9b U+043b
+0x9c U+043c
+0x9d U+043d
+0x9e U+043e
+0x9f U+043f
+0xa0 U+044f
+0xa1 U+007e
+0xa2 U+0073
+0xa3 U+0074
+0xa4 U+0075
+0xa5 U+0076
+0xa6 U+0077
+0xa7 U+0078
+0xa8 U+0079
+0xa9 U+007a
+0xaa U+0440
+0xab U+0441
+0xac U+0442
+0xad U+0443
+0xae U+0436
+0xaf U+0432
+0xb0 U+044c
+0xb1 U+044b
+0xb2 U+0437
+0xb3 U+0448
+0xb4 U+044d
+0xb5 U+0449
+0xb6 U+0447
+0xb7 U+044a
+0xb8 U+042e
+0xb9 U+0410
+0xba U+0411
+0xbb U+0426
+0xbc U+0414
+0xbd U+0415
+0xbe U+0424
+0xbf U+0413
+0xc0 U+007b
+0xc1 U+0041
+0xc2 U+0042
+0xc3 U+0043
+0xc4 U+0044
+0xc5 U+0045
+0xc6 U+0046
+0xc7 U+0047
+0xc8 U+0048
+0xc9 U+0049
+0xca U+0425
+0xcb U+0418
+0xcc U+0419
+0xcd U+041a
+0xce U+041b
+0xcf U+041c
+0xd0 U+007d
+0xd1 U+004a
+0xd2 U+004b
+0xd3 U+004c
+0xd4 U+004d
+0xd5 U+004e
+0xd6 U+004f
+0xd7 U+0050
+0xd8 U+0051
+0xd9 U+0052
+0xda U+041d
+0xdb U+041e
+0xdc U+041f
+0xdd U+042f
+0xde U+0420
+0xdf U+0421
+0xe0 U+005c
+0xe1 U+20ac
+0xe2 U+0053
+0xe3 U+0054
+0xe4 U+0055
+0xe5 U+0056
+0xe6 U+0057
+0xe7 U+0058
+0xe8 U+0059
+0xe9 U+005a
+0xea U+0422
+0xeb U+0423
+0xec U+0416
+0xed U+0412
+0xee U+042c
+0xef U+042b
+0xf0 U+0030
+0xf1 U+0031
+0xf2 U+0032
+0xf3 U+0033
+0xf4 U+0034
+0xf5 U+0035
+0xf6 U+0036
+0xf7 U+0037
+0xf8 U+0038
+0xf9 U+0039
+0xfa U+0417
+0xfb U+0428
+0xfc U+042d
+0xfd U+0429
+0xfe U+0427
+0xff U+009f
diff --git a/make/data/charsetmapping/IBM1166.nr b/make/data/charsetmapping/IBM1166.nr
new file mode 100644
index 0000000..6754519
--- /dev/null
+++ b/make/data/charsetmapping/IBM1166.nr
@@ -0,0 +1 @@
+0x25 U+000a
diff --git a/make/data/charsetmapping/extsbcs b/make/data/charsetmapping/extsbcs
index ed82dbe..502358e 100644
--- a/make/data/charsetmapping/extsbcs
+++ b/make/data/charsetmapping/extsbcs
@@ -22,6 +22,7 @@
IBM1147 IBM01147 Cp1147 false sun.nio.cs.ext
IBM1148 IBM01148 Cp1148 false sun.nio.cs.ext
IBM1149 IBM01149 Cp1149 false sun.nio.cs.ext
+IBM1166 x-IBM1166 Cp1166 false sun.nio.cs.ext
IBM273 IBM273 Cp273 false sun.nio.cs.ext
IBM277 IBM277 Cp277 false sun.nio.cs.ext
IBM278 IBM278 Cp278 false sun.nio.cs.ext
diff --git a/make/gensrc/GensrcLocaleDataMetaInfo.gmk b/make/gensrc/GensrcLocaleDataMetaInfo.gmk
index 80b9669..d449ad8 100644
--- a/make/gensrc/GensrcLocaleDataMetaInfo.gmk
+++ b/make/gensrc/GensrcLocaleDataMetaInfo.gmk
@@ -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
@@ -34,7 +34,8 @@
-name "TimeZoneNames_*.java" -o -name "TimeZoneNames_*.properties" -o \
-name "LocaleNames_*.java" -o -name "LocaleNames_*.properties" -o \
-name "CurrencyNames_*.java" -o -name "CurrencyNames_*.properties" -o \
- -name "CalendarData_*.java" -o -name "CalendarData_*.properties")
+ -name "CalendarData_*.java" -o -name "CalendarData_*.properties" -o \
+ -name "BreakIteratorInfo_*.java" -o -name "BreakIteratorRules_*.java")
# Then translate the locale files into for example: FormatData_sv
LOCALE_RESOURCES := $(sort $(subst .properties,,$(subst .java,,$(notdir $(LOCALE_FILES)))))
@@ -79,6 +80,12 @@
#sun.text.resources.CollationData
$(eval $(call CaptureLocale,CollationData))
+#sun.text.resources.BreakIteratorInfo
+$(eval $(call CaptureLocale,BreakIteratorInfo))
+
+#sun.text.resources.BreakIteratorRules
+$(eval $(call CaptureLocale,BreakIteratorRules))
+
#sun.util.resources.TimeZoneNames
$(eval $(call CaptureLocale,TimeZoneNames))
diff --git a/make/gensrc/GensrcMisc.gmk b/make/gensrc/GensrcMisc.gmk
index 33a655e..de686d4 100644
--- a/make/gensrc/GensrcMisc.gmk
+++ b/make/gensrc/GensrcMisc.gmk
@@ -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
@@ -174,11 +174,10 @@
##########################################################################################
-ifndef OPENJDK
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: \
@@ -216,6 +215,5 @@
endif
endif
-endif
##########################################################################################
diff --git a/make/lib/Awt2dLibraries.gmk b/make/lib/Awt2dLibraries.gmk
index fe3eb02..e4ded78 100644
--- a/make/lib/Awt2dLibraries.gmk
+++ b/make/lib/Awt2dLibraries.gmk
@@ -319,7 +319,6 @@
ifeq ($(OPENJDK_TARGET_OS), macosx)
LIBAWT_FILES += awt_LoadLibrary.c
- LIBAWT_CFLAGS += -F/System/Library/Frameworks/JavaVM.framework/Frameworks
endif
ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc)
@@ -485,7 +484,6 @@
LDFLAGS_SUFFIX_macosx := -lmlib_image -ljvm $(LIBM) \
-framework Cocoa \
-framework OpenGL \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport \
-framework ApplicationServices \
@@ -827,8 +825,8 @@
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_SUFFIX := $(BUILD_LIBFONTMANAGER_FONTLIB), \
LDFLAGS_SUFFIX_linux := -lawt $(LIBM) $(LIBCXX) -ljava -ljvm -lc, \
- LDFLAGS_SUFFIX_solaris := -lawt -lawt_xawt -lc $(LIBM) $(LIBCXX) -ljava -ljvm, \
- LDFLAGS_SUFFIX_aix := -lawt -lawt_xawt $(LIBM) $(LIBCXX) -ljava -ljvm,\
+ LDFLAGS_SUFFIX_solaris := -lawt -lawt_headless -lc $(LIBM) $(LIBCXX) -ljava -ljvm, \
+ LDFLAGS_SUFFIX_aix := -lawt -lawt_headless $(LIBM) $(LIBCXX) -ljava -ljvm,\
LDFLAGS_SUFFIX_macosx := -lawt $(LIBM) $(LIBCXX) -undefined dynamic_lookup \
-ljava -ljvm, \
LDFLAGS_SUFFIX_windows := $(WIN_JAVA_LIB) advapi32.lib user32.lib gdi32.lib \
@@ -1120,12 +1118,6 @@
-I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/jdga \
$(foreach dir, $(LIBAWT_HEADLESS_DIRS), -I$(dir))
- ifeq ($(OPENJDK_TARGET_OS), macosx)
- LIBAWT_HEADLESS_CFLAGS += \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
- -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks
- endif
-
LIBAWT_HEADLESS_FILES := \
awt_Font.c \
HeadlessToolkit.c \
@@ -1217,8 +1209,7 @@
ifeq ($(OPENJDK_TARGET_OS), macosx)
LIBSPLASHSCREEN_CFLAGS := -I$(JDK_TOPDIR)/src/macosx/native/sun/awt/splashscreen \
- $(LIBSPLASHSCREEN_CFLAGS) \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks
+ $(LIBSPLASHSCREEN_CFLAGS)
LIBSPLASHSCREEN_CFLAGS += -DWITH_MACOSX
LIBSPLASHSCREEN_CFLAGS += -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp
@@ -1250,7 +1241,6 @@
-framework ApplicationServices \
-framework Foundation \
-framework Cocoa \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation
else ifeq ($(OPENJDK_TARGET_OS), windows)
LIBSPLASHSCREEN_LDFLAGS_SUFFIX += kernel32.lib user32.lib gdi32.lib delayimp.lib -DELAYLOAD:user32.dll
@@ -1436,9 +1426,7 @@
-I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \
-I$(JDK_TOPDIR)/src/share/native/sun/java2d/loops \
-I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \
- -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
- -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \
+ -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_SUFFIX_macosx := -lawt -lmlib_image -losxapp -ljvm $(LIBM) \
@@ -1449,7 +1437,6 @@
-framework Cocoa \
-framework Security \
-framework ExceptionHandling \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport \
-framework OpenGL \
@@ -1482,8 +1469,7 @@
CFLAGS := $(CFLAGS_JDKLIB) \
-I$(JDK_TOPDIR)/src/macosx/native/com/apple/laf \
-I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \
- -I$(JDK_TOPDIR)/src/macosx/native/sun/awt \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks, \
+ -I$(JDK_TOPDIR)/src/macosx/native/sun/awt, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN) \
-Xlinker -rpath -Xlinker @loader_path, \
@@ -1491,7 +1477,6 @@
-framework Cocoa \
-framework Carbon \
-framework ApplicationServices \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport \
-ljava -ljvm, \
diff --git a/make/lib/PlatformLibraries.gmk b/make/lib/PlatformLibraries.gmk
index 533c698..88dae8c 100644
--- a/make/lib/PlatformLibraries.gmk
+++ b/make/lib/PlatformLibraries.gmk
@@ -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
@@ -32,14 +32,11 @@
LANG := C, \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) \
- -I$(JDK_TOPDIR)/src/macosx/native/apple/applescript \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
- -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \
+ -I$(JDK_TOPDIR)/src/macosx/native/apple/applescript, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_SUFFIX := -framework Cocoa \
-framework Carbon \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
$(LDFLAGS_JDKLIB_SUFFIX), \
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libAppleScriptEngine, \
@@ -63,9 +60,7 @@
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) \
-I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \
- -I$(JDK_OUTPUTDIR)/gensrc/sun/osxapp \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
- -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \
+ -I$(JDK_OUTPUTDIR)/gensrc/sun/osxapp, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_SUFFIX_macosx := \
@@ -76,7 +71,6 @@
-framework Cocoa \
-framework Security \
-framework ExceptionHandling \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport \
-framework OpenGL \
@@ -108,16 +102,13 @@
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) \
$(foreach dir, $(LIBOSX_DIRS), -I$(dir)) \
- -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
- -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \
+ -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_SUFFIX_macosx := \
-losxapp \
-framework Cocoa \
-framework ApplicationServices \
- -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport \
-framework Security \
@@ -136,10 +127,9 @@
##########################################################################################
-ifndef OPENJDK
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
@@ -158,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" \
@@ -168,7 +157,8 @@
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjawtaccessbridge$1, \
DEBUG_SYMBOLS := true)
- $$(BUILD_JAWTACCESSBRIDGE$1): $(JDK_OUTPUTDIR)/lib/$(LIBRARY_PREFIX)jawt$(STATIC_LIBRARY_SUFFIX)
+ $$(BUILD_JAWTACCESSBRIDGE$1): \
+ $(JDK_OUTPUTDIR)/lib/$(LIBRARY_PREFIX)jawt$(STATIC_LIBRARY_SUFFIX)
$(call SetupNativeCompilation,BUILD_JAVAACCESSBRIDGE$1, \
LIBRARY = JavaAccessBridge$1, \
@@ -184,8 +174,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" \
@@ -230,5 +219,5 @@
else
$(eval $(call SetupAccessBridge,-64,X64,64))
endif
+
endif
-endif
diff --git a/make/mapfiles/libnet/mapfile-vers b/make/mapfiles/libnet/mapfile-vers
index 9e07f44..3eb5e6d 100644
--- a/make/mapfiles/libnet/mapfile-vers
+++ b/make/mapfiles/libnet/mapfile-vers
@@ -110,6 +110,8 @@
NET_Bind;
NET_MapSocketOption;
NET_Wait;
+ NET_EnableFastTcpLoopback;
+ NET_ThrowNew;
ipv6_available;
local:
diff --git a/make/profile-includes.txt b/make/profile-includes.txt
index 86f1f85..3014a71 100644
--- a/make/profile-includes.txt
+++ b/make/profile-includes.txt
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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
@@ -22,38 +22,150 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
+
+# These lists define where a file belongs if it exists. It is perfectly fine
+# if a file does not exist on some platforms - we do not have to produce exact
+# per-platform lists. However, for clarity, platform-unique files are handled
+# in platform-specific conditionals.
+
+# On different platforms the libraries are placed into different locations in the
+# JRE:
+ifeq (, $(findstring $(OPENJDK_TARGET_OS), windows macosx))
+ # On non-windows/OSX libraries go into jre/lib/<arch>
+ LIBS_PREFIX := $(OPENJDK_TARGET_CPU_LEGACY_LIB)/
+else
+ # On OSX they go into jre/lib/ - on Windows they go into jre/bin/ and we won't use this
+ LIBS_PREFIX :=
+endif
+
+# Debug info files are tricky to deal with due to all the different platform variants
+# and because they can be zipped.
+ifeq ($(ZIP_DEBUGINFO_FILES), true)
+ # Common case and 'just works' on all platforms
+ DEBUG_SUFFIX := .diz
+else
+ # It gets complicated ...
+ ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # This is a directory, not a simple file, so
+ # it needs expanding explicitly later on
+ DEBUG_SUFFIX := $(SHARED_LIBRARY_SUFFIX).dSYM
+ else
+ ifeq ($(OPENJDK_TARGET_OS), windows)
+ DEBUG_SUFFIX := .map .pdb
+ else
+ DEBUG_SUFFIX := .debuginfo
+ endif
+ endif
+endif
+
+# Expand the contents of the .dSYM directories on macosx.
+# Param 1 - debug files list eg libFoo.dylib.dSYM or libFoo.diz (if zipped)
+# Param 2 - libraries list eg Foo
+# On macosx if not zipping debuginfo files we expand the contents of the .dSYM directories,
+# else we return the original list of .diz files.
+# On other OS we return the original list of debuginfo files (whether zipped or not)
+#
+define expand-debuginfo
+ $(if $(and $(filter-out true, $(ZIP_DEBUGINFO_FILES)), $(filter macosx, $(OPENJDK_TARGET_OS))), \
+ $(foreach i, $1, $(addsuffix /Contents/Info.plist, $i)) \
+ $(foreach i, $2, $(addsuffix /Contents/Resources/DWARF/$i, $(filter $i.%, $1))), \
+ $1)
+endef
+
+# Common executable files
PROFILE_1_JRE_BIN_FILES := \
java$(EXE_SUFFIX) \
keytool$(EXE_SUFFIX)
-PROFILE_1_JRE_LIB_FILES := \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)j2pkcs11$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)java$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsig.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)net$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)nio$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)sunec$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)verify$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)verify.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)zip$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/client/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/client/$(LIBRARY_PREFIX)jsig.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/client/$(LIBRARY_PREFIX)jvm$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/client/$(LIBRARY_PREFIX)jvm.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/client/Xusage.txt \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/jli/$(LIBRARY_PREFIX)jli$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/jvm.cfg \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/minimal/$(LIBRARY_PREFIX)jsig.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/minimal/$(LIBRARY_PREFIX)jvm$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/minimal/$(LIBRARY_PREFIX)jvm.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/minimal/Xusage.txt \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jsig.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jvm$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jvm.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/Xusage.txt \
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ PROFILE_1_JRE_BIN_FILES += javaw$(EXE_SUFFIX)
+endif
+
+PROFILE_1_LIBRARIES := \
+ j2pkcs11 \
+ java \
+ jsig \
+ net \
+ nio \
+ sunec \
+ verify \
+ zip
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ PROFILE_1_LIBRARIES += msvcrt100
+endif
+
+PROFILE_1_LIBRARIES := $(addprefix $(LIBRARY_PREFIX), $(PROFILE_1_LIBRARIES))
+PROFILE_1_DEBUG_FILES := $(foreach i, $(DEBUG_SUFFIX), $(addsuffix $i, $(PROFILE_1_LIBRARIES)))
+PROFILE_1_LIBRARIES := $(addsuffix $(SHARED_LIBRARY_SUFFIX), $(PROFILE_1_LIBRARIES))
+PROFILE_1_DEBUG_FILES := $(call expand-debuginfo, $(PROFILE_1_DEBUG_FILES), $(PROFILE_1_LIBRARIES))
+PROFILE_1_LIBRARIES += $(PROFILE_1_DEBUG_FILES)
+
+# Note: libjsig exists as both the real file and a symlink in the VM directory
+# so we have to treat it with care when looking for the debuginfo files
+VM_LIBRARIES := \
+ jvm
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+ VM_LIBRARIES += jvm_db jvm_dtrace
+endif
+
+VM_SYMLINKS := \
+ jsig
+
+VM_LIBRARIES := $(addprefix $(LIBRARY_PREFIX), $(VM_LIBRARIES))
+VM_DEBUG_FILES := $(foreach i, $(DEBUG_SUFFIX), $(addsuffix $i, $(VM_LIBRARIES)))
+VM_SYMLINKS := $(addprefix $(LIBRARY_PREFIX), $(VM_SYMLINKS))
+VM_LIBRARIES := $(addsuffix $(SHARED_LIBRARY_SUFFIX), $(VM_LIBRARIES))
+VM_DEBUG_FILES := $(call expand-debuginfo, $(VM_DEBUG_FILES), $(VM_LIBRARIES))
+VM_DEBUG_FILES += $(foreach i, $(DEBUG_SUFFIX), $(addsuffix $i, $(VM_SYMLINKS)))
+VM_SYMLINKS := $(addsuffix $(SHARED_LIBRARY_SUFFIX), $(VM_SYMLINKS))
+VM_LIBRARIES += $(VM_SYMLINKS)
+
+VM_FILES := \
+ Xusage.txt
+
+VM_DIRS := client server minimal
+
+VM_FILES := $(foreach i, $(VM_DIRS), $(addprefix $i/, $(VM_LIBRARIES) $(VM_FILES) $(VM_DEBUG_FILES)))
+
+JLI_LIBRARIES := \
+ jli
+
+ifneq ($(OPENJDK_TARGET_OS), windows)
+ JLI_SUBDIR := jli/
+else
+ JLI_SUBDIR :=
+endif
+
+JLI_LIBRARIES := $(addprefix $(JLI_SUBDIR)$(LIBRARY_PREFIX), $(JLI_LIBRARIES))
+JLI_DEBUG_FILES := $(foreach i, $(DEBUG_SUFFIX), $(addsuffix $i, $(JLI_LIBRARIES)))
+JLI_LIBRARIES := $(addsuffix $(SHARED_LIBRARY_SUFFIX), $(JLI_LIBRARIES))
+JLI_DEBUG_FILES := $(call expand-debuginfo, $(JLI_DEBUG_FILES), $(JLI_LIBRARIES))
+JLI_LIBRARIES += $(JLI_DEBUG_FILES)
+
+ifneq ($(OPENJDK_TARGET_OS), windows)
+ PROFILE_1_JRE_LIB_FILES := \
+ $(addprefix $(LIBS_PREFIX), $(PROFILE_1_LIBRARIES) $(VM_FILES) $(JLI_LIBRARIES))
+else
+ # On windows libraries go into jre/bin
+ PROFILE_1_JRE_BIN_FILES += $(PROFILE_1_LIBRARIES) $(VM_FILES) $(JLI_LIBRARIES)
+endif
+
+# Remaining jre/lib contents
+# OSX doesn't use <arch> directory
+#
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+ PROFILE_1_JRE_LIB_FILES += \
+ jvm.cfg \
+ jspawnhelper
+else
+ PROFILE_1_JRE_LIB_FILES += \
+ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/jvm.cfg \
+ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/jspawnhelper
+endif
+
+PROFILE_1_JRE_LIB_FILES += \
calendars.properties \
classlist \
content-types.properties \
@@ -81,6 +193,14 @@
security/trusted.libraries \
tzdb.dat
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ PROFILE_1_JRE_LIB_FILES += tzmappings
+else
+ ifeq ($(OPENJDK_TARGET_OS), solaris)
+ PROFILE_1_JRE_LIB_FILES += sdp/sdp.conf
+ endif
+endif
+
PROFILE_1_JRE_OTHER_FILES := \
COPYRIGHT \
LICENSE \
@@ -106,32 +226,63 @@
rmid$(EXE_SUFFIX) \
rmiregistry$(EXE_SUFFIX)
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ PROFILE_2_JRE_BIN_FILES += java-rmi$(EXE_SUFFIX)
+endif
+
+# If you add libraries here, make sure you use the same techniques
+# as used for the other profile's libraries regarding debug files etc
PROFILE_2_JRE_LIB_FILES :=
PROFILE_2_JRE_OTHER_FILES :=
PROFILE_2_JRE_JAR_FILES :=
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ PROFILE_3_JRE_BIN_FILES := \
+ kinit$(EXE_SUFFIX) \
+ klist$(EXE_SUFFIX) \
+ ktab$(EXE_SUFFIX)
+else
+ PROFILE_3_JRE_BIN_FILES :=
+endif
-PROFILE_3_JRE_BIN_FILES :=
+PROFILE_3_LIBRARIES := \
+ hprof \
+ instrument \
+ j2gss \
+ j2pcsc \
+ jaas_unix \
+ jaas_nt \
+ java_crw_demo \
+ jsdt \
+ management \
+ npt \
+ sctp
-PROFILE_3_JRE_LIB_FILES := \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)hprof$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)hprof.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)instrument$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)instrument.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)j2gss$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)j2pcsc$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jaas_unix$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)java_crw_demo$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)java_crw_demo.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsdt$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsdt.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)management$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)management.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)npt$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)npt.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)sctp$(SHARED_LIBRARY_SUFFIX) \
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ PROFILE_3_LIBRARIES += w2k_lsa_auth
+else
+ ifeq ($(OPENJDK_TARGET_OS), macosx)
+ PROFILE_3_LIBRARIES += osxkrb5
+ endif
+endif
+
+PROFILE_3_LIBRARIES := $(addprefix $(LIBRARY_PREFIX), $(PROFILE_3_LIBRARIES))
+PROFILE_3_DEBUG_FILES := $(foreach i, $(DEBUG_SUFFIX), $(addsuffix $i, $(PROFILE_3_LIBRARIES)))
+PROFILE_3_LIBRARIES := $(addsuffix $(SHARED_LIBRARY_SUFFIX), $(PROFILE_3_LIBRARIES))
+PROFILE_3_DEBUG_FILES := $(call expand-debuginfo, $(PROFILE_3_DEBUG_FILES), $(PROFILE_3_LIBRARIES))
+PROFILE_3_LIBRARIES += $(PROFILE_3_DEBUG_FILES)
+
+ifneq ($(OPENJDK_TARGET_OS), windows)
+ PROFILE_3_JRE_LIB_FILES := \
+ $(addprefix $(LIBS_PREFIX), $(PROFILE_3_LIBRARIES))
+else
+ # On windows libraries go into jre/bin
+ PROFILE_3_JRE_BIN_FILES += $(PROFILE_3_LIBRARIES)
+endif
+
+PROFILE_3_JRE_LIB_FILES += \
jvm.hprof.txt \
management-agent.jar \
management/jmxremote.access \
@@ -153,25 +304,40 @@
tnameserv$(EXE_SUFFIX) \
unpack200$(EXE_SUFFIX)
-FULL_JRE_LIB_FILES := \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)awt$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)awt_headless$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)awt_xawt$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)dcpr$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)dt_socket$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)dt_socket.diz \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)fontmanager$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jawt$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jdwp$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jfr$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jpeg$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsound$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsoundalsa$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)kcms$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)mlib_image$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)splashscreen$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)t2k$(SHARED_LIBRARY_SUFFIX) \
- $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)unpack$(SHARED_LIBRARY_SUFFIX) \
+JRE_LIBRARIES := \
+ awt \
+ awt_headless \
+ awt_xawt \
+ dcpr \
+ dt_socket \
+ fontmanager \
+ jawt \
+ jdwp \
+ jfr \
+ jpeg \
+ jsound \
+ jsoundalsa \
+ kcms \
+ mlib_image \
+ splashscreen \
+ t2k \
+ unpack
+
+JRE_LIBRARIES := $(addprefix $(LIBRARY_PREFIX), $(JRE_LIBRARIES))
+JRE_DEBUG_FILES := $(foreach i, $(DEBUG_SUFFIX), $(addsuffix $i, $(JRE_LIBRARIES)))
+JRE_LIBRARIES := $(addsuffix $(SHARED_LIBRARY_SUFFIX), $(JRE_LIBRARIES))
+JRE_DEBUG_FILES := $(call expand-debuginfo, $(JRE_DEBUG_FILES), $(JRE_LIBRARIES))
+JRE_LIBRARIES += $(JRE_DEBUG_FILES)
+
+ifneq ($(OPENJDK_TARGET_OS), windows)
+ FULL_JRE_LIB_FILES := \
+ $(addprefix $(LIBS_PREFIX), $(JRE_LIBRARIES))
+else
+ # On windows libraries go into jre/bin
+ FULL_JRE_BIN_FILES += $(JRE_LIBRARIES)
+endif
+
+FULL_JRE_LIB_FILES += \
charsets.jar \
cmm/CIEXYZ.pf \
cmm/GRAY.pf \
@@ -254,3 +420,4 @@
ext/nashorn.jar \
ext/zipfs.jar \
jfr.jar
+
diff --git a/make/profile-rtjar-includes.txt b/make/profile-rtjar-includes.txt
index ba90ac6..fc25e48 100644
--- a/make/profile-rtjar-includes.txt
+++ b/make/profile-rtjar-includes.txt
@@ -162,6 +162,8 @@
javax/management/remote/rmi/_RMIServer_Stub.class
FULL_JRE_RTJAR_INCLUDE_PACKAGES := \
+ apple \
+ com/apple \
com/oracle \
com/sun/accessibility/internal/resources \
com/sun/activation/registries \
@@ -213,6 +215,7 @@
sun/dc \
sun/font \
sun/java2d \
+ sun/lwawt \
sun/net/ftp \
sun/net/smtp \
sun/net/www/content/audio \
diff --git a/make/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java b/make/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java
index ca1271e..d424bc1 100644
--- a/make/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java
+++ b/make/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -72,10 +72,6 @@
private static String formatVersion;
private static String dataVersion;
private static String validCurrencyCodes;
- private static String currenciesWith0MinorUnitDecimals;
- private static String currenciesWith1MinorUnitDecimal;
- private static String currenciesWith3MinorUnitDecimal;
- private static String currenciesWithMinorUnitsUndefined;
// handy constants - must match definitions in java.util.Currency
// magic number
@@ -83,29 +79,31 @@
// number of characters from A to Z
private static final int A_TO_Z = ('Z' - 'A') + 1;
// entry for invalid country codes
- private static final int INVALID_COUNTRY_ENTRY = 0x007F;
+ private static final int INVALID_COUNTRY_ENTRY = 0x0000007F;
// entry for countries without currency
- private static final int COUNTRY_WITHOUT_CURRENCY_ENTRY = 0x0080;
+ private static final int COUNTRY_WITHOUT_CURRENCY_ENTRY = 0x00000200;
// mask for simple case country entries
- private static final int SIMPLE_CASE_COUNTRY_MASK = 0x0000;
+ private static final int SIMPLE_CASE_COUNTRY_MASK = 0x00000000;
// mask for simple case country entry final character
- private static final int SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK = 0x001F;
+ private static final int SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK = 0x0000001F;
// mask for simple case country entry default currency digits
- private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK = 0x0060;
+ private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK = 0x000001E0;
// shift count for simple case country entry default currency digits
private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT = 5;
+ // maximum number for simple case country entry default currency digits
+ private static final int SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS = 9;
// mask for special case country entries
- private static final int SPECIAL_CASE_COUNTRY_MASK = 0x0080;
+ private static final int SPECIAL_CASE_COUNTRY_MASK = 0x00000200;
// mask for special case country index
- private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x001F;
+ private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x0000001F;
// delta from entry index component in main table to index into special case tables
private static final int SPECIAL_CASE_COUNTRY_INDEX_DELTA = 1;
// mask for distinguishing simple and special case countries
private static final int COUNTRY_TYPE_MASK = SIMPLE_CASE_COUNTRY_MASK | SPECIAL_CASE_COUNTRY_MASK;
// mask for the numeric code of the currency
- private static final int NUMERIC_CODE_MASK = 0x0003FF00;
+ private static final int NUMERIC_CODE_MASK = 0x000FFC00;
// shift count for the numeric code of the currency
- private static final int NUMERIC_CODE_SHIFT = 8;
+ private static final int NUMERIC_CODE_SHIFT = 10;
// generated data
private static int[] mainTable = new int[A_TO_Z * A_TO_Z];
@@ -120,7 +118,7 @@
private static int[] specialCaseOldCurrenciesNumericCode = new int[maxSpecialCases];
private static int[] specialCaseNewCurrenciesNumericCode = new int[maxSpecialCases];
- private static final int maxOtherCurrencies = 70;
+ private static final int maxOtherCurrencies = 128;
private static int otherCurrenciesCount = 0;
private static StringBuffer otherCurrencies = new StringBuffer();
private static int[] otherCurrenciesDefaultFractionDigits = new int[maxOtherCurrencies];
@@ -129,6 +127,11 @@
// date format for parsing cut-over times
private static SimpleDateFormat format;
+ // Minor Units
+ private static String[] currenciesWithDefinedMinorUnitDecimals =
+ new String[SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS + 1];
+ private static String currenciesWithMinorUnitsUndefined;
+
public static void main(String[] args) {
// Look for "-o outputfilename" option
@@ -171,16 +174,14 @@
formatVersion = (String) currencyData.get("formatVersion");
dataVersion = (String) currencyData.get("dataVersion");
validCurrencyCodes = (String) currencyData.get("all");
- currenciesWith0MinorUnitDecimals = (String) currencyData.get("minor0");
- currenciesWith1MinorUnitDecimal = (String) currencyData.get("minor1");
- currenciesWith3MinorUnitDecimal = (String) currencyData.get("minor3");
+ for (int i = 0; i <= SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS; i++) {
+ currenciesWithDefinedMinorUnitDecimals[i]
+ = (String) currencyData.get("minor"+i);
+ }
currenciesWithMinorUnitsUndefined = (String) currencyData.get("minorUndefined");
if (formatVersion == null ||
dataVersion == null ||
validCurrencyCodes == null ||
- currenciesWith0MinorUnitDecimals == null ||
- currenciesWith1MinorUnitDecimal == null ||
- currenciesWith3MinorUnitDecimal == null ||
currenciesWithMinorUnitsUndefined == null) {
throw new NullPointerException("not all required data is defined in input");
}
@@ -207,7 +208,7 @@
if (currencyInfo.charAt(0) == firstChar && currencyInfo.charAt(1) == secondChar) {
checkCurrencyCode(currencyInfo);
int digits = getDefaultFractionDigits(currencyInfo);
- if (digits < 0 || digits > 3) {
+ if (digits < 0 || digits > SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS) {
throw new RuntimeException("fraction digits out of range for " + currencyInfo);
}
int numericCode= getNumericCode(currencyInfo);
@@ -231,13 +232,14 @@
}
private static int getDefaultFractionDigits(String currencyCode) {
- if (currenciesWith0MinorUnitDecimals.indexOf(currencyCode) != -1) {
- return 0;
- } else if (currenciesWith1MinorUnitDecimal.indexOf(currencyCode) != -1) {
- return 1;
- } else if (currenciesWith3MinorUnitDecimal.indexOf(currencyCode) != -1) {
- return 3;
- } else if (currenciesWithMinorUnitsUndefined.indexOf(currencyCode) != -1) {
+ for (int i = 0; i <= SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS; i++) {
+ if (currenciesWithDefinedMinorUnitDecimals[i] != null &&
+ currenciesWithDefinedMinorUnitDecimals[i].indexOf(currencyCode) != -1) {
+ return i;
+ }
+ }
+
+ if (currenciesWithMinorUnitsUndefined.indexOf(currencyCode) != -1) {
return -1;
} else {
return 2;
diff --git a/make/src/classes/build/tools/tzdb/ZoneRulesBuilder.java b/make/src/classes/build/tools/tzdb/ZoneRulesBuilder.java
index f4a437d..2b4f8ad 100644
--- a/make/src/classes/build/tools/tzdb/ZoneRulesBuilder.java
+++ b/make/src/classes/build/tools/tzdb/ZoneRulesBuilder.java
@@ -491,10 +491,10 @@
TZRule rule = new TZRule(year, month, dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay, timeDefinition, savingAmountSecs);
if (lastRule) {
lastRuleList.add(rule);
- maxLastRuleStartYear = Math.max(startYear, maxLastRuleStartYear);
} else {
ruleList.add(rule);
}
+ maxLastRuleStartYear = Math.max(startYear, maxLastRuleStartYear);
year++;
}
}
diff --git a/src/aix/classes/sun/nio/fs/AixNativeDispatcher.java b/src/aix/classes/sun/nio/fs/AixNativeDispatcher.java
index d46d80f..76e833a 100644
--- a/src/aix/classes/sun/nio/fs/AixNativeDispatcher.java
+++ b/src/aix/classes/sun/nio/fs/AixNativeDispatcher.java
@@ -43,7 +43,7 @@
static native UnixMountEntry[] getmntctl() throws UnixException;
// initialize
- private static native int init();
+ private static native void init();
static {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
diff --git a/src/aix/classes/sun/tools/attach/AixVirtualMachine.java b/src/aix/classes/sun/tools/attach/AixVirtualMachine.java
index 714f5c0..29ee013 100644
--- a/src/aix/classes/sun/tools/attach/AixVirtualMachine.java
+++ b/src/aix/classes/sun/tools/attach/AixVirtualMachine.java
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 SAP AG. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2015 SAP AG. 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
@@ -25,14 +25,14 @@
*/
package sun.tools.attach;
-import com.sun.tools.attach.VirtualMachine;
+import com.sun.tools.attach.AttachOperationFailedException;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.spi.AttachProvider;
+
import java.io.InputStream;
import java.io.IOException;
import java.io.File;
-import java.util.Properties;
// Based on 'LinuxVirtualMachine.java'. All occurrences of the string
// "Linux" have been textually replaced by "Aix" to avoid confusion.
@@ -192,6 +192,8 @@
}
if (completionStatus != 0) {
+ // read from the stream and use that as the error message
+ String message = readErrorMessage(sis);
sis.close();
// In the event of a protocol mismatch then the target VM
@@ -206,7 +208,11 @@
if (cmd.equals("load")) {
throw new AgentLoadException("Failed to load agent library");
} else {
- throw new IOException("Command failed in target VM");
+ if (message == null) {
+ throw new AttachOperationFailedException("Command failed in target VM");
+ } else {
+ throw new AttachOperationFailedException(message);
+ }
}
}
diff --git a/src/aix/native/sun/nio/fs/AixNativeDispatcher.c b/src/aix/native/sun/nio/fs/AixNativeDispatcher.c
index 82d8f62..e7afb20 100644
--- a/src/aix/native/sun/nio/fs/AixNativeDispatcher.c
+++ b/src/aix/native/sun/nio/fs/AixNativeDispatcher.c
@@ -56,23 +56,26 @@
/**
* Initialization
*/
-JNIEXPORT jint JNICALL
+JNIEXPORT void JNICALL
Java_sun_nio_fs_AixNativeDispatcher_init(JNIEnv* env, jclass this)
{
- jint flags = 0;
jclass clazz;
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
- if (clazz == NULL) {
- return 0;
- }
+ CHECK_NULL(clazz);
entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
+ CHECK_NULL(entry_name);
entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
+ CHECK_NULL(entry_dir);
entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
+ CHECK_NULL(entry_fstype);
entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
+ CHECK_NULL(entry_options);
entry_cls = (*env)->NewGlobalRef(env, clazz);
-
- return 0;
+ if (entry_cls == NULL) {
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return;
+ }
}
/**
diff --git a/src/aix/native/sun/tools/attach/AixVirtualMachine.c b/src/aix/native/sun/tools/attach/AixVirtualMachine.c
index a5ba160..8ed522d 100644
--- a/src/aix/native/sun/tools/attach/AixVirtualMachine.c
+++ b/src/aix/native/sun/tools/attach/AixVirtualMachine.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 SAP AG. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2015 SAP AG. 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
@@ -238,14 +238,14 @@
len = remaining;
}
- RESTARTABLE(read(fd, buf+off, len), n);
+ RESTARTABLE(read(fd, buf, len), n);
if (n == -1) {
JNU_ThrowIOExceptionWithLastError(env, "read");
} else {
if (n == 0) {
n = -1; // EOF
} else {
- (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off));
+ (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
}
}
return n;
diff --git a/src/macosx/classes/apple/security/KeychainStore.java b/src/macosx/classes/apple/security/KeychainStore.java
index 2016c48..c6c771a 100644
--- a/src/macosx/classes/apple/security/KeychainStore.java
+++ b/src/macosx/classes/apple/security/KeychainStore.java
@@ -140,7 +140,8 @@
* password to recover it.
*
* @param alias the alias name
- * @param password the password for recovering the key
+ * @param password the password for recovering the key. This password is
+ * used internally as the key is exported in a PKCS12 format.
*
* @return the requested key, or null if the given alias does not exist
* or does not identify a <i>key entry</i>.
@@ -155,6 +156,20 @@
{
permissionCheck();
+ // An empty password is rejected by MacOS API, no private key data
+ // is exported. If no password is passed (as is the case when
+ // this implementation is used as browser keystore in various
+ // deployment scenarios like Webstart, JFX and applets), create
+ // a dummy password so MacOS API is happy.
+ if (password == null || password.length == 0) {
+ // Must not be a char array with only a 0, as this is an empty
+ // string.
+ if (random == null) {
+ random = new SecureRandom();
+ }
+ password = Long.toString(random.nextLong()).toCharArray();
+ }
+
Object entry = entries.get(alias.toLowerCase());
if (entry == null || !(entry instanceof KeyEntry)) {
diff --git a/src/macosx/classes/com/apple/laf/AquaBorder.java b/src/macosx/classes/com/apple/laf/AquaBorder.java
index dfb6fdd..dcc645f 100644
--- a/src/macosx/classes/com/apple/laf/AquaBorder.java
+++ b/src/macosx/classes/com/apple/laf/AquaBorder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, 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
@@ -68,8 +68,9 @@
painter.state.set(size);
}
+ @Override
public Insets getBorderInsets(final Component c) {
- return sizeVariant.margins;
+ return (Insets) sizeVariant.margins.clone();
}
protected AquaBorder deriveBorderForSize(final Size size) {
@@ -130,8 +131,10 @@
return (focusable != null && focusable instanceof JComponent && ((JComponent)focusable).hasFocus());
}
+ @Override
public boolean isBorderOpaque() { return false; }
+ @Override
public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int w, final int h) {
painter.paint(g, c, x, y, w, h);
}
diff --git a/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java b/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java
index 5345828..63ce47c 100644
--- a/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java
+++ b/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java
@@ -152,20 +152,6 @@
}
@Override
- public void focusGained(final FocusEvent e) {
- if (arrowButton != null) {
- arrowButton.repaint();
- }
- }
-
- @Override
- public void focusLost(final FocusEvent e) {
- if (arrowButton != null) {
- arrowButton.repaint();
- }
- }
-
- @Override
public void changedUpdate(final DocumentEvent e) {
editorTextChanged();
}
@@ -250,6 +236,16 @@
*/
protected FocusListener createFocusListener() {
return new BasicComboBoxUI.FocusHandler() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ super.focusGained(e);
+
+ if (arrowButton != null) {
+ arrowButton.repaint();
+ }
+ }
+
+ @Override
public void focusLost(final FocusEvent e) {
hasFocus = false;
if (!e.isTemporary()) {
@@ -262,6 +258,10 @@
if (ac != null) {
ac.firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null);
}
+
+ if (arrowButton != null) {
+ arrowButton.repaint();
+ }
}
};
}
@@ -273,7 +273,7 @@
actionMap.put("aquaSelectNext", highlightNextAction);
actionMap.put("aquaSelectPrevious", highlightPreviousAction);
- actionMap.put("aquaEnterPressed", triggerSelectionAction);
+ actionMap.put("enterPressed", triggerSelectionAction);
actionMap.put("aquaSpacePressed", toggleSelectionAction);
actionMap.put("aquaSelectHome", highlightFirstAction);
@@ -429,6 +429,7 @@
if (editor != null) {
final Rectangle editorRect = rectangleForCurrentValue();
editorRect.width += 4;
+ editorRect.height += 1;
editor.setBounds(editorRect);
}
}
diff --git a/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java b/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java
index d847bd7..6c4ee80 100644
--- a/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java
+++ b/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java
@@ -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
@@ -1089,8 +1089,15 @@
super(f);
}
- public Component getTableCellRendererComponent(final JTable list, final Object value, final boolean isSelected, final boolean cellHasFocus, final int index, final int col) {
- super.getTableCellRendererComponent(list, value, isSelected, false, index, col); // No focus border, thanks
+ public Component getTableCellRendererComponent(final JTable list,
+ final Object value,
+ final boolean isSelected,
+ final boolean cellHasFocus,
+ final int index,
+ final int col) {
+ super.getTableCellRendererComponent(list, value, isSelected, false,
+ index,
+ col); // No focus border, thanks
final File file = (File)value;
final JFileChooser fc = getFileChooser();
setText(fc.getName(file));
@@ -1105,8 +1112,14 @@
super(f);
}
- public Component getTableCellRendererComponent(final JTable list, final Object value, final boolean isSelected, final boolean cellHasFocus, final int index, final int col) {
- super.getTableCellRendererComponent(list, value, isSelected, false, index, col);
+ public Component getTableCellRendererComponent(final JTable list,
+ final Object value,
+ final boolean isSelected,
+ final boolean cellHasFocus,
+ final int index,
+ final int col) {
+ super.getTableCellRendererComponent(list, value, isSelected, false,
+ index, col);
final File file = (File)fFileList.getValueAt(index, 0);
setEnabled(isSelectableInList(file));
final DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT);
@@ -1122,14 +1135,17 @@
}
}
+ @Override
public Dimension getPreferredSize(final JComponent c) {
- return PREF_SIZE;
+ return new Dimension(PREF_WIDTH, PREF_HEIGHT);
}
+ @Override
public Dimension getMinimumSize(final JComponent c) {
- return MIN_SIZE;
+ return new Dimension(MIN_WIDTH, MIN_HEIGHT);
}
+ @Override
public Dimension getMaximumSize(final JComponent c) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
@@ -1793,12 +1809,8 @@
private static final int PREF_WIDTH = 550;
private static final int PREF_HEIGHT = 400;
- private static final Dimension PREF_SIZE = new Dimension(PREF_WIDTH, PREF_HEIGHT);
-
private static final int MIN_WIDTH = 400;
private static final int MIN_HEIGHT = 250;
- private static final Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT);
-
private static final int LIST_MIN_WIDTH = 400;
private static final int LIST_MIN_HEIGHT = 100;
private static final Dimension LIST_MIN_SIZE = new Dimension(LIST_MIN_WIDTH, LIST_MIN_HEIGHT);
diff --git a/src/macosx/classes/com/apple/laf/AquaIcon.java b/src/macosx/classes/com/apple/laf/AquaIcon.java
index 3a24c35..e8f8549 100644
--- a/src/macosx/classes/com/apple/laf/AquaIcon.java
+++ b/src/macosx/classes/com/apple/laf/AquaIcon.java
@@ -195,7 +195,7 @@
AquaPainter.create(JRSUIState.getInstance());
initIconPainter(painter);
- g.setClip(new Rectangle(x, y, width, height));
+ g.clipRect(x, y, width, height);
painter.paint(g, c, x, y, width, height);
g.dispose();
}
diff --git a/src/macosx/classes/com/apple/laf/AquaKeyBindings.java b/src/macosx/classes/com/apple/laf/AquaKeyBindings.java
index 9804826..b66e331 100644
--- a/src/macosx/classes/com/apple/laf/AquaKeyBindings.java
+++ b/src/macosx/classes/com/apple/laf/AquaKeyBindings.java
@@ -214,7 +214,7 @@
"PAGE_DOWN", "aquaSelectPageDown",
"HOME", "aquaSelectHome",
"END", "aquaSelectEnd",
- "ENTER", "aquaEnterPressed",
+ "ENTER", "enterPressed",
"UP", "aquaSelectPrevious",
"KP_UP", "aquaSelectPrevious",
"DOWN", "aquaSelectNext",
diff --git a/src/macosx/classes/com/apple/laf/AquaMenuBarBorder.java b/src/macosx/classes/com/apple/laf/AquaMenuBarBorder.java
index 389eb4c..bd5ab2b 100644
--- a/src/macosx/classes/com/apple/laf/AquaMenuBarBorder.java
+++ b/src/macosx/classes/com/apple/laf/AquaMenuBarBorder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, 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
@@ -25,46 +25,33 @@
package com.apple.laf;
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Insets;
import javax.swing.border.Border;
+import sun.swing.SwingUtilities2;
+
+/**
+ * The class represents the border of a {@code JMenuBar}.
+ */
public class AquaMenuBarBorder implements Border {
- public AquaMenuBarBorder() {
- super();
- }
- /**
- * Paints the border for the specified component with the specified
- * position and size.
- * @param c the component for which this border is being painted
- * @param g the paint graphics
- * @param x the x position of the painted border
- * @param y the y position of the painted border
- * @param width the width of the painted border
- * @param height the height of the painted border
- */
- public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) {
- // for now we don't paint a border. We let the button paint it since there
- // needs to be a strict ordering for aqua components.
- //paintButton(c, g, x, y, width, height);
+ @Override
+ public void paintBorder(final Component c, final Graphics g, final int x,
+ final int y, final int width, final int height) {
g.setColor(Color.gray);
- g.drawLine(x, y + height - 1, x + width, y + height - 1);
+ SwingUtilities2.drawHLine(g, x, x + width - 1, y + height - 1);
}
- /**
- * Returns the insets of the border.
- * @param c the component for which this border insets value applies
- */
+ @Override
public Insets getBorderInsets(final Component c) {
return new Insets(0, 0, 1, 0);
}
- /**
- * Returns whether or not the border is opaque. If the border
- * is opaque, it is responsible for filling in it's own
- * background when painting.
- */
+ @Override
public boolean isBorderOpaque() {
return false;
}
diff --git a/src/macosx/classes/com/apple/laf/AquaMenuUI.java b/src/macosx/classes/com/apple/laf/AquaMenuUI.java
index 450bf54..f56a3c6 100644
--- a/src/macosx/classes/com/apple/laf/AquaMenuUI.java
+++ b/src/macosx/classes/com/apple/laf/AquaMenuUI.java
@@ -148,11 +148,15 @@
// In Aqua, we always have a menu delay, regardless of where the menu is.
if (!(selectedPath.length > 0 && selectedPath[selectedPath.length - 1] == menu.getPopupMenu())) {
- if (menu.getDelay() == 0) {
- appendPath(getPath(), menu.getPopupMenu());
- } else {
- manager.setSelectedPath(getPath());
- setupPostTimer(menu);
+ // the condition below prevents from activating menu in other frame
+ if (!menu.isTopLevelMenu() || (selectedPath.length > 0 &&
+ selectedPath[0] == menu.getParent())) {
+ if (menu.getDelay() == 0) {
+ appendPath(getPath(), menu.getPopupMenu());
+ } else {
+ manager.setSelectedPath(getPath());
+ setupPostTimer(menu);
+ }
}
}
}
diff --git a/src/macosx/classes/com/apple/laf/AquaScrollPaneUI.java b/src/macosx/classes/com/apple/laf/AquaScrollPaneUI.java
index 3241ab1..0729321 100644
--- a/src/macosx/classes/com/apple/laf/AquaScrollPaneUI.java
+++ b/src/macosx/classes/com/apple/laf/AquaScrollPaneUI.java
@@ -29,6 +29,7 @@
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.basic.BasicScrollPaneUI;
public class AquaScrollPaneUI extends javax.swing.plaf.basic.BasicScrollPaneUI {
public static ComponentUI createUI(final JComponent x) {
@@ -39,28 +40,9 @@
return new XYMouseWheelHandler();
}
- // This is a grody hack to trick BasicScrollPaneUI into scrolling horizontally
- // when we notice that the shift key is down. This should be removed when AWT/Swing
- // becomes aware of of multi-axis scroll wheels.
- protected class XYMouseWheelHandler extends javax.swing.plaf.basic.BasicScrollPaneUI.MouseWheelHandler {
+ protected class XYMouseWheelHandler extends BasicScrollPaneUI.MouseWheelHandler {
public void mouseWheelMoved(final MouseWheelEvent e) {
- JScrollBar vScrollBar = null;
- boolean wasVisible = false;
-
- if (e.isShiftDown()) {
- vScrollBar = scrollpane.getVerticalScrollBar();
- if (vScrollBar != null) {
- wasVisible = vScrollBar.isVisible();
- vScrollBar.setVisible(false);
- }
- }
-
super.mouseWheelMoved(e);
-
- if (wasVisible) {
- vScrollBar.setVisible(true);
- }
-
// Consume the event even when the scrollBar is invisible
// see #7124320
e.consume();
diff --git a/src/macosx/classes/com/apple/laf/AquaTextFieldBorder.java b/src/macosx/classes/com/apple/laf/AquaTextFieldBorder.java
index f4e9f20..6f161b7 100644
--- a/src/macosx/classes/com/apple/laf/AquaTextFieldBorder.java
+++ b/src/macosx/classes/com/apple/laf/AquaTextFieldBorder.java
@@ -124,7 +124,7 @@
public Insets getBorderInsets(final Component c) {
if (!(c instanceof JTextComponent) || c.isOpaque()) return new InsetsUIResource(3, 7, 3, 7);
- return new InsetsUIResource(6, 7, 6, 7);
+ return new InsetsUIResource(5, 5, 5, 5);
}
protected static State getStateFor(final JTextComponent jc) {
diff --git a/src/macosx/classes/sun/awt/CGraphicsDevice.java b/src/macosx/classes/sun/awt/CGraphicsDevice.java
index 22795f3..29d90a3 100644
--- a/src/macosx/classes/sun/awt/CGraphicsDevice.java
+++ b/src/macosx/classes/sun/awt/CGraphicsDevice.java
@@ -43,7 +43,6 @@
* therefore methods, which is using this id should be ready to it.
*/
private volatile int displayID;
- private volatile Insets screenInsets;
private volatile double xResolution;
private volatile double yResolution;
private volatile int scale;
@@ -120,7 +119,13 @@
}
public Insets getScreenInsets() {
- return screenInsets;
+ // the insets are queried synchronously and are not cached
+ // since there are no Quartz or Cocoa means to receive notifications
+ // on insets changes (e.g. when the Dock is resized):
+ // the existing CGDisplayReconfigurationCallBack is not notified
+ // as well as the NSApplicationDidChangeScreenParametersNotification
+ // is fired on the Dock location changes only
+ return nativeGetScreenInsets(displayID);
}
public int getScaleFactor() {
@@ -135,7 +140,6 @@
public void displayChanged() {
xResolution = nativeGetXResolution(displayID);
yResolution = nativeGetYResolution(displayID);
- screenInsets = nativeGetScreenInsets(displayID);
scale = (int) nativeGetScaleFactor(displayID);
//TODO configs/fullscreenWindow/modes?
}
diff --git a/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java b/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java
index c3b91a2..fe85cce 100644
--- a/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java
+++ b/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java
@@ -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
@@ -132,7 +132,9 @@
@Override
public void setState(final boolean state) {
synchronized (getDelegateLock()) {
+ getDelegate().getCurrentButton().removeItemListener(this);
getDelegate().setSelected(state);
+ getDelegate().getCurrentButton().addItemListener(this);
}
repaintPeer();
}
diff --git a/src/macosx/classes/sun/lwawt/LWWindowPeer.java b/src/macosx/classes/sun/lwawt/LWWindowPeer.java
index 4655d2b..b1bf878 100644
--- a/src/macosx/classes/sun/lwawt/LWWindowPeer.java
+++ b/src/macosx/classes/sun/lwawt/LWWindowPeer.java
@@ -1295,6 +1295,12 @@
}
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+
+ if (!becomesFocused && kfmPeer.getCurrentFocusedWindow() != getTarget()) {
+ // late window focus lost event - ingoring
+ return;
+ }
+
kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
diff --git a/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java b/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java
index 859909e..f218c90 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java
@@ -161,7 +161,7 @@
}
// ignore focus "lost" native request as it may mistakenly
// deactivate active window (see 8001161)
- if (globalFocusedWindow == this && parentWindowActive) {
+ if (globalFocusedWindow == this) {
responder.handleWindowFocusEvent(parentWindowActive, null);
}
}
diff --git a/src/macosx/classes/sun/lwawt/macosx/CImage.java b/src/macosx/classes/sun/lwawt/macosx/CImage.java
index 0cbd570..bef17be 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CImage.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CImage.java
@@ -136,33 +136,35 @@
return ((DataBufferInt)bimg.getRaster().getDataBuffer()).getData();
}
+ // This is used to create a CImage from a Image
+ public CImage createFromImage(final Image image) {
+ return createFromImage(image, true);
+ }
+
public CImage createFromImageImmediately(final Image image) {
- int[] buffer = imageToArray(image, false);
-
- if (buffer == null) {
- return null;
- }
-
- return new CImage(nativeCreateNSImageFromArray(buffer, image.getWidth(null),
- image.getHeight(null)));
+ return createFromImage(image, false);
}
// This is used to create a CImage from a Image
- public CImage createFromImage(final Image image) {
+ private CImage createFromImage(final Image image, final boolean prepareImage) {
if (image instanceof MultiResolutionImage) {
List<Image> resolutionVariants
= ((MultiResolutionImage) image).getResolutionVariants();
- return createFromImages(resolutionVariants);
+ return createFromImages(resolutionVariants, prepareImage);
}
- int[] buffer = imageToArray(image, true);
+ int[] buffer = imageToArray(image, prepareImage);
if (buffer == null) {
return null;
}
return new CImage(nativeCreateNSImageFromArray(buffer, image.getWidth(null), image.getHeight(null)));
}
- public CImage createFromImages(List<Image> images) {
+ public CImage createFromImages(final List<Image> images) {
+ return createFromImages(images, true);
+ }
+
+ private CImage createFromImages(final List<Image> images, final boolean prepareImage) {
if (images == null || images.isEmpty()) {
return null;
}
@@ -175,8 +177,8 @@
num = 0;
- for (Image img : images) {
- buffers[num] = imageToArray(img, true);
+ for (final Image img : images) {
+ buffers[num] = imageToArray(img, prepareImage);
if (buffers[num] == null) {
// Unable to process the image
continue;
@@ -191,9 +193,9 @@
}
return new CImage(nativeCreateNSImageFromArrays(
- Arrays.copyOf(buffers, num),
- Arrays.copyOf(w, num),
- Arrays.copyOf(h, num)));
+ Arrays.copyOf(buffers, num),
+ Arrays.copyOf(w, num),
+ Arrays.copyOf(h, num)));
}
static int getSelectorAsInt(final String fromString) {
diff --git a/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
index 29f4639..4530fff 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
@@ -36,6 +36,10 @@
import javax.print.*;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.standard.Media;
+import javax.print.attribute.standard.MediaPrintableArea;
+import javax.print.attribute.standard.MediaSize;
+import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.PageRanges;
import sun.java2d.*;
@@ -741,4 +745,34 @@
protected void startPage(PageFormat arg0, Printable arg1, int arg2, boolean arg3) throws PrinterException {
// TODO Auto-generated method stub
}
+
+ @Override
+ protected MediaSize getMediaSize(Media media, PrintService service,
+ PageFormat page) {
+ if (media == null || !(media instanceof MediaSizeName)) {
+ return getDefaultMediaSize(page);
}
+ MediaSize size = MediaSize.getMediaSizeForName((MediaSizeName) media);
+ return size != null ? size : getDefaultMediaSize(page);
+ }
+
+ private MediaSize getDefaultMediaSize(PageFormat page){
+ final int inch = 72;
+ Paper paper = page.getPaper();
+ float width = (float) (paper.getWidth() / inch);
+ float height = (float) (paper.getHeight() / inch);
+ return new MediaSize(width, height, MediaSize.INCH);
+ }
+
+ @Override
+ protected MediaPrintableArea getDefaultPrintableArea(PageFormat page, double w, double h) {
+ final float dpi = 72.0f;
+ Paper paper = page.getPaper();
+ return new MediaPrintableArea(
+ (float) (paper.getImageableX() / dpi),
+ (float) (paper.getImageableY() / dpi),
+ (float) (paper.getImageableWidth() / dpi),
+ (float) (paper.getImageableHeight() / dpi),
+ MediaPrintableArea.INCH);
+ }
+}
\ No newline at end of file
diff --git a/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_PCM.cpp b/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_PCM.cpp
index 7b95a70..40cddfc 100644
--- a/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_PCM.cpp
+++ b/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_PCM.cpp
@@ -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
@@ -28,7 +28,6 @@
//#define USE_VERBOSE_TRACE
#include <AudioUnit/AudioUnit.h>
-#include <CoreServices/CoreServices.h>
#include <AudioToolbox/AudioConverter.h>
#include <pthread.h>
#include <math.h>
@@ -617,7 +616,7 @@
~OSX_DirectAudioDevice() {
if (audioUnit) {
- CloseComponent(audioUnit);
+ AudioComponentInstanceDispose(audioUnit);
}
if (resampler) {
delete resampler;
@@ -629,17 +628,16 @@
{
OSStatus err;
AudioUnit unit;
- UInt32 size;
- ComponentDescription desc;
+ AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = (deviceID == 0 && isSource) ? kAudioUnitSubType_DefaultOutput : kAudioUnitSubType_HALOutput;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
- Component comp = FindNextComponent(NULL, &desc);
- err = OpenAComponent(comp, &unit);
+ AudioComponent comp = AudioComponentFindNext(NULL, &desc);
+ err = AudioComponentInstanceNew(comp, &unit);
if (err) {
OS_ERROR0(err, "CreateOutputUnit:OpenAComponent");
@@ -664,7 +662,7 @@
// get real AudioDeviceID for default input device (macosx current input device)
deviceID = GetDefaultDevice(isSource);
if (!deviceID) {
- CloseComponent(unit);
+ AudioComponentInstanceDispose(unit);
return NULL;
}
}
@@ -675,7 +673,7 @@
0, &deviceID, sizeof(deviceID));
if (err) {
OS_ERROR0(err, "SetProperty (CurrentDevice)");
- CloseComponent(unit);
+ AudioComponentInstanceDispose(unit);
return NULL;
}
}
diff --git a/src/macosx/native/sun/awt/AWTView.m b/src/macosx/native/sun/awt/AWTView.m
index d98d0d3..0cba2ed 100644
--- a/src/macosx/native/sun/awt/AWTView.m
+++ b/src/macosx/native/sun/awt/AWTView.m
@@ -310,7 +310,10 @@
}
- (BOOL) performKeyEquivalent: (NSEvent *) event {
- [self deliverJavaKeyEventHelper: event];
+ // if IM is active key events should be ignored
+ if (![self hasMarkedText] && !fInPressAndHold) {
+ [self deliverJavaKeyEventHelper: event];
+ }
// Workaround for 8020209: special case for "Cmd =" and "Cmd ."
// because Cocoa calls performKeyEquivalent twice for these keystrokes
diff --git a/src/macosx/native/sun/awt/LWCToolkit.h b/src/macosx/native/sun/awt/LWCToolkit.h
index 9df44be..c3e1b53 100644
--- a/src/macosx/native/sun/awt/LWCToolkit.h
+++ b/src/macosx/native/sun/awt/LWCToolkit.h
@@ -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
@@ -28,8 +28,6 @@
#import <Cocoa/Cocoa.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>
-#import <CoreServices/CoreServices.h>
-#import <AudioToolbox/AudioToolbox.h>
#define DEBUG 1
diff --git a/src/macosx/native/sun/awt/awt.m b/src/macosx/native/sun/awt/awt.m
index 293a6c0..d36edd5 100644
--- a/src/macosx/native/sun/awt/awt.m
+++ b/src/macosx/native/sun/awt/awt.m
@@ -30,6 +30,7 @@
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
+#import "jni_util.h"
#import "NSApplicationAWT.h"
#import "PropertiesUtilities.h"
#import "ThreadUtilities.h"
@@ -436,8 +437,11 @@
}
JNIEnv* env = [ThreadUtilities getJNIEnvUncached];
jclass jc_ThreadGroupUtils = (*env)->FindClass(env, "sun/misc/ThreadGroupUtils");
+ CHECK_NULL_RETURN(jc_ThreadGroupUtils, JNI_VERSION_1_4);
jmethodID sjm_getRootThreadGroup = (*env)->GetStaticMethodID(env, jc_ThreadGroupUtils, "getRootThreadGroup", "()Ljava/lang/ThreadGroup;");
+ CHECK_NULL_RETURN(sjm_getRootThreadGroup, JNI_VERSION_1_4);
jobject rootThreadGroup = (*env)->CallStaticObjectMethod(env, jc_ThreadGroupUtils, sjm_getRootThreadGroup);
+ CHECK_NULL_RETURN(rootThreadGroup, JNI_VERSION_1_4);
[ThreadUtilities setAppkitThreadGroup:(*env)->NewGlobalRef(env, rootThreadGroup)];
// The current thread was attached in getJNIEnvUnchached.
// Detach it back. It will be reattached later if needed with a proper TG
diff --git a/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m b/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m
index c71c636..07bbd43 100644
--- a/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m
+++ b/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m
@@ -126,12 +126,30 @@
return buf;
}
+BOOL isSWTRunning() {
+ char envVar[80];
+ // If this property is present we are running SWT
+ snprintf(envVar, sizeof(envVar), "JAVA_STARTED_ON_FIRST_THREAD_%d", getpid());
+ return getenv(envVar) != NULL;
+}
+
char* SplashGetScaledImageName(const char* jar, const char* file,
float *scaleFactor) {
- NSAutoreleasePool *pool = [NSAutoreleasePool new];
*scaleFactor = 1;
+
+ if(isSWTRunning()){
+ return nil;
+ }
+
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
char* scaledFile = nil;
- float screenScaleFactor = 1;
+ __block float screenScaleFactor = 1;
+
+ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+ // initialize NSApplication and AWT stuff
+ [NSApplicationAWT sharedApplication];
+ screenScaleFactor = [SplashNSScreen() backingScaleFactor];
+ }];
if (screenScaleFactor > 1) {
NSString *fileName = [NSString stringWithUTF8String: file];
@@ -176,9 +194,12 @@
splash->screenFormat.byteOrder = 1 ? BYTE_ORDER_LSBFIRST : BYTE_ORDER_MSBFIRST;
splash->screenFormat.depthBytes = 4;
- [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^() {
- [NSApplicationAWT runAWTLoopWithApp:[NSApplicationAWT sharedApplication]];
- }];
+ // If we are running SWT we should not start a runLoop
+ if (!isSWTRunning()) {
+ [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^() {
+ [NSApplicationAWT runAWTLoopWithApp:[NSApplicationAWT sharedApplication]];
+ }];
+ }
}
void
diff --git a/src/share/classes/com/sun/crypto/provider/GHASH.java b/src/share/classes/com/sun/crypto/provider/GHASH.java
index 8b0ba28..ee747c8 100644
--- a/src/share/classes/com/sun/crypto/provider/GHASH.java
+++ b/src/share/classes/com/sun/crypto/provider/GHASH.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,9 +29,7 @@
package com.sun.crypto.provider;
-import java.util.Arrays;
-import java.security.*;
-import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
+import java.security.ProviderException;
/**
* This class represents the GHASH function defined in NIST 800-38D
@@ -44,62 +43,90 @@
*/
final class GHASH {
- private static final byte P128 = (byte) 0xe1; //reduction polynomial
-
- private static boolean getBit(byte[] b, int pos) {
- int p = pos / 8;
- pos %= 8;
- int i = (b[p] >>> (7 - pos)) & 1;
- return i != 0;
+ private static long getLong(byte[] buffer, int offset) {
+ long result = 0;
+ int end = offset + 8;
+ for (int i = offset; i < end; ++i) {
+ result = (result << 8) + (buffer[i] & 0xFF);
+ }
+ return result;
}
- private static void shift(byte[] b) {
- byte temp, temp2;
- temp2 = 0;
- for (int i = 0; i < b.length; i++) {
- temp = (byte) ((b[i] & 0x01) << 7);
- b[i] = (byte) ((b[i] & 0xff) >>> 1);
- b[i] = (byte) (b[i] | temp2);
- temp2 = temp;
+ private static void putLong(byte[] buffer, int offset, long value) {
+ int end = offset + 8;
+ for (int i = end - 1; i >= offset; --i) {
+ buffer[i] = (byte) value;
+ value >>= 8;
}
}
- // Given block X and Y, returns the muliplication of X * Y
- private static byte[] blockMult(byte[] x, byte[] y) {
- if (x.length != AES_BLOCK_SIZE || y.length != AES_BLOCK_SIZE) {
- throw new RuntimeException("illegal input sizes");
- }
- byte[] z = new byte[AES_BLOCK_SIZE];
- byte[] v = y.clone();
- // calculate Z1-Z127 and V1-V127
- for (int i = 0; i < 127; i++) {
+ private static final int AES_BLOCK_SIZE = 16;
+
+ // Multiplies state0, state1 by V0, V1.
+ private void blockMult(long V0, long V1) {
+ long Z0 = 0;
+ long Z1 = 0;
+ long X;
+
+ // Separate loops for processing state0 and state1.
+ X = state0;
+ for (int i = 0; i < 64; i++) {
// Zi+1 = Zi if bit i of x is 0
- if (getBit(x, i)) {
- for (int n = 0; n < z.length; n++) {
- z[n] ^= v[n];
- }
- }
- boolean lastBitOfV = getBit(v, 127);
- shift(v);
- if (lastBitOfV) v[0] ^= P128;
+ long mask = X >> 63;
+ Z0 ^= V0 & mask;
+ Z1 ^= V1 & mask;
+
+ // Save mask for conditional reduction below.
+ mask = (V1 << 63) >> 63;
+
+ // V = rightshift(V)
+ long carry = V0 & 1;
+ V0 = V0 >>> 1;
+ V1 = (V1 >>> 1) | (carry << 63);
+
+ // Conditional reduction modulo P128.
+ V0 ^= 0xe100000000000000L & mask;
+ X <<= 1;
}
+
+ X = state1;
+ for (int i = 64; i < 127; i++) {
+ // Zi+1 = Zi if bit i of x is 0
+ long mask = X >> 63;
+ Z0 ^= V0 & mask;
+ Z1 ^= V1 & mask;
+
+ // Save mask for conditional reduction below.
+ mask = (V1 << 63) >> 63;
+
+ // V = rightshift(V)
+ long carry = V0 & 1;
+ V0 = V0 >>> 1;
+ V1 = (V1 >>> 1) | (carry << 63);
+
+ // Conditional reduction.
+ V0 ^= 0xe100000000000000L & mask;
+ X <<= 1;
+ }
+
// calculate Z128
- if (getBit(x, 127)) {
- for (int n = 0; n < z.length; n++) {
- z[n] ^= v[n];
- }
- }
- return z;
+ long mask = X >> 63;
+ Z0 ^= V0 & mask;
+ Z1 ^= V1 & mask;
+
+ // Save result.
+ state0 = Z0;
+ state1 = Z1;
}
// hash subkey H; should not change after the object has been constructed
- private final byte[] subkeyH;
+ private final long subkeyH0, subkeyH1;
// buffer for storing hash
- private byte[] state;
+ private long state0, state1;
// variables for save/restore calls
- private byte[] stateSave = null;
+ private long stateSave0, stateSave1;
/**
* Initializes the cipher in the specified mode with the given key
@@ -114,8 +141,8 @@
if ((subkeyH == null) || subkeyH.length != AES_BLOCK_SIZE) {
throw new ProviderException("Internal error");
}
- this.subkeyH = subkeyH;
- this.state = new byte[AES_BLOCK_SIZE];
+ this.subkeyH0 = getLong(subkeyH, 0);
+ this.subkeyH1 = getLong(subkeyH, 8);
}
/**
@@ -124,31 +151,33 @@
* this object for different data w/ the same H.
*/
void reset() {
- Arrays.fill(state, (byte) 0);
+ state0 = 0;
+ state1 = 0;
}
/**
* Save the current snapshot of this GHASH object.
*/
void save() {
- stateSave = state.clone();
+ stateSave0 = state0;
+ stateSave1 = state1;
}
/**
* Restores this object using the saved snapshot.
*/
void restore() {
- state = stateSave;
+ state0 = stateSave0;
+ state1 = stateSave1;
}
private void processBlock(byte[] data, int ofs) {
if (data.length - ofs < AES_BLOCK_SIZE) {
throw new RuntimeException("need complete block");
}
- for (int n = 0; n < state.length; n++) {
- state[n] ^= data[ofs + n];
- }
- state = blockMult(state, subkeyH);
+ state0 ^= getLong(data, ofs);
+ state1 ^= getLong(data, ofs + 8);
+ blockMult(subkeyH0, subkeyH1);
}
void update(byte[] in) {
@@ -169,10 +198,10 @@
}
byte[] digest() {
- try {
- return state.clone();
- } finally {
- reset();
- }
+ byte[] result = new byte[AES_BLOCK_SIZE];
+ putLong(result, 0, state0);
+ putLong(result, 8, state1);
+ reset();
+ return result;
}
}
diff --git a/src/share/classes/com/sun/crypto/provider/JceKeyStore.java b/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
index 5d48553..cbbc54e 100644
--- a/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
+++ b/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -107,7 +107,7 @@
{
Key key = null;
- Object entry = entries.get(alias.toLowerCase());
+ Object entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
if (!((entry instanceof PrivateKeyEntry) ||
(entry instanceof SecretKeyEntry))) {
@@ -150,7 +150,7 @@
{
Certificate[] chain = null;
- Object entry = entries.get(alias.toLowerCase());
+ Object entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
if ((entry instanceof PrivateKeyEntry)
&& (((PrivateKeyEntry)entry).chain != null)) {
@@ -178,7 +178,7 @@
public Certificate engineGetCertificate(String alias) {
Certificate cert = null;
- Object entry = entries.get(alias.toLowerCase());
+ Object entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
if (entry != null) {
if (entry instanceof TrustedCertEntry) {
@@ -203,7 +203,7 @@
public Date engineGetCreationDate(String alias) {
Date date = null;
- Object entry = entries.get(alias.toLowerCase());
+ Object entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
if (entry != null) {
// We have to create a new instance of java.util.Date because
@@ -266,7 +266,7 @@
}
// store the entry
- entries.put(alias.toLowerCase(), entry);
+ entries.put(alias.toLowerCase(Locale.ENGLISH), entry);
} else {
SecretKeyEntry entry = new SecretKeyEntry();
@@ -274,7 +274,7 @@
// seal and store the key
entry.sealedKey = keyProtector.seal(key);
- entries.put(alias.toLowerCase(), entry);
+ entries.put(alias.toLowerCase(Locale.ENGLISH), entry);
}
} catch (Exception e) {
@@ -322,7 +322,7 @@
entry.chain = null;
}
- entries.put(alias.toLowerCase(), entry);
+ entries.put(alias.toLowerCase(Locale.ENGLISH), entry);
}
}
@@ -345,7 +345,7 @@
{
synchronized(entries) {
- Object entry = entries.get(alias.toLowerCase());
+ Object entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
if (entry != null) {
if (entry instanceof PrivateKeyEntry) {
throw new KeyStoreException("Cannot overwrite own "
@@ -358,7 +358,7 @@
TrustedCertEntry trustedCertEntry = new TrustedCertEntry();
trustedCertEntry.cert = cert;
trustedCertEntry.date = new Date();
- entries.put(alias.toLowerCase(), trustedCertEntry);
+ entries.put(alias.toLowerCase(Locale.ENGLISH), trustedCertEntry);
}
}
@@ -373,7 +373,7 @@
throws KeyStoreException
{
synchronized(entries) {
- entries.remove(alias.toLowerCase());
+ entries.remove(alias.toLowerCase(Locale.ENGLISH));
}
}
@@ -394,7 +394,7 @@
* @return true if the alias exists, false otherwise
*/
public boolean engineContainsAlias(String alias) {
- return entries.containsKey(alias.toLowerCase());
+ return entries.containsKey(alias.toLowerCase(Locale.ENGLISH));
}
/**
@@ -416,7 +416,7 @@
public boolean engineIsKeyEntry(String alias) {
boolean isKey = false;
- Object entry = entries.get(alias.toLowerCase());
+ Object entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
if ((entry instanceof PrivateKeyEntry)
|| (entry instanceof SecretKeyEntry)) {
isKey = true;
@@ -434,7 +434,7 @@
*/
public boolean engineIsCertificateEntry(String alias) {
boolean isCert = false;
- Object entry = entries.get(alias.toLowerCase());
+ Object entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
if (entry instanceof TrustedCertEntry) {
isCert = true;
}
diff --git a/src/share/classes/com/sun/crypto/provider/PBEKey.java b/src/share/classes/com/sun/crypto/provider/PBEKey.java
index 7264bc2..3331f78 100644
--- a/src/share/classes/com/sun/crypto/provider/PBEKey.java
+++ b/src/share/classes/com/sun/crypto/provider/PBEKey.java
@@ -28,6 +28,7 @@
import java.security.MessageDigest;
import java.security.KeyRep;
import java.security.spec.InvalidKeySpecException;
+import java.util.Locale;
import javax.crypto.SecretKey;
import javax.crypto.spec.PBEKeySpec;
@@ -92,7 +93,7 @@
for (int i = 1; i < this.key.length; i++) {
retval += this.key[i] * i;
}
- return(retval ^= getAlgorithm().toLowerCase().hashCode());
+ return(retval ^= getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode());
}
public boolean equals(Object obj) {
diff --git a/src/share/classes/com/sun/crypto/provider/PBEKeyFactory.java b/src/share/classes/com/sun/crypto/provider/PBEKeyFactory.java
index 26dd086..0c87971 100644
--- a/src/share/classes/com/sun/crypto/provider/PBEKeyFactory.java
+++ b/src/share/classes/com/sun/crypto/provider/PBEKeyFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -32,6 +32,7 @@
import javax.crypto.SecretKeyFactorySpi;
import javax.crypto.spec.PBEKeySpec;
import java.util.HashSet;
+import java.util.Locale;
/**
* This class implements a key factory for PBE keys according to PKCS#5,
@@ -56,24 +57,24 @@
static {
validTypes = new HashSet<String>(17);
- validTypes.add("PBEWithMD5AndDES".toUpperCase());
- validTypes.add("PBEWithSHA1AndDESede".toUpperCase());
- validTypes.add("PBEWithSHA1AndRC2_40".toUpperCase());
- validTypes.add("PBEWithSHA1AndRC2_128".toUpperCase());
- validTypes.add("PBEWithSHA1AndRC4_40".toUpperCase());
- validTypes.add("PBEWithSHA1AndRC4_128".toUpperCase());
+ validTypes.add("PBEWithMD5AndDES".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithSHA1AndDESede".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithSHA1AndRC2_40".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithSHA1AndRC2_128".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithSHA1AndRC4_40".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithSHA1AndRC4_128".toUpperCase(Locale.ENGLISH));
// Proprietary algorithm.
- validTypes.add("PBEWithMD5AndTripleDES".toUpperCase());
- validTypes.add("PBEWithHmacSHA1AndAES_128".toUpperCase());
- validTypes.add("PBEWithHmacSHA224AndAES_128".toUpperCase());
- validTypes.add("PBEWithHmacSHA256AndAES_128".toUpperCase());
- validTypes.add("PBEWithHmacSHA384AndAES_128".toUpperCase());
- validTypes.add("PBEWithHmacSHA512AndAES_128".toUpperCase());
- validTypes.add("PBEWithHmacSHA1AndAES_256".toUpperCase());
- validTypes.add("PBEWithHmacSHA224AndAES_256".toUpperCase());
- validTypes.add("PBEWithHmacSHA256AndAES_256".toUpperCase());
- validTypes.add("PBEWithHmacSHA384AndAES_256".toUpperCase());
- validTypes.add("PBEWithHmacSHA512AndAES_256".toUpperCase());
+ validTypes.add("PBEWithMD5AndTripleDES".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithHmacSHA1AndAES_128".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithHmacSHA224AndAES_128".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithHmacSHA256AndAES_128".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithHmacSHA384AndAES_128".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithHmacSHA512AndAES_128".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithHmacSHA1AndAES_256".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithHmacSHA224AndAES_256".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithHmacSHA256AndAES_256".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithHmacSHA384AndAES_256".toUpperCase(Locale.ENGLISH));
+ validTypes.add("PBEWithHmacSHA512AndAES_256".toUpperCase(Locale.ENGLISH));
}
public static final class PBEWithMD5AndDES
@@ -237,7 +238,7 @@
protected KeySpec engineGetKeySpec(SecretKey key, Class<?> keySpecCl)
throws InvalidKeySpecException {
if ((key instanceof SecretKey)
- && (validTypes.contains(key.getAlgorithm().toUpperCase()))
+ && (validTypes.contains(key.getAlgorithm().toUpperCase(Locale.ENGLISH)))
&& (key.getFormat().equalsIgnoreCase("RAW"))) {
// Check if requested key spec is amongst the valid ones
@@ -279,7 +280,7 @@
{
try {
if ((key != null) &&
- (validTypes.contains(key.getAlgorithm().toUpperCase())) &&
+ (validTypes.contains(key.getAlgorithm().toUpperCase(Locale.ENGLISH))) &&
(key.getFormat().equalsIgnoreCase("RAW"))) {
// Check if key originates from this factory
diff --git a/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java b/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java
index 606c15c..b2bf32a 100644
--- a/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java
+++ b/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java
@@ -31,6 +31,7 @@
import java.nio.charset.Charset;
import java.util.Arrays;
import java.security.MessageDigest;
+import java.util.Locale;
import java.security.KeyRep;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
@@ -144,7 +145,7 @@
@Override
public int hashCode() {
return Arrays.hashCode(password) * 41 +
- prf.getAlgorithm().toLowerCase().hashCode();
+ prf.getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode();
}
@Override
public boolean equals(Object obj) {
@@ -222,7 +223,7 @@
for (int i = 1; i < this.key.length; i++) {
retval += this.key[i] * i;
}
- return(retval ^= getAlgorithm().toLowerCase().hashCode());
+ return(retval ^= getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode());
}
public boolean equals(Object obj) {
diff --git a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java
index fc56076..6a33bd5 100644
--- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java
+++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -43,8 +43,6 @@
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
-import java.awt.image.SampleModel;
-import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
@@ -1048,7 +1046,13 @@
// Call the writer, who will call back for every scanline
- processImageStarted(currentImage);
+ clearAbortRequest();
+ cbLock.lock();
+ try {
+ processImageStarted(currentImage);
+ } finally {
+ cbLock.unlock();
+ }
boolean aborted = false;
@@ -1100,6 +1104,11 @@
currentImage++; // After a successful write
}
+ @Override
+ public boolean canWriteSequence() {
+ return true;
+ }
+
public void prepareWriteSequence(IIOMetadata streamMetadata)
throws IOException {
setThreadLock();
@@ -1225,6 +1234,23 @@
}
}
+ @Override
+ protected synchronized void clearAbortRequest() {
+ setThreadLock();
+ try {
+ cbLock.check();
+ if (abortRequested()) {
+ super.clearAbortRequest();
+ // reset C structures
+ resetWriter(structPointer);
+ // reset the native destination
+ setDest(structPointer);
+ }
+ } finally {
+ clearThreadLock();
+ }
+ }
+
private void resetInternalState() {
// reset C structures
resetWriter(structPointer);
diff --git a/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java b/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java
index 530cece..258e3e3 100644
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java
+++ b/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java
@@ -100,7 +100,8 @@
private static Dimension prefListSize = new Dimension(75, 150);
private static Dimension PREF_SIZE = new Dimension(435, 360);
- private static Dimension MIN_SIZE = new Dimension(200, 300);
+ private static final int MIN_WIDTH = 200;
+ private static final int MIN_HEIGHT = 300;
private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);
@@ -1038,6 +1039,7 @@
}
}
+ @Override
public Dimension getPreferredSize(JComponent c) {
Dimension prefSize = new Dimension(PREF_SIZE);
JComponent accessory = getFileChooser().getAccessory();
@@ -1053,10 +1055,12 @@
}
}
- public Dimension getMinimumSize(JComponent x) {
- return new Dimension(MIN_SIZE);
+ @Override
+ public Dimension getMinimumSize(JComponent x) {
+ return new Dimension(MIN_WIDTH, MIN_HEIGHT);
}
+ @Override
public Dimension getMaximumSize(JComponent x) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
diff --git a/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java b/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java
index ae7baa5..e6b33bc 100644
--- a/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java
+++ b/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java
@@ -1,5 +1,5 @@
/*
- * 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
@@ -65,8 +65,8 @@
private static Dimension WITH_ACCELERATOR_PREF_SIZE = new Dimension(650, 450);
private static Dimension PREF_SIZE = new Dimension(350, 450);
- private static Dimension MIN_SIZE = new Dimension(200, 300);
-
+ private static final int MIN_WIDTH = 200;
+ private static final int MIN_HEIGHT = 300;
private static Dimension PREF_ACC_SIZE = new Dimension(10, 10);
private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);
@@ -615,6 +615,7 @@
return scrollpane;
}
+ @Override
public Dimension getPreferredSize(JComponent c) {
Dimension prefSize =
(getFileChooser().getAccessory() != null) ? WITH_ACCELERATOR_PREF_SIZE : PREF_SIZE;
@@ -627,10 +628,12 @@
}
}
- public Dimension getMinimumSize(JComponent x) {
- return MIN_SIZE;
+ @Override
+ public Dimension getMinimumSize(JComponent x) {
+ return new Dimension(MIN_WIDTH, MIN_HEIGHT);
}
+ @Override
public Dimension getMaximumSize(JComponent x) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
diff --git a/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java b/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java
index b22ebf9..b9b9b91 100644
--- a/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java
+++ b/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java
@@ -93,7 +93,6 @@
private static int MIN_WIDTH = 425;
private static int MIN_HEIGHT = 245;
- private static Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT);
private static int LIST_PREF_WIDTH = 444;
private static int LIST_PREF_HEIGHT = 138;
@@ -631,6 +630,7 @@
* @return a <code>Dimension</code> specifying the preferred
* width and height of the file chooser
*/
+ @Override
public Dimension getPreferredSize(JComponent c) {
int prefWidth = PREF_SIZE.width;
Dimension d = c.getLayout().preferredLayoutSize(c);
@@ -649,8 +649,9 @@
* @return a <code>Dimension</code> specifying the minimum
* width and height of the file chooser
*/
+ @Override
public Dimension getMinimumSize(JComponent c) {
- return MIN_SIZE;
+ return new Dimension(MIN_WIDTH, MIN_HEIGHT);
}
/**
@@ -660,6 +661,7 @@
* @return a <code>Dimension</code> specifying the maximum
* width and height of the file chooser
*/
+ @Override
public Dimension getMaximumSize(JComponent c) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
diff --git a/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java b/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java
index 68379a7..54c27e9 100644
--- a/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java
+++ b/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java
@@ -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
@@ -538,6 +538,13 @@
currentFetchThread = null;
}
+ if (nr == null) {
+ if (logger.traceOn()) {
+ logger.trace("NotifFetcher-run",
+ "Recieved null object as notifs, stops fetching because the "
+ + "notification server is terminated.");
+ }
+ }
if (nr == null || shouldStop()) {
// tell that the thread is REALLY stopped
setState(STOPPED);
@@ -657,7 +664,7 @@
return null;
}
- if (shouldStop())
+ if (shouldStop() || nr == null)
return null;
startSequenceNumber = nr.getNextSequenceNumber();
diff --git a/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java b/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java
index da7e55a..0f263ad 100644
--- a/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java
+++ b/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -131,6 +131,15 @@
}
@Override
+ boolean isAssignableTo(ReferenceType type) {
+ if (type.name().equals("java.lang.Object")) {
+ // interfaces are always assignable to j.l.Object
+ return true;
+ }
+ return super.isAssignableTo(type);
+ }
+
+ @Override
List<InterfaceType> interfaces() {
return superinterfaces();
}
@@ -140,4 +149,4 @@
// method must be directly in this interface
return this.equals(method.declaringType());
}
-}
\ No newline at end of file
+}
diff --git a/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java b/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java
index 1d5a6c9..f457337 100644
--- a/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java
+++ b/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -311,7 +311,7 @@
/*
* For nonvirtual invokes, method must have a body
*/
- if ((options & INVOKE_NONVIRTUAL) != 0) {
+ if (isNonVirtual(options)) {
if (method.isAbstract()) {
throw new IllegalArgumentException("Abstract method");
}
@@ -323,7 +323,7 @@
* method argument types.
*/
ClassTypeImpl invokedClass;
- if ((options & INVOKE_NONVIRTUAL) != 0) {
+ if (isNonVirtual(options)) {
// No overrides in non-virtual invokes
invokedClass = clazz;
} else {
@@ -348,7 +348,7 @@
/*
* Only default methods allowed for nonvirtual invokes
*/
- if (!method.isDefault()) {
+ if (isNonVirtual(options) && !method.isDefault()) {
throw new IllegalArgumentException("Not a default method");
}
}
@@ -624,4 +624,8 @@
byte typeValueKey() {
return JDWP.Tag.OBJECT;
}
+
+ private static boolean isNonVirtual(int options) {
+ return (options & INVOKE_NONVIRTUAL) != 0;
+ }
}
diff --git a/src/share/classes/java/awt/Component.java b/src/share/classes/java/awt/Component.java
index 286c69a..c77c5f2 100644
--- a/src/share/classes/java/awt/Component.java
+++ b/src/share/classes/java/awt/Component.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -1669,15 +1669,6 @@
/* do nothing */
}
- /*
- * Delete references from LightweithDispatcher of a heavyweight parent
- */
- void clearLightweightDispatcherOnRemove(Component removedComponent) {
- if (parent != null) {
- parent.clearLightweightDispatcherOnRemove(removedComponent);
- }
- }
-
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>setVisible(boolean)</code>.
@@ -6180,7 +6171,7 @@
/**
* Indicates whether a class or its superclasses override coalesceEvents.
* Must be called with lock on coalesceMap and privileged.
- * @see checkCoalsecing
+ * @see checkCoalescing
*/
private static boolean isCoalesceEventsOverriden(Class<?> clazz) {
assert Thread.holdsLock(coalesceMap);
@@ -6986,8 +6977,6 @@
}
synchronized (getTreeLock()) {
- clearLightweightDispatcherOnRemove(this);
-
if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabledFor(this)) {
transferFocus(true);
}
diff --git a/src/share/classes/java/awt/Container.java b/src/share/classes/java/awt/Container.java
index db95ed7..ee8ba91 100644
--- a/src/share/classes/java/awt/Container.java
+++ b/src/share/classes/java/awt/Container.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -41,6 +41,7 @@
import java.io.PrintStream;
import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.util.EventListener;
@@ -3310,16 +3311,6 @@
}
}
- @Override
- void clearLightweightDispatcherOnRemove(Component removedComponent) {
- if (dispatcher != null) {
- dispatcher.removeReferences(removedComponent);
- } else {
- //It is a Lightweight Container, should clear parent`s Dispatcher
- super.clearLightweightDispatcherOnRemove(removedComponent);
- }
- }
-
final Container getTraversalRoot() {
if (isFocusCycleRoot()) {
return findTraversalRoot();
@@ -4413,7 +4404,9 @@
LightweightDispatcher(Container nativeContainer) {
this.nativeContainer = nativeContainer;
- mouseEventTarget = null;
+ mouseEventTarget = new WeakReference<>(null);
+ targetLastEntered = new WeakReference<>(null);
+ targetLastEnteredDT = new WeakReference<>(null);
eventMask = 0;
}
@@ -4424,9 +4417,9 @@
void dispose() {
//System.out.println("Disposing lw dispatcher");
stopListeningForOtherDrags();
- mouseEventTarget = null;
- targetLastEntered = null;
- targetLastEnteredDT = null;
+ mouseEventTarget.clear();
+ targetLastEntered.clear();
+ targetLastEnteredDT.clear();
}
/**
@@ -4513,65 +4506,62 @@
trackMouseEnterExit(mouseOver, e);
- // 4508327 : MOUSE_CLICKED should only go to the recipient of
- // the accompanying MOUSE_PRESSED, so don't reset mouseEventTarget on a
- // MOUSE_CLICKED.
- if (!isMouseGrab(e) && id != MouseEvent.MOUSE_CLICKED) {
- mouseEventTarget = (mouseOver != nativeContainer) ? mouseOver: null;
- isCleaned = false;
+ Component met = mouseEventTarget.get();
+ // 4508327 : MOUSE_CLICKED should only go to the recipient of
+ // the accompanying MOUSE_PRESSED, so don't reset mouseEventTarget on a
+ // MOUSE_CLICKED.
+ if (!isMouseGrab(e) && id != MouseEvent.MOUSE_CLICKED) {
+ met = (mouseOver != nativeContainer) ? mouseOver : null;
+ mouseEventTarget = new WeakReference<>(met);
}
- if (mouseEventTarget != null) {
+ if (met != null) {
switch (id) {
- case MouseEvent.MOUSE_ENTERED:
- case MouseEvent.MOUSE_EXITED:
- break;
- case MouseEvent.MOUSE_PRESSED:
- retargetMouseEvent(mouseEventTarget, id, e);
- break;
- case MouseEvent.MOUSE_RELEASED:
- retargetMouseEvent(mouseEventTarget, id, e);
- break;
- case MouseEvent.MOUSE_CLICKED:
- // 4508327: MOUSE_CLICKED should never be dispatched to a Component
- // other than that which received the MOUSE_PRESSED event. If the
- // mouse is now over a different Component, don't dispatch the event.
- // The previous fix for a similar problem was associated with bug
- // 4155217.
- if (mouseOver == mouseEventTarget) {
- retargetMouseEvent(mouseOver, id, e);
- }
- break;
- case MouseEvent.MOUSE_MOVED:
- retargetMouseEvent(mouseEventTarget, id, e);
- break;
- case MouseEvent.MOUSE_DRAGGED:
- if (isMouseGrab(e)) {
- retargetMouseEvent(mouseEventTarget, id, e);
- }
- break;
- case MouseEvent.MOUSE_WHEEL:
- // This may send it somewhere that doesn't have MouseWheelEvents
- // enabled. In this case, Component.dispatchEventImpl() will
- // retarget the event to a parent that DOES have the events enabled.
- if (eventLog.isLoggable(PlatformLogger.Level.FINEST) && (mouseOver != null)) {
- eventLog.finest("retargeting mouse wheel to " +
+ case MouseEvent.MOUSE_ENTERED:
+ case MouseEvent.MOUSE_EXITED:
+ break;
+ case MouseEvent.MOUSE_PRESSED:
+ retargetMouseEvent(met, id, e);
+ break;
+ case MouseEvent.MOUSE_RELEASED:
+ retargetMouseEvent(met, id, e);
+ break;
+ case MouseEvent.MOUSE_CLICKED:
+ // 4508327: MOUSE_CLICKED should never be dispatched to a Component
+ // other than that which received the MOUSE_PRESSED event. If the
+ // mouse is now over a different Component, don't dispatch the event.
+ // The previous fix for a similar problem was associated with bug
+ // 4155217.
+ if (mouseOver == met) {
+ retargetMouseEvent(mouseOver, id, e);
+ }
+ break;
+ case MouseEvent.MOUSE_MOVED:
+ retargetMouseEvent(met, id, e);
+ break;
+ case MouseEvent.MOUSE_DRAGGED:
+ if (isMouseGrab(e)) {
+ retargetMouseEvent(met, id, e);
+ }
+ break;
+ case MouseEvent.MOUSE_WHEEL:
+ // This may send it somewhere that doesn't have MouseWheelEvents
+ // enabled. In this case, Component.dispatchEventImpl() will
+ // retarget the event to a parent that DOES have the events enabled.
+ if (eventLog.isLoggable(PlatformLogger.Level.FINEST) && (mouseOver != null)) {
+ eventLog.finest("retargeting mouse wheel to " +
mouseOver.getName() + ", " +
mouseOver.getClass());
+ }
+ retargetMouseEvent(mouseOver, id, e);
+ break;
}
- retargetMouseEvent(mouseOver, id, e);
- break;
+ //Consuming of wheel events is implemented in "retargetMouseEvent".
+ if (id != MouseEvent.MOUSE_WHEEL) {
+ e.consume();
}
- //Consuming of wheel events is implemented in "retargetMouseEvent".
- if (id != MouseEvent.MOUSE_WHEEL) {
- e.consume();
}
- } else if (isCleaned && id != MouseEvent.MOUSE_WHEEL) {
- //After mouseEventTarget was removed and cleaned should consume all events
- //until new mouseEventTarget is found
- e.consume();
- }
- return e.isConsumed();
+ return e.isConsumed();
}
private boolean processDropTargetEvent(SunDropTargetEvent e) {
@@ -4628,15 +4618,16 @@
// drag has an associated drop target. MOUSE_ENTERED comes when the
// mouse is in the native container already. To propagate this event
// properly we should null out targetLastEntered.
- targetLastEnteredDT = null;
+ targetLastEnteredDT.clear();
} else if (id == MouseEvent.MOUSE_ENTERED) {
isMouseDTInNativeContainer = true;
} else if (id == MouseEvent.MOUSE_EXITED) {
isMouseDTInNativeContainer = false;
}
- targetLastEnteredDT = retargetMouseEnterExit(targetOver, e,
- targetLastEnteredDT,
+ Component tle = retargetMouseEnterExit(targetOver, e,
+ targetLastEnteredDT.get(),
isMouseDTInNativeContainer);
+ targetLastEnteredDT = new WeakReference<>(tle);
}
/*
@@ -4662,9 +4653,10 @@
isMouseInNativeContainer = false;
stopListeningForOtherDrags();
}
- targetLastEntered = retargetMouseEnterExit(targetOver, e,
- targetLastEntered,
+ Component tle = retargetMouseEnterExit(targetOver, e,
+ targetLastEntered.get(),
isMouseInNativeContainer);
+ targetLastEntered = new WeakReference<>(tle);
}
private Component retargetMouseEnterExit(Component targetOver, MouseEvent e,
@@ -4926,22 +4918,17 @@
* is null, there are currently no events being forwarded to
* a subcomponent.
*/
- private transient Component mouseEventTarget;
+ private transient WeakReference<Component> mouseEventTarget;
/**
* The last component entered by the {@code MouseEvent}.
*/
- private transient Component targetLastEntered;
+ private transient WeakReference<Component> targetLastEntered;
/**
* The last component entered by the {@code SunDropTargetEvent}.
*/
- private transient Component targetLastEnteredDT;
-
- /**
- * Indicates whether {@code mouseEventTarget} was removed and nulled
- */
- private transient boolean isCleaned;
+ private transient WeakReference<Component> targetLastEnteredDT;
/**
* Is the mouse over the native container.
@@ -4982,17 +4969,4 @@
AWTEvent.MOUSE_EVENT_MASK |
AWTEvent.MOUSE_MOTION_EVENT_MASK |
AWTEvent.MOUSE_WHEEL_EVENT_MASK;
-
- void removeReferences(Component removedComponent) {
- if (mouseEventTarget == removedComponent) {
- isCleaned = true;
- mouseEventTarget = null;
- }
- if (targetLastEntered == removedComponent) {
- targetLastEntered = null;
- }
- if (targetLastEnteredDT == removedComponent) {
- targetLastEnteredDT = null;
- }
- }
}
diff --git a/src/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java b/src/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java
index a450fec..5d7cb08 100644
--- a/src/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java
+++ b/src/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java
@@ -504,7 +504,10 @@
} else if (comp instanceof Container && comp != aContainer) {
Container cont = (Container)comp;
if (cont.isFocusTraversalPolicyProvider()) {
- return cont.getFocusTraversalPolicy().getLastComponent(cont);
+ Component retComp = cont.getFocusTraversalPolicy().getLastComponent(cont);
+ if (retComp != null) {
+ return retComp;
+ }
}
}
}
diff --git a/src/share/classes/java/awt/GraphicsEnvironment.java b/src/share/classes/java/awt/GraphicsEnvironment.java
index 66ab39a..b3c6b11 100644
--- a/src/share/classes/java/awt/GraphicsEnvironment.java
+++ b/src/share/classes/java/awt/GraphicsEnvironment.java
@@ -28,6 +28,7 @@
import java.awt.image.BufferedImage;
import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Locale;
import sun.font.FontManager;
@@ -160,42 +161,38 @@
*/
private static boolean getHeadlessProperty() {
if (headless == null) {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Object>() {
- public Object run() {
- String nm = System.getProperty("java.awt.headless");
+ AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+ String nm = System.getProperty("java.awt.headless");
- if (nm == null) {
- /* No need to ask for DISPLAY when run in a browser */
- if (System.getProperty("javaplugin.version") != null) {
- headless = defaultHeadless = Boolean.FALSE;
- } else {
- String osName = System.getProperty("os.name");
- if (osName.contains("OS X") && "sun.awt.HToolkit".equals(
- System.getProperty("awt.toolkit")))
- {
- headless = defaultHeadless = Boolean.TRUE;
- } else {
- headless = defaultHeadless =
- Boolean.valueOf(("Linux".equals(osName) ||
- "SunOS".equals(osName) ||
- "FreeBSD".equals(osName) ||
- "NetBSD".equals(osName) ||
- "OpenBSD".equals(osName)) &&
- (System.getenv("DISPLAY") == null));
- }
- }
- } else if (nm.equals("true")) {
- headless = Boolean.TRUE;
+ if (nm == null) {
+ /* No need to ask for DISPLAY when run in a browser */
+ if (System.getProperty("javaplugin.version") != null) {
+ headless = defaultHeadless = Boolean.FALSE;
} else {
- headless = Boolean.FALSE;
+ String osName = System.getProperty("os.name");
+ if (osName.contains("OS X") && "sun.awt.HToolkit".equals(
+ System.getProperty("awt.toolkit")))
+ {
+ headless = defaultHeadless = Boolean.TRUE;
+ } else {
+ final String display = System.getenv("DISPLAY");
+ headless = defaultHeadless =
+ ("Linux".equals(osName) ||
+ "SunOS".equals(osName) ||
+ "FreeBSD".equals(osName) ||
+ "NetBSD".equals(osName) ||
+ "OpenBSD".equals(osName) ||
+ "AIX".equals(osName)) &&
+ (display == null || display.trim().isEmpty());
+ }
}
- return null;
+ } else {
+ headless = Boolean.valueOf(nm);
}
- }
- );
+ return null;
+ });
}
- return headless.booleanValue();
+ return headless;
}
/**
diff --git a/src/share/classes/java/awt/MenuBar.java b/src/share/classes/java/awt/MenuBar.java
index a31745a..afaa35d 100644
--- a/src/share/classes/java/awt/MenuBar.java
+++ b/src/share/classes/java/awt/MenuBar.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -181,7 +181,7 @@
* removed from the menu bar, and replaced with the specified menu.
* @param m the menu to be set as the help menu
*/
- public void setHelpMenu(Menu m) {
+ public void setHelpMenu(final Menu m) {
synchronized (getTreeLock()) {
if (helpMenu == m) {
return;
@@ -189,11 +189,11 @@
if (helpMenu != null) {
remove(helpMenu);
}
- if (m.parent != this) {
- add(m);
- }
helpMenu = m;
if (m != null) {
+ if (m.parent != this) {
+ add(m);
+ }
m.isHelpMenu = true;
m.parent = this;
MenuBarPeer peer = (MenuBarPeer)this.peer;
@@ -242,7 +242,7 @@
* @param index the position of the menu to be removed.
* @see java.awt.MenuBar#add(java.awt.Menu)
*/
- public void remove(int index) {
+ public void remove(final int index) {
synchronized (getTreeLock()) {
Menu m = getMenu(index);
menus.removeElementAt(index);
@@ -252,6 +252,10 @@
m.parent = null;
peer.delMenu(index);
}
+ if (helpMenu == m) {
+ helpMenu = null;
+ m.isHelpMenu = false;
+ }
}
}
diff --git a/src/share/classes/java/awt/image/BufferedImage.java b/src/share/classes/java/awt/image/BufferedImage.java
index bb272aa..5ad5bd5 100644
--- a/src/share/classes/java/awt/image/BufferedImage.java
+++ b/src/share/classes/java/awt/image/BufferedImage.java
@@ -1,5 +1,5 @@
/*
- * 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
@@ -25,26 +25,23 @@
package java.awt.image;
-import java.awt.Transparency;
-import java.awt.color.ColorSpace;
import java.awt.Graphics2D;
-import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
-import java.awt.ImageCapabilities;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.Point2D;
import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Hashtable;
+import java.util.Set;
import java.util.Vector;
-import sun.awt.image.BytePackedRaster;
-import sun.awt.image.ShortComponentRaster;
import sun.awt.image.ByteComponentRaster;
+import sun.awt.image.BytePackedRaster;
import sun.awt.image.IntegerComponentRaster;
import sun.awt.image.OffScreenImageSource;
+import sun.awt.image.ShortComponentRaster;
/**
*
@@ -68,18 +65,14 @@
* @see Raster
* @see WritableRaster
*/
-
public class BufferedImage extends java.awt.Image
implements WritableRenderedImage, Transparency
{
- int imageType = TYPE_CUSTOM;
- ColorModel colorModel;
- WritableRaster raster;
- OffScreenImageSource osis;
- Hashtable properties;
-
- boolean isAlphaPremultiplied;// If true, alpha has been premultiplied in
- // color channels
+ private int imageType = TYPE_CUSTOM;
+ private ColorModel colorModel;
+ private final WritableRaster raster;
+ private OffScreenImageSource osis;
+ private Hashtable<String, Object> properties;
/**
* Image Type Constants
@@ -328,8 +321,8 @@
0x000000ff, // Blue
0x0 // Alpha
);
- raster = colorModel.createCompatibleWritableRaster(width,
- height);
+ raster = colorModel.createCompatibleWritableRaster(width,
+ height);
}
break;
@@ -355,9 +348,8 @@
true, // Alpha Premultiplied
DataBuffer.TYPE_INT
);
-
- raster = colorModel.createCompatibleWritableRaster(width,
- height);
+ raster = colorModel.createCompatibleWritableRaster(width,
+ height);
}
break;
@@ -368,8 +360,8 @@
0x0000ff00, // Green
0x00ff0000 // Blue
);
- raster = colorModel.createCompatibleWritableRaster(width,
- height);
+ raster = colorModel.createCompatibleWritableRaster(width,
+ height);
}
break;
@@ -642,7 +634,14 @@
colorModel = cm;
this.raster = raster;
- this.properties = properties;
+ if (properties != null && !properties.isEmpty()) {
+ this.properties = new Hashtable<>();
+ for (final Object key : properties.keySet()) {
+ if (key instanceof String) {
+ this.properties.put((String) key, properties.get(key));
+ }
+ }
+ }
int numBands = raster.getNumBands();
boolean isAlphaPre = cm.isAlphaPremultiplied();
final boolean isStandard = isStandard(cm, raster);
@@ -1272,7 +1271,11 @@
* or <code>null</code> if no property names are recognized.
*/
public String[] getPropertyNames() {
- return null;
+ if (properties == null || properties.isEmpty()) {
+ return null;
+ }
+ final Set<String> keys = properties.keySet();
+ return keys.toArray(new String[keys.size()]);
}
/**
diff --git a/src/share/classes/java/beans/package.html b/src/share/classes/java/beans/package.html
index 9f82346..a1e7498 100644
--- a/src/share/classes/java/beans/package.html
+++ b/src/share/classes/java/beans/package.html
@@ -1,5 +1,5 @@
<!--
- Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 1998, 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
@@ -147,8 +147,8 @@
For overview, architecture, and tutorial documentation, please see:
<ul>
- <li><a href="http://java.sun.com/docs/books/tutorial/javabeans/">JavaBeans</a>, a trail in <em>The Java Tutorial</em>.
- <li><a href="http://java.sun.com/products/jfc/tsc/articles/persistence2/">Long-Term Persistence</a>, an article in <em>The Swing Connection</em>.
+ <li><a href="http://docs.oracle.com/javase/tutorial/javabeans/">JavaBeans</a>, a trail in <em>The Java Tutorial</em>.
+ <li><a href="http://www.oracle.com/technetwork/java/persistence2-141443.html">Long-Term Persistence</a>, an article in <em>The Swing Connection</em>.
</ul>
<p>
diff --git a/src/share/classes/java/lang/Object.java b/src/share/classes/java/lang/Object.java
index d4bf7f6..bff85dd 100644
--- a/src/share/classes/java/lang/Object.java
+++ b/src/share/classes/java/lang/Object.java
@@ -453,7 +453,7 @@
"nanosecond timeout value out of range");
}
- if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
+ if (nanos > 0) {
timeout++;
}
diff --git a/src/share/classes/java/lang/String.java b/src/share/classes/java/lang/String.java
index 483d1c6..16edf70 100644
--- a/src/share/classes/java/lang/String.java
+++ b/src/share/classes/java/lang/String.java
@@ -135,7 +135,7 @@
* unnecessary since Strings are immutable.
*/
public String() {
- this.value = new char[0];
+ this.value = "".value;
}
/**
@@ -191,8 +191,14 @@
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
- if (count < 0) {
- throw new StringIndexOutOfBoundsException(count);
+ if (count <= 0) {
+ if (count < 0) {
+ throw new StringIndexOutOfBoundsException(count);
+ }
+ if (offset <= value.length) {
+ this.value = "".value;
+ return;
+ }
}
// Note: offset or count might be near -1>>>1.
if (offset > value.length - count) {
@@ -233,8 +239,14 @@
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
- if (count < 0) {
- throw new StringIndexOutOfBoundsException(count);
+ if (count <= 0) {
+ if (count < 0) {
+ throw new StringIndexOutOfBoundsException(count);
+ }
+ if (offset <= codePoints.length) {
+ this.value = "".value;
+ return;
+ }
}
// Note: offset or count might be near -1>>>1.
if (offset > codePoints.length - count) {
@@ -782,7 +794,7 @@
* subarray of {@code dst} starting at index {@code dstBegin}
* and ending at index:
* <blockquote><pre>
- * dstbegin + (srcEnd-srcBegin) - 1
+ * dstBegin + (srcEnd-srcBegin) - 1
* </pre></blockquote>
*
* @param srcBegin index of the first character in the string
@@ -827,7 +839,7 @@
* dst} starting at index {@code dstBegin} and ending at index:
*
* <blockquote><pre>
- * dstbegin + (srcEnd-srcBegin) - 1
+ * dstBegin + (srcEnd-srcBegin) - 1
* </pre></blockquote>
*
* @deprecated This method does not properly convert characters into
diff --git a/src/share/classes/java/lang/invoke/DirectMethodHandle.java b/src/share/classes/java/lang/invoke/DirectMethodHandle.java
index e9d2526..cabd071 100644
--- a/src/share/classes/java/lang/invoke/DirectMethodHandle.java
+++ b/src/share/classes/java/lang/invoke/DirectMethodHandle.java
@@ -31,7 +31,6 @@
import sun.invoke.util.VerifyAccess;
import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.LambdaForm.*;
-import static java.lang.invoke.LambdaForm.BasicType.*;
import static java.lang.invoke.MethodTypeForm.*;
import static java.lang.invoke.MethodHandleStatics.*;
import java.lang.ref.WeakReference;
diff --git a/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java b/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
index 752c097..47357db 100644
--- a/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
+++ b/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
@@ -285,6 +285,7 @@
// Forward the SAM method
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, samMethodName,
samMethodType.toMethodDescriptorString(), null, null);
+ mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
new ForwardingMethodGenerator(mv).generate(samMethodType);
// Forward the bridges
@@ -292,6 +293,7 @@
for (MethodType mt : additionalBridges) {
mv = cw.visitMethod(ACC_PUBLIC|ACC_BRIDGE, samMethodName,
mt.toMethodDescriptorString(), null, null);
+ mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
new ForwardingMethodGenerator(mv).generate(mt);
}
}
diff --git a/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
index 6e8d091..d9c6f0f 100644
--- a/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
+++ b/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
@@ -56,9 +56,11 @@
private static final String OBJ = "java/lang/Object";
private static final String OBJARY = "[Ljava/lang/Object;";
+ private static final String MH_SIG = "L" + MH + ";";
private static final String LF_SIG = "L" + LF + ";";
private static final String LFN_SIG = "L" + LFN + ";";
private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";";
+ private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V";
private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";";
/** Name of its super class*/
@@ -616,6 +618,15 @@
return g.loadMethod(g.generateCustomizedCodeBytes());
}
+ /** Generates code to check that actual receiver and LambdaForm matches */
+ private boolean checkActualReceiver() {
+ // Expects MethodHandle on the stack and actual receiver MethodHandle in slot #0
+ mv.visitInsn(Opcodes.DUP);
+ mv.visitVarInsn(Opcodes.ALOAD, localsMap[0]);
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "assertSame", LLV_SIG, false);
+ return true;
+ }
+
/**
* Generate an invoker method for the passed {@link LambdaForm}.
*/
@@ -635,6 +646,16 @@
mv.visitAnnotation("Ljava/lang/invoke/DontInline;", true);
}
+ if (lambdaForm.customized != null) {
+ // Since LambdaForm is customized for a particular MethodHandle, it's safe to substitute
+ // receiver MethodHandle (at slot #0) with an embedded constant and use it instead.
+ // It enables more efficient code generation in some situations, since embedded constants
+ // are compile-time constants for JIT compiler.
+ mv.visitLdcInsn(constantPlaceholder(lambdaForm.customized));
+ mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
+ assert(checkActualReceiver()); // expects MethodHandle on top of the stack
+ mv.visitVarInsn(Opcodes.ASTORE, localsMap[0]);
+ }
// iterate over the form's names, generating bytecode instructions for each
// start iterating at the first name following the arguments
diff --git a/src/share/classes/java/lang/invoke/Invokers.java b/src/share/classes/java/lang/invoke/Invokers.java
index 14aef1b..e09dc36 100644
--- a/src/share/classes/java/lang/invoke/Invokers.java
+++ b/src/share/classes/java/lang/invoke/Invokers.java
@@ -247,6 +247,7 @@
int nameCursor = OUTARG_LIMIT;
final int MTYPE_ARG = customized ? -1 : nameCursor++; // might be last in-argument
final int CHECK_TYPE = nameCursor++;
+ final int CHECK_CUSTOM = (CUSTOMIZE_THRESHOLD >= 0) ? nameCursor++ : -1;
final int LINKER_CALL = nameCursor++;
MethodType invokerFormType = mtype.invokerType();
if (isLinker) {
@@ -279,6 +280,9 @@
// mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*)
outArgs[0] = names[CHECK_TYPE];
}
+ if (CHECK_CUSTOM != -1) {
+ names[CHECK_CUSTOM] = new Name(NF_checkCustomized, names[CALL_MH]);
+ }
names[LINKER_CALL] = new Name(outCallType, outArgs);
lform = new LambdaForm(debugName, INARG_LIMIT, names);
if (isLinker)
@@ -386,11 +390,32 @@
return ((CallSite)site).getTarget();
}
+ /*non-public*/ static
+ @ForceInline
+ void checkCustomized(Object o) {
+ MethodHandle mh = (MethodHandle)o;
+ if (mh.form.customized == null) {
+ maybeCustomize(mh);
+ }
+ }
+
+ /*non-public*/ static
+ @DontInline
+ void maybeCustomize(MethodHandle mh) {
+ byte count = mh.customizationCount;
+ if (count >= CUSTOMIZE_THRESHOLD) {
+ mh.customize();
+ } else {
+ mh.customizationCount = (byte)(count+1);
+ }
+ }
+
// Local constant functions:
private static final NamedFunction
NF_checkExactType,
NF_checkGenericType,
- NF_getCallSiteTarget;
+ NF_getCallSiteTarget,
+ NF_checkCustomized;
static {
try {
NamedFunction nfs[] = {
@@ -399,7 +424,9 @@
NF_checkGenericType = new NamedFunction(Invokers.class
.getDeclaredMethod("checkGenericType", Object.class, Object.class)),
NF_getCallSiteTarget = new NamedFunction(Invokers.class
- .getDeclaredMethod("getCallSiteTarget", Object.class))
+ .getDeclaredMethod("getCallSiteTarget", Object.class)),
+ NF_checkCustomized = new NamedFunction(Invokers.class
+ .getDeclaredMethod("checkCustomized", Object.class))
};
for (NamedFunction nf : nfs) {
// Each nf must be statically invocable or we get tied up in our bootstraps.
diff --git a/src/share/classes/java/lang/invoke/LambdaForm.java b/src/share/classes/java/lang/invoke/LambdaForm.java
index 2129f86..5c44107 100644
--- a/src/share/classes/java/lang/invoke/LambdaForm.java
+++ b/src/share/classes/java/lang/invoke/LambdaForm.java
@@ -120,12 +120,14 @@
final int arity;
final int result;
final boolean forceInline;
+ final MethodHandle customized;
@Stable final Name[] names;
final String debugName;
MemberName vmentry; // low-level behavior, or null if not yet prepared
private boolean isCompiled;
- volatile Object transformCache; // managed by LambdaFormEditor
+ // Either a LambdaForm cache (managed by LambdaFormEditor) or a link to uncustomized version (for customized LF)
+ volatile Object transformCache;
public static final int VOID_RESULT = -1, LAST_RESULT = -2;
@@ -244,16 +246,17 @@
LambdaForm(String debugName,
int arity, Name[] names, int result) {
- this(debugName, arity, names, result, true);
+ this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null);
}
LambdaForm(String debugName,
- int arity, Name[] names, int result, boolean forceInline) {
+ int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) {
assert(namesOK(arity, names));
this.arity = arity;
this.result = fixResult(result, names);
this.names = names.clone();
this.debugName = fixDebugName(debugName);
this.forceInline = forceInline;
+ this.customized = customized;
int maxOutArity = normalize();
if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) {
// Cannot use LF interpreter on very high arity expressions.
@@ -263,21 +266,21 @@
}
LambdaForm(String debugName,
int arity, Name[] names) {
- this(debugName, arity, names, LAST_RESULT, true);
+ this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null);
}
LambdaForm(String debugName,
int arity, Name[] names, boolean forceInline) {
- this(debugName, arity, names, LAST_RESULT, forceInline);
+ this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null);
}
LambdaForm(String debugName,
Name[] formals, Name[] temps, Name result) {
this(debugName,
- formals.length, buildNames(formals, temps, result), LAST_RESULT, true);
+ formals.length, buildNames(formals, temps, result), LAST_RESULT, /*forceInline=*/true, /*customized=*/null);
}
LambdaForm(String debugName,
Name[] formals, Name[] temps, Name result, boolean forceInline) {
this(debugName,
- formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline);
+ formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline, /*customized=*/null);
}
private static Name[] buildNames(Name[] formals, Name[] temps, Name result) {
@@ -291,10 +294,6 @@
}
private LambdaForm(String sig) {
- this(sig, true);
- }
-
- private LambdaForm(String sig, boolean forceInline) {
// Make a blank lambda form, which returns a constant zero or null.
// It is used as a template for managing the invocation of similar forms that are non-empty.
// Called only from getPreparedForm.
@@ -303,7 +302,8 @@
this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity);
this.names = buildEmptyNames(arity, sig);
this.debugName = "LF.zero";
- this.forceInline = forceInline;
+ this.forceInline = true;
+ this.customized = null;
assert(nameRefsAreLegal());
assert(isEmpty());
assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature();
@@ -375,6 +375,31 @@
return true;
}
+ /** Customize LambdaForm for a particular MethodHandle */
+ LambdaForm customize(MethodHandle mh) {
+ LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh);
+ if (COMPILE_THRESHOLD > 0 && isCompiled) {
+ // If shared LambdaForm has been compiled, compile customized version as well.
+ customForm.compileToBytecode();
+ }
+ customForm.transformCache = this; // LambdaFormEditor should always use uncustomized form.
+ return customForm;
+ }
+
+ /** Get uncustomized flavor of the LambdaForm */
+ LambdaForm uncustomize() {
+ if (customized == null) {
+ return this;
+ }
+ assert(transformCache != null); // Customized LambdaForm should always has a link to uncustomized version.
+ LambdaForm uncustomizedForm = (LambdaForm)transformCache;
+ if (COMPILE_THRESHOLD > 0 && isCompiled) {
+ // If customized LambdaForm has been compiled, compile uncustomized version as well.
+ uncustomizedForm.compileToBytecode();
+ }
+ return uncustomizedForm;
+ }
+
/** Renumber and/or replace params so that they are interned and canonically numbered.
* @return maximum argument list length among the names (since we have to pass over them anyway)
*/
@@ -417,8 +442,8 @@
for (int i = arity; i < names.length; i++) {
names[i].internArguments();
}
- assert(nameRefsAreLegal());
}
+ assert(nameRefsAreLegal());
return maxOutArity;
}
diff --git a/src/share/classes/java/lang/invoke/LambdaFormEditor.java b/src/share/classes/java/lang/invoke/LambdaFormEditor.java
index 1c23e94..7bc2dfb 100644
--- a/src/share/classes/java/lang/invoke/LambdaFormEditor.java
+++ b/src/share/classes/java/lang/invoke/LambdaFormEditor.java
@@ -51,7 +51,10 @@
static LambdaFormEditor lambdaFormEditor(LambdaForm lambdaForm) {
// TO DO: Consider placing intern logic here, to cut down on duplication.
// lambdaForm = findPreexistingEquivalent(lambdaForm)
- return new LambdaFormEditor(lambdaForm);
+
+ // Always use uncustomized version for editing.
+ // It helps caching and customized LambdaForms reuse transformCache field to keep a link to uncustomized version.
+ return new LambdaFormEditor(lambdaForm.uncustomize());
}
/** A description of a cached transform, possibly associated with the result of the transform.
diff --git a/src/share/classes/java/lang/invoke/MethodHandle.java b/src/share/classes/java/lang/invoke/MethodHandle.java
index 9b586a3..7973064 100644
--- a/src/share/classes/java/lang/invoke/MethodHandle.java
+++ b/src/share/classes/java/lang/invoke/MethodHandle.java
@@ -434,6 +434,8 @@
// form is not private so that invokers can easily fetch it
/*private*/ MethodHandle asTypeCache;
// asTypeCache is not private so that invokers can easily fetch it
+ /*non-public*/ byte customizationCount;
+ // customizationCount should be accessible from invokers
/**
* Reports the type of this method handle.
@@ -454,9 +456,9 @@
type.getClass(); // explicit NPE
form.getClass(); // explicit NPE
this.type = type;
- this.form = form;
+ this.form = form.uncustomize();
- form.prepare(); // TO DO: Try to delay this step until just before invocation.
+ this.form.prepare(); // TO DO: Try to delay this step until just before invocation.
}
/**
@@ -1425,12 +1427,24 @@
*/
/*non-public*/
void updateForm(LambdaForm newForm) {
+ assert(newForm.customized == null || newForm.customized == this);
if (form == newForm) return;
newForm.prepare(); // as in MethodHandle.<init>
UNSAFE.putObject(this, FORM_OFFSET, newForm);
UNSAFE.fullFence();
}
+ /** Craft a LambdaForm customized for this particular MethodHandle */
+ /*non-public*/
+ void customize() {
+ if (form.customized == null) {
+ LambdaForm newForm = form.customize(this);
+ updateForm(newForm);
+ } else {
+ assert(form.customized == this);
+ }
+ }
+
private static final long FORM_OFFSET;
static {
try {
diff --git a/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/src/share/classes/java/lang/invoke/MethodHandleImpl.java
index 8812b6d..a339e17 100644
--- a/src/share/classes/java/lang/invoke/MethodHandleImpl.java
+++ b/src/share/classes/java/lang/invoke/MethodHandleImpl.java
@@ -597,6 +597,7 @@
static final NamedFunction NF_checkSpreadArgument;
static final NamedFunction NF_guardWithCatch;
static final NamedFunction NF_throwException;
+ static final NamedFunction NF_profileBoolean;
static final MethodHandle MH_castReference;
static final MethodHandle MH_selectAlternative;
@@ -614,10 +615,12 @@
NF_guardWithCatch = new NamedFunction(MHI.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
MethodHandle.class, Object[].class));
NF_throwException = new NamedFunction(MHI.getDeclaredMethod("throwException", Throwable.class));
+ NF_profileBoolean = new NamedFunction(MHI.getDeclaredMethod("profileBoolean", boolean.class, int[].class));
NF_checkSpreadArgument.resolve();
NF_guardWithCatch.resolve();
NF_throwException.resolve();
+ NF_profileBoolean.resolve();
MH_castReference = IMPL_LOOKUP.findStatic(MHI, "castReference",
MethodType.methodType(Object.class, Class.class, Object.class));
@@ -697,7 +700,26 @@
@LambdaForm.Hidden
static
MethodHandle selectAlternative(boolean testResult, MethodHandle target, MethodHandle fallback) {
- return testResult ? target : fallback;
+ if (testResult) {
+ return target;
+ } else {
+ return fallback;
+ }
+ }
+
+ // Intrinsified by C2. Counters are used during parsing to calculate branch frequencies.
+ @LambdaForm.Hidden
+ static
+ boolean profileBoolean(boolean result, int[] counters) {
+ // Profile is int[2] where [0] and [1] correspond to false and true occurrences respectively.
+ int idx = result ? 1 : 0;
+ try {
+ counters[idx] = Math.addExact(counters[idx], 1);
+ } catch (ArithmeticException e) {
+ // Avoid continuous overflow by halving the problematic count.
+ counters[idx] = counters[idx] / 2;
+ }
+ return result;
}
static
@@ -708,13 +730,18 @@
assert(test.type().equals(type.changeReturnType(boolean.class)) && fallback.type().equals(type));
MethodType basicType = type.basicType();
LambdaForm form = makeGuardWithTestForm(basicType);
- BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL();
BoundMethodHandle mh;
-
try {
- mh = (BoundMethodHandle)
- data.constructor().invokeBasic(type, form,
- (Object) test, (Object) profile(target), (Object) profile(fallback));
+ if (PROFILE_GWT) {
+ int[] counts = new int[2];
+ mh = (BoundMethodHandle)
+ BoundMethodHandle.speciesData_LLLL().constructor().invokeBasic(type, form,
+ (Object) test, (Object) profile(target), (Object) profile(fallback), counts);
+ } else {
+ mh = (BoundMethodHandle)
+ BoundMethodHandle.speciesData_LLL().constructor().invokeBasic(type, form,
+ (Object) test, (Object) profile(target), (Object) profile(fallback));
+ }
} catch (Throwable ex) {
throw uncaughtException(ex);
}
@@ -800,7 +827,7 @@
MethodHandle wrapper;
if (isCounting) {
LambdaForm lform;
- lform = countingFormProducer.apply(target);
+ lform = countingFormProducer.apply(newTarget);
wrapper = new CountingWrapper(newTarget, lform, countingFormProducer, nonCountingFormProducer, DONT_INLINE_THRESHOLD);
} else {
wrapper = newTarget; // no need for a counting wrapper anymore
@@ -856,7 +883,10 @@
final int GET_TEST = nameCursor++;
final int GET_TARGET = nameCursor++;
final int GET_FALLBACK = nameCursor++;
+ final int GET_COUNTERS = PROFILE_GWT ? nameCursor++ : -1;
final int CALL_TEST = nameCursor++;
+ final int PROFILE = (GET_COUNTERS != -1) ? nameCursor++ : -1;
+ final int TEST = nameCursor-1; // previous statement: either PROFILE or CALL_TEST
final int SELECT_ALT = nameCursor++;
final int CALL_TARGET = nameCursor++;
assert(CALL_TARGET == SELECT_ALT+1); // must be true to trigger IBG.emitSelectAlternative
@@ -864,12 +894,16 @@
MethodType lambdaType = basicType.invokerType();
Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
- BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL();
+ BoundMethodHandle.SpeciesData data =
+ (GET_COUNTERS != -1) ? BoundMethodHandle.speciesData_LLLL()
+ : BoundMethodHandle.speciesData_LLL();
names[THIS_MH] = names[THIS_MH].withConstraint(data);
names[GET_TEST] = new Name(data.getterFunction(0), names[THIS_MH]);
names[GET_TARGET] = new Name(data.getterFunction(1), names[THIS_MH]);
names[GET_FALLBACK] = new Name(data.getterFunction(2), names[THIS_MH]);
-
+ if (GET_COUNTERS != -1) {
+ names[GET_COUNTERS] = new Name(data.getterFunction(3), names[THIS_MH]);
+ }
Object[] invokeArgs = Arrays.copyOfRange(names, 0, ARG_LIMIT, Object[].class);
// call test
@@ -877,15 +911,18 @@
invokeArgs[0] = names[GET_TEST];
names[CALL_TEST] = new Name(testType, invokeArgs);
+ // profile branch
+ if (PROFILE != -1) {
+ names[PROFILE] = new Name(Lazy.NF_profileBoolean, names[CALL_TEST], names[GET_COUNTERS]);
+ }
// call selectAlternative
- names[SELECT_ALT] = new Name(Lazy.MH_selectAlternative, names[CALL_TEST],
- names[GET_TARGET], names[GET_FALLBACK]);
+ names[SELECT_ALT] = new Name(Lazy.MH_selectAlternative, names[TEST], names[GET_TARGET], names[GET_FALLBACK]);
// call target or fallback
invokeArgs[0] = names[SELECT_ALT];
names[CALL_TARGET] = new Name(basicType, invokeArgs);
- lform = new LambdaForm("guard", lambdaType.parameterCount(), names);
+ lform = new LambdaForm("guard", lambdaType.parameterCount(), names, /*forceInline=*/true);
return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWT, lform);
}
@@ -1615,4 +1652,13 @@
assert(elemType.isPrimitive());
return Lazy.MH_copyAsPrimitiveArray.bindTo(Wrapper.forPrimitiveType(elemType));
}
+
+ /*non-public*/ static void assertSame(Object mh1, Object mh2) {
+ if (mh1 != mh2) {
+ String msg = String.format("mh1 != mh2: mh1 = %s (form: %s); mh2 = %s (form: %s)",
+ mh1, ((MethodHandle)mh1).form,
+ mh2, ((MethodHandle)mh2).form);
+ throw newInternalError(msg);
+ }
+ }
}
diff --git a/src/share/classes/java/lang/invoke/MethodHandleStatics.java b/src/share/classes/java/lang/invoke/MethodHandleStatics.java
index 335a322..144de11 100644
--- a/src/share/classes/java/lang/invoke/MethodHandleStatics.java
+++ b/src/share/classes/java/lang/invoke/MethodHandleStatics.java
@@ -48,9 +48,11 @@
static final int COMPILE_THRESHOLD;
static final int DONT_INLINE_THRESHOLD;
static final int PROFILE_LEVEL;
+ static final boolean PROFILE_GWT;
+ static final int CUSTOMIZE_THRESHOLD;
static {
- final Object[] values = new Object[7];
+ final Object[] values = new Object[9];
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
@@ -60,6 +62,8 @@
values[4] = Integer.getInteger("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", 0);
values[5] = Integer.getInteger("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", 30);
values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0);
+ values[7] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true"));
+ values[8] = Integer.getInteger("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", 127);
return null;
}
});
@@ -70,6 +74,12 @@
COMPILE_THRESHOLD = (Integer) values[4];
DONT_INLINE_THRESHOLD = (Integer) values[5];
PROFILE_LEVEL = (Integer) values[6];
+ PROFILE_GWT = (Boolean) values[7];
+ CUSTOMIZE_THRESHOLD = (Integer) values[8];
+
+ if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
+ throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
+ }
}
/** Tell if any of the debugging switches are turned on.
diff --git a/src/share/classes/java/math/BigDecimal.java b/src/share/classes/java/math/BigDecimal.java
index c17b8b7..cab8480 100644
--- a/src/share/classes/java/math/BigDecimal.java
+++ b/src/share/classes/java/math/BigDecimal.java
@@ -4801,41 +4801,61 @@
if (dividendHi >= divisor) {
return null;
}
+
final int shift = Long.numberOfLeadingZeros(divisor);
divisor <<= shift;
final long v1 = divisor >>> 32;
final long v0 = divisor & LONG_MASK;
- long q1, q0;
- long r_tmp;
-
long tmp = dividendLo << shift;
long u1 = tmp >>> 32;
long u0 = tmp & LONG_MASK;
tmp = (dividendHi << shift) | (dividendLo >>> 64 - shift);
long u2 = tmp & LONG_MASK;
- tmp = divWord(tmp,v1);
- q1 = tmp & LONG_MASK;
- r_tmp = tmp >>> 32;
+ long q1, r_tmp;
+ if (v1 == 1) {
+ q1 = tmp;
+ r_tmp = 0;
+ } else if (tmp >= 0) {
+ q1 = tmp / v1;
+ r_tmp = tmp - q1 * v1;
+ } else {
+ long[] rq = divRemNegativeLong(tmp, v1);
+ q1 = rq[1];
+ r_tmp = rq[0];
+ }
+
while(q1 >= DIV_NUM_BASE || unsignedLongCompare(q1*v0, make64(r_tmp, u1))) {
q1--;
r_tmp += v1;
if (r_tmp >= DIV_NUM_BASE)
break;
}
+
tmp = mulsub(u2,u1,v1,v0,q1);
u1 = tmp & LONG_MASK;
- tmp = divWord(tmp,v1);
- q0 = tmp & LONG_MASK;
- r_tmp = tmp >>> 32;
+ long q0;
+ if (v1 == 1) {
+ q0 = tmp;
+ r_tmp = 0;
+ } else if (tmp >= 0) {
+ q0 = tmp / v1;
+ r_tmp = tmp - q0 * v1;
+ } else {
+ long[] rq = divRemNegativeLong(tmp, v1);
+ q0 = rq[1];
+ r_tmp = rq[0];
+ }
+
while(q0 >= DIV_NUM_BASE || unsignedLongCompare(q0*v0,make64(r_tmp,u0))) {
q0--;
r_tmp += v1;
if (r_tmp >= DIV_NUM_BASE)
break;
}
+
if((int)q1 < 0) {
// result (which is positive and unsigned here)
// can't fit into long due to sign bit is used for value
@@ -4858,10 +4878,13 @@
}
}
}
+
long q = make64(q1,q0);
q*=sign;
+
if (roundingMode == ROUND_DOWN && scale == preferredScale)
return valueOf(q, scale);
+
long r = mulsub(u1, u0, v1, v0, q0) >>> shift;
if (r != 0) {
boolean increment = needIncrement(divisor >>> shift, roundingMode, sign, q, r);
@@ -4904,28 +4927,35 @@
}
}
- private static long divWord(long n, long dLong) {
- long r;
- long q;
- if (dLong == 1) {
- q = (int)n;
- return (q & LONG_MASK);
- }
+ /**
+ * Calculate the quotient and remainder of dividing a negative long by
+ * another long.
+ *
+ * @param n the numerator; must be negative
+ * @param d the denominator; must not be unity
+ * @return a two-element {@long} array with the remainder and quotient in
+ * the initial and final elements, respectively
+ */
+ private static long[] divRemNegativeLong(long n, long d) {
+ assert n < 0 : "Non-negative numerator " + n;
+ assert d != 1 : "Unity denominator";
+
// Approximate the quotient and remainder
- q = (n >>> 1) / (dLong >>> 1);
- r = n - q*dLong;
+ long q = (n >>> 1) / (d >>> 1);
+ long r = n - q * d;
// Correct the approximation
while (r < 0) {
- r += dLong;
+ r += d;
q--;
}
- while (r >= dLong) {
- r -= dLong;
+ while (r >= d) {
+ r -= d;
q++;
}
- // n - q*dlong == r && 0 <= r <dLong, hence we're done.
- return (r << 32) | (q & LONG_MASK);
+
+ // n - q*d == r && 0 <= r < d, hence we're done.
+ return new long[] {r, q};
}
private static long make64(long hi, long lo) {
diff --git a/src/share/classes/java/security/AccessControlContext.java b/src/share/classes/java/security/AccessControlContext.java
index 1805aaf..8862b3d 100644
--- a/src/share/classes/java/security/AccessControlContext.java
+++ b/src/share/classes/java/security/AccessControlContext.java
@@ -1,5 +1,5 @@
/*
- * 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
@@ -172,9 +172,24 @@
public AccessControlContext(AccessControlContext acc,
DomainCombiner combiner) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(SecurityConstants.CREATE_ACC_PERMISSION);
+ this(acc, combiner, false);
+ }
+
+ /**
+ * package private to allow calls from ProtectionDomain without performing
+ * the security check for {@linkplain SecurityConstants.CREATE_ACC_PERMISSION}
+ * permission
+ */
+ AccessControlContext(AccessControlContext acc,
+ DomainCombiner combiner,
+ boolean preauthorized) {
+ if (!preauthorized) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(SecurityConstants.CREATE_ACC_PERMISSION);
+ this.isAuthorized = true;
+ }
+ } else {
this.isAuthorized = true;
}
diff --git a/src/share/classes/java/security/ProtectionDomain.java b/src/share/classes/java/security/ProtectionDomain.java
index ed57ce9..5a5ed35 100644
--- a/src/share/classes/java/security/ProtectionDomain.java
+++ b/src/share/classes/java/security/ProtectionDomain.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -25,6 +25,7 @@
package java.security;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
@@ -59,35 +60,44 @@
*/
public class ProtectionDomain {
+ private static class JavaSecurityAccessImpl implements JavaSecurityAccess {
+
+ private JavaSecurityAccessImpl() {
+ }
+
+ @Override
+ public <T> T doIntersectionPrivilege(
+ PrivilegedAction<T> action,
+ final AccessControlContext stack,
+ final AccessControlContext context) {
+ if (action == null) {
+ throw new NullPointerException();
+ }
+
+ return AccessController.doPrivileged(
+ action,
+ getCombinedACC(context, stack)
+ );
+ }
+
+ @Override
+ public <T> T doIntersectionPrivilege(
+ PrivilegedAction<T> action,
+ AccessControlContext context) {
+ return doIntersectionPrivilege(action,
+ AccessController.getContext(), context);
+ }
+
+ private static AccessControlContext getCombinedACC(AccessControlContext context, AccessControlContext stack) {
+ AccessControlContext acc = new AccessControlContext(context, stack.getCombiner(), true);
+
+ return new AccessControlContext(stack.getContext(), acc).optimize();
+ }
+ }
static {
// Set up JavaSecurityAccess in SharedSecrets
- SharedSecrets.setJavaSecurityAccess(
- new JavaSecurityAccess() {
- public <T> T doIntersectionPrivilege(
- PrivilegedAction<T> action,
- final AccessControlContext stack,
- final AccessControlContext context)
- {
- if (action == null) {
- throw new NullPointerException();
- }
- return AccessController.doPrivileged(
- action,
- new AccessControlContext(
- stack.getContext(), context).optimize()
- );
- }
-
- public <T> T doIntersectionPrivilege(
- PrivilegedAction<T> action,
- AccessControlContext context)
- {
- return doIntersectionPrivilege(action,
- AccessController.getContext(), context);
- }
- }
- );
+ SharedSecrets.setJavaSecurityAccess(new JavaSecurityAccessImpl());
}
/* CodeSource */
@@ -447,24 +457,37 @@
/**
* Used for storing ProtectionDomains as keys in a Map.
*/
- final class Key {}
+ final static class Key {}
+
+ // A cache of ProtectionDomains and their Permissions
+ private static class PDCache implements ProtectionDomainCache {
+ // We must wrap the PermissionCollection in a WeakReference as there
+ // are some PermissionCollections which contain strong references
+ // back to a ProtectionDomain and otherwise would never be removed
+ // from the WeakHashMap
+ private final Map<Key, WeakReference<PermissionCollection>>
+ map = new WeakHashMap<>();
+
+ @Override
+ public synchronized void put(ProtectionDomain pd,
+ PermissionCollection pc) {
+ map.put(pd == null ? null : pd.key, new WeakReference<>(pc));
+ }
+
+ @Override
+ public synchronized PermissionCollection get(ProtectionDomain pd) {
+ WeakReference<PermissionCollection> ref =
+ map.get(pd == null ? null : pd.key);
+ return ref == null ? null : ref.get();
+ }
+ }
static {
SharedSecrets.setJavaSecurityProtectionDomainAccess(
new JavaSecurityProtectionDomainAccess() {
+ @Override
public ProtectionDomainCache getProtectionDomainCache() {
- return new ProtectionDomainCache() {
- private final Map<Key, PermissionCollection> map =
- Collections.synchronizedMap
- (new WeakHashMap<Key, PermissionCollection>());
- public void put(ProtectionDomain pd,
- PermissionCollection pc) {
- map.put((pd == null ? null : pd.key), pc);
- }
- public PermissionCollection get(ProtectionDomain pd) {
- return pd == null ? map.get(null) : map.get(pd.key);
- }
- };
+ return new PDCache();
}
});
}
diff --git a/src/share/classes/java/security/cert/X509CertSelector.java b/src/share/classes/java/security/cert/X509CertSelector.java
index aae32c9..4a1ff7e 100644
--- a/src/share/classes/java/security/cert/X509CertSelector.java
+++ b/src/share/classes/java/security/cert/X509CertSelector.java
@@ -2574,8 +2574,10 @@
} else {
if (maxPathLen < basicConstraints) {
if (debug != null) {
- debug.println("X509CertSelector.match: maxPathLen too small ("
- + maxPathLen + " < " + basicConstraints + ")");
+ debug.println("X509CertSelector.match: cert's maxPathLen " +
+ "is less than the min maxPathLen set by " +
+ "basicConstraints. " +
+ "(" + maxPathLen + " < " + basicConstraints + ")");
}
return false;
}
diff --git a/src/share/classes/java/util/Calendar.java b/src/share/classes/java/util/Calendar.java
index 0334241..3efdc0f 100644
--- a/src/share/classes/java/util/Calendar.java
+++ b/src/share/classes/java/util/Calendar.java
@@ -2083,17 +2083,33 @@
return null;
}
+ String calendarType = getCalendarType();
+ int fieldValue = get(field);
// the standalone and narrow styles are supported only through CalendarDataProviders.
- if (isStandaloneStyle(style) || isNarrowStyle(style)) {
- return CalendarDataUtility.retrieveFieldValueName(getCalendarType(),
- field, get(field),
- style, locale);
+ if (isStandaloneStyle(style) || isNarrowFormatStyle(style)) {
+ String val = CalendarDataUtility.retrieveFieldValueName(calendarType,
+ field, fieldValue,
+ style, locale);
+ // Perform fallback here to follow the CLDR rules
+ if (val == null) {
+ if (isNarrowFormatStyle(style)) {
+ val = CalendarDataUtility.retrieveFieldValueName(calendarType,
+ field, fieldValue,
+ toStandaloneStyle(style),
+ locale);
+ } else if (isStandaloneStyle(style)) {
+ val = CalendarDataUtility.retrieveFieldValueName(calendarType,
+ field, fieldValue,
+ getBaseStyle(style),
+ locale);
+ }
+ }
+ return val;
}
DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale);
String[] strings = getFieldStrings(field, style, symbols);
if (strings != null) {
- int fieldValue = get(field);
if (fieldValue < strings.length) {
return strings[fieldValue];
}
@@ -2155,10 +2171,26 @@
ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
return null;
}
- if (style == ALL_STYLES || isStandaloneStyle(style)) {
- return CalendarDataUtility.retrieveFieldValueNames(getCalendarType(), field, style, locale);
+
+ String calendarType = getCalendarType();
+ if (style == ALL_STYLES || isStandaloneStyle(style) || isNarrowFormatStyle(style)) {
+ Map<String, Integer> map;
+ map = CalendarDataUtility.retrieveFieldValueNames(calendarType, field, style, locale);
+
+ // Perform fallback here to follow the CLDR rules
+ if (map == null) {
+ if (isNarrowFormatStyle(style)) {
+ map = CalendarDataUtility.retrieveFieldValueNames(calendarType, field,
+ toStandaloneStyle(style), locale);
+ } else if (style != ALL_STYLES) {
+ map = CalendarDataUtility.retrieveFieldValueNames(calendarType, field,
+ getBaseStyle(style), locale);
+ }
+ }
+ return map;
}
- // SHORT, LONG, or NARROW
+
+ // SHORT or LONG
return getDisplayNamesImpl(field, style, locale);
}
@@ -2544,14 +2576,22 @@
return style & ~STANDALONE_MASK;
}
- boolean isStandaloneStyle(int style) {
+ private int toStandaloneStyle(int style) {
+ return style | STANDALONE_MASK;
+ }
+
+ private boolean isStandaloneStyle(int style) {
return (style & STANDALONE_MASK) != 0;
}
- boolean isNarrowStyle(int style) {
+ private boolean isNarrowStyle(int style) {
return style == NARROW_FORMAT || style == NARROW_STANDALONE;
}
+ private boolean isNarrowFormatStyle(int style) {
+ return style == NARROW_FORMAT;
+ }
+
/**
* Returns the pseudo-time-stamp for two fields, given their
* individual pseudo-time-stamps. If either of the fields
diff --git a/src/share/classes/java/util/ComparableTimSort.java b/src/share/classes/java/util/ComparableTimSort.java
index e7c7ac0..36c8d90 100644
--- a/src/share/classes/java/util/ComparableTimSort.java
+++ b/src/share/classes/java/util/ComparableTimSort.java
@@ -144,10 +144,14 @@
* large) stack lengths for smaller arrays. The "magic numbers" in the
* computation below must be changed if MIN_MERGE is decreased. See
* the MIN_MERGE declaration above for more information.
+ * The maximum value of 49 allows for an array up to length
+ * Integer.MAX_VALUE-4, if array is filled by the worst case stack size
+ * increasing scenario. More explanations are given in section 4 of:
+ * http://envisage-project.eu/wp-content/uploads/2015/02/sorting.pdf
*/
int stackLen = (len < 120 ? 5 :
len < 1542 ? 10 :
- len < 119151 ? 24 : 40);
+ len < 119151 ? 24 : 49);
runBase = new int[stackLen];
runLen = new int[stackLen];
}
diff --git a/src/share/classes/java/util/Currency.java b/src/share/classes/java/util/Currency.java
index 2c4a2e7..09d97f8 100644
--- a/src/share/classes/java/util/Currency.java
+++ b/src/share/classes/java/util/Currency.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -139,11 +139,11 @@
// - maps country code to 32-bit int
// - 26*26 entries, corresponding to [A-Z]*[A-Z]
// - \u007F -> not valid country
- // - bits 18-31: unused
- // - bits 8-17: numeric code (0 to 1023)
- // - bit 7: 1 - special case, bits 0-4 indicate which one
+ // - bits 20-31: unused
+ // - bits 10-19: numeric code (0 to 1023)
+ // - bit 9: 1 - special case, bits 0-4 indicate which one
// 0 - simple country, bits 0-4 indicate final char of currency code
- // - bits 5-6: fraction digits for simple countries, 0 for special cases
+ // - bits 5-8: fraction digits for simple countries, 0 for special cases
// - bits 0-4: final char for currency code for simple country, or ID of special case
// - special case IDs:
// - 0: country has no currency
@@ -181,32 +181,34 @@
// number of characters from A to Z
private static final int A_TO_Z = ('Z' - 'A') + 1;
// entry for invalid country codes
- private static final int INVALID_COUNTRY_ENTRY = 0x007F;
+ private static final int INVALID_COUNTRY_ENTRY = 0x0000007F;
// entry for countries without currency
- private static final int COUNTRY_WITHOUT_CURRENCY_ENTRY = 0x0080;
+ private static final int COUNTRY_WITHOUT_CURRENCY_ENTRY = 0x00000200;
// mask for simple case country entries
- private static final int SIMPLE_CASE_COUNTRY_MASK = 0x0000;
+ private static final int SIMPLE_CASE_COUNTRY_MASK = 0x00000000;
// mask for simple case country entry final character
- private static final int SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK = 0x001F;
+ private static final int SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK = 0x0000001F;
// mask for simple case country entry default currency digits
- private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK = 0x0060;
+ private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK = 0x000001E0;
// shift count for simple case country entry default currency digits
private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT = 5;
+ // maximum number for simple case country entry default currency digits
+ private static final int SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS = 9;
// mask for special case country entries
- private static final int SPECIAL_CASE_COUNTRY_MASK = 0x0080;
+ private static final int SPECIAL_CASE_COUNTRY_MASK = 0x00000200;
// mask for special case country index
- private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x001F;
+ private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x0000001F;
// delta from entry index component in main table to index into special case tables
private static final int SPECIAL_CASE_COUNTRY_INDEX_DELTA = 1;
// mask for distinguishing simple and special case countries
private static final int COUNTRY_TYPE_MASK = SIMPLE_CASE_COUNTRY_MASK | SPECIAL_CASE_COUNTRY_MASK;
// mask for the numeric code of the currency
- private static final int NUMERIC_CODE_MASK = 0x0003FF00;
+ private static final int NUMERIC_CODE_MASK = 0x000FFC00;
// shift count for the numeric code of the currency
- private static final int NUMERIC_CODE_SHIFT = 8;
+ private static final int NUMERIC_CODE_SHIFT = 10;
// Currency data format version
- private static final int VALID_FORMAT_VERSION = 1;
+ private static final int VALID_FORMAT_VERSION = 2;
static {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@@ -261,7 +263,7 @@
Set<String> keys = props.stringPropertyNames();
Pattern propertiesPattern =
Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" +
- "([0-3])\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" +
+ "(\\d+)\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" +
"\\d{2}:\\d{2})?");
for (String key : keys) {
replaceCurrencyData(propertiesPattern,
@@ -682,7 +684,7 @@
* @param ctry country code
* @param curdata currency data. This is a comma separated string that
* consists of "three-letter alphabet code", "three-digit numeric code",
- * and "one-digit (0,1,2, or 3) default fraction digit".
+ * and "one-digit (0-9) default fraction digit".
* For example, "JPZ,392,0".
* An optional UTC date can be appended to the string (comma separated)
* to allow a currency change take effect after date specified.
@@ -721,8 +723,14 @@
String code = m.group(1);
int numeric = Integer.parseInt(m.group(2));
- int fraction = Integer.parseInt(m.group(3));
int entry = numeric << NUMERIC_CODE_SHIFT;
+ int fraction = Integer.parseInt(m.group(3));
+ if (fraction > SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS) {
+ info("currency.properties entry for " + ctry +
+ " ignored since the fraction is more than " +
+ SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS + ":" + curdata, null);
+ return;
+ }
int index;
for (index = 0; index < scOldCurrencies.length; index++) {
diff --git a/src/share/classes/java/util/CurrencyData.properties b/src/share/classes/java/util/CurrencyData.properties
index 2b5a570..5f2656e 100644
--- a/src/share/classes/java/util/CurrencyData.properties
+++ b/src/share/classes/java/util/CurrencyData.properties
@@ -23,7 +23,10 @@
# questions.
#
-formatVersion=1
+# Version of the currency data format.
+# 1: initial
+# 2: Change in minor unit (allowing 4-9 digits)
+formatVersion=2
# Version of the currency code information in this class.
# It is a serial number that accompanies with each amendment.
@@ -36,7 +39,7 @@
all=ADP020-AED784-AFA004-AFN971-ALL008-AMD051-ANG532-AOA973-ARS032-ATS040-AUD036-\
AWG533-AYM945-AZM031-AZN944-BAM977-BBD052-BDT050-BEF056-BGL100-BGN975-BHD048-BIF108-\
BMD060-BND096-BOB068-BOV984-BRL986-BSD044-BTN064-BWP072-BYB112-BYR974-\
- BZD084-CAD124-CDF976-CHF756-CLF990-CLP152-CNY156-COP170-CRC188-CSD891-CUP192-CUC931-\
+ BZD084-CAD124-CDF976-CHE947-CHF756-CHW948-CLF990-CLP152-CNY156-COP170-COU970-CRC188-CSD891-CUP192-CUC931-\
CVE132-CYP196-CZK203-DEM276-DJF262-DKK208-DOP214-DZD012-EEK233-EGP818-\
ERN232-ESP724-ETB230-EUR978-FIM246-FJD242-FKP238-FRF250-GBP826-GEL981-\
GHC288-GHS936-GIP292-GMD270-GNF324-GRD300-GTQ320-GWP624-GYD328-HKD344-HNL340-\
@@ -49,7 +52,7 @@
PKR586-PLN985-PTE620-PYG600-QAR634-ROL946-RON946-RSD941-RUB643-RUR810-RWF646-SAR682-\
SBD090-SCR690-SDD736-SDG938-SEK752-SGD702-SHP654-SIT705-SKK703-SLL694-SOS706-\
SRD968-SRG740-SSP728-STD678-SVC222-SYP760-SZL748-THB764-TJS972-TMM795-TMT934-TND788-TOP776-\
- TPE626-TRL792-TRY949-TTD780-TWD901-TZS834-UAH980-UGX800-USD840-USN997-USS998-\
+ TPE626-TRL792-TRY949-TTD780-TWD901-TZS834-UAH980-UGX800-USD840-USN997-USS998-UYI940-\
UYU858-UZS860-VEB862-VEF937-VND704-VUV548-WST882-XAF950-XAG961-XAU959-XBA955-\
XBB956-XBC957-XBD958-XCD951-XDR960-XFO000-XFU000-XOF952-XPD964-XPF953-\
XPT962-XSU994-XTS963-XUA965-XXX999-YER886-YUM891-ZAR710-ZMK894-ZMW967-ZWD716-ZWL932-\
@@ -579,16 +582,17 @@
ZW=ZWL
-# List of currencies with 0, 1, OR 3 decimals for minor units, or where there
-# are no minor units defined. All others use 2 decimals.
+# List of currencies with non-2digit decimals for minor units,
+# or where there are no minor units defined. All others use 2 decimals.
minor0=\
- ADP-BEF-BIF-BYB-BYR-CLF-CLP-DJF-ESP-GNF-\
+ ADP-BEF-BIF-BYB-BYR-CLP-DJF-ESP-GNF-\
GRD-ISK-ITL-JPY-KMF-KRW-LUF-MGF-PYG-PTE-RWF-\
- TPE-TRL-UGX-VND-VUV-XAF-XOF-XPF
-minor1=
+ TPE-TRL-UGX-UYI-VND-VUV-XAF-XOF-XPF
minor3=\
BHD-IQD-JOD-KWD-LYD-OMR-TND
+minor4=\
+ CLF
minorUndefined=\
XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-\
XPT-XSU-XTS-XUA-XXX
diff --git a/src/share/classes/java/util/TimSort.java b/src/share/classes/java/util/TimSort.java
index 9966f74..ea0d58f 100644
--- a/src/share/classes/java/util/TimSort.java
+++ b/src/share/classes/java/util/TimSort.java
@@ -174,10 +174,14 @@
* large) stack lengths for smaller arrays. The "magic numbers" in the
* computation below must be changed if MIN_MERGE is decreased. See
* the MIN_MERGE declaration above for more information.
+ * The maximum value of 49 allows for an array up to length
+ * Integer.MAX_VALUE-4, if array is filled by the worst case stack size
+ * increasing scenario. More explanations are given in section 4 of:
+ * http://envisage-project.eu/wp-content/uploads/2015/02/sorting.pdf
*/
int stackLen = (len < 120 ? 5 :
len < 1542 ? 10 :
- len < 119151 ? 24 : 40);
+ len < 119151 ? 24 : 49);
runBase = new int[stackLen];
runLen = new int[stackLen];
}
diff --git a/src/share/classes/java/util/concurrent/CompletableFuture.java b/src/share/classes/java/util/concurrent/CompletableFuture.java
index 8476dcc..955daab 100644
--- a/src/share/classes/java/util/concurrent/CompletableFuture.java
+++ b/src/share/classes/java/util/concurrent/CompletableFuture.java
@@ -978,7 +978,15 @@
}
try {
@SuppressWarnings("unchecked") T t = (T) r;
- return f.apply(t).toCompletableFuture();
+ CompletableFuture<V> g = f.apply(t).toCompletableFuture();
+ Object s = g.result;
+ if (s != null)
+ return new CompletableFuture<V>(encodeRelay(s));
+ CompletableFuture<V> d = new CompletableFuture<V>();
+ UniRelay<V> copy = new UniRelay<V>(d, g);
+ g.push(copy);
+ copy.tryFire(SYNC);
+ return d;
} catch (Throwable ex) {
return new CompletableFuture<V>(encodeThrowable(ex));
}
diff --git a/src/share/classes/java/util/concurrent/ForkJoinPool.java b/src/share/classes/java/util/concurrent/ForkJoinPool.java
index 8b6ed6d..255a0b2 100644
--- a/src/share/classes/java/util/concurrent/ForkJoinPool.java
+++ b/src/share/classes/java/util/concurrent/ForkJoinPool.java
@@ -2406,7 +2406,7 @@
int j = ((am & s) << ASHIFT) + ABASE;
U.putOrderedObject(a, j, task);
U.putOrderedInt(q, QTOP, s + 1);
- U.putOrderedInt(q, QLOCK, 0);
+ U.putIntVolatile(q, QLOCK, 0);
if (n <= 1)
signalWork(ws, q);
return;
diff --git a/src/share/classes/java/util/zip/ZipEntry.java b/src/share/classes/java/util/zip/ZipEntry.java
index 3f958c4..aa93bcb 100644
--- a/src/share/classes/java/util/zip/ZipEntry.java
+++ b/src/share/classes/java/util/zip/ZipEntry.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -41,7 +41,9 @@
class ZipEntry implements ZipConstants, Cloneable {
String name; // entry name
- long time = -1; // last modification time
+ long xdostime = -1; // last modification time (in extended DOS time,
+ // where milliseconds lost in conversion might
+ // be encoded into the upper half)
FileTime mtime; // last modification time, from extra field data
FileTime atime; // last access time, from extra field data
FileTime ctime; // creation time, from extra field data
@@ -64,6 +66,28 @@
public static final int DEFLATED = 8;
/**
+ * DOS time constant for representing timestamps before 1980.
+ */
+ static final long DOSTIME_BEFORE_1980 = (1 << 21) | (1 << 16);
+
+ /**
+ * Approximately 128 years, in milliseconds (ignoring leap years etc).
+ *
+ * This establish an approximate high-bound value for DOS times in
+ * milliseconds since epoch, used to enable an efficient but
+ * sufficient bounds check to avoid generating extended last modified
+ * time entries.
+ *
+ * Calculating the exact number is locale dependent, would require loading
+ * TimeZone data eagerly, and would make little practical sense. Since DOS
+ * times theoretically go to 2107 - with compatibility not guaranteed
+ * after 2099 - setting this to a time that is before but near 2099
+ * should be sufficient.
+ */
+ private static final long UPPER_DOSTIME_BOUND =
+ 128L * 365 * 24 * 60 * 60 * 1000;
+
+ /**
* Creates a new zip entry with the specified name.
*
* @param name
@@ -93,7 +117,7 @@
public ZipEntry(ZipEntry e) {
Objects.requireNonNull(e, "entry");
name = e.name;
- time = e.time;
+ xdostime = e.xdostime;
mtime = e.mtime;
atime = e.atime;
ctime = e.ctime;
@@ -137,8 +161,14 @@
* @see #getLastModifiedTime()
*/
public void setTime(long time) {
- this.time = time;
- this.mtime = null;
+ this.xdostime = javaToExtendedDosTime(time);
+ // Avoid setting the mtime field if time is in the valid
+ // range for a DOS time
+ if (xdostime != DOSTIME_BEFORE_1980 && time <= UPPER_DOSTIME_BOUND) {
+ this.mtime = null;
+ } else {
+ this.mtime = FileTime.from(time, TimeUnit.MILLISECONDS);
+ }
}
/**
@@ -158,7 +188,10 @@
* @see #setLastModifiedTime(FileTime)
*/
public long getTime() {
- return time;
+ if (mtime != null) {
+ return mtime.toMillis();
+ }
+ return (xdostime != -1) ? extendedDosToJavaTime(xdostime) : -1;
}
/**
@@ -180,9 +213,8 @@
* @since 1.8
*/
public ZipEntry setLastModifiedTime(FileTime time) {
- Objects.requireNonNull(name, "time");
- this.mtime = time;
- this.time = time.to(TimeUnit.MILLISECONDS);
+ this.mtime = Objects.requireNonNull(time, "lastModifiedTime");
+ this.xdostime = javaToExtendedDosTime(time.to(TimeUnit.MILLISECONDS));
return this;
}
@@ -205,9 +237,9 @@
public FileTime getLastModifiedTime() {
if (mtime != null)
return mtime;
- if (time == -1)
+ if (xdostime == -1)
return null;
- return FileTime.from(time, TimeUnit.MILLISECONDS);
+ return FileTime.from(getTime(), TimeUnit.MILLISECONDS);
}
/**
@@ -227,8 +259,7 @@
* @since 1.8
*/
public ZipEntry setLastAccessTime(FileTime time) {
- Objects.requireNonNull(name, "time");
- this.atime = time;
+ this.atime = Objects.requireNonNull(time, "lastAccessTime");
return this;
}
@@ -265,8 +296,7 @@
* @since 1.8
*/
public ZipEntry setCreationTime(FileTime time) {
- Objects.requireNonNull(name, "time");
- this.ctime = time;
+ this.ctime = Objects.requireNonNull(time, "creationTime");
return this;
}
@@ -451,6 +481,8 @@
}
break;
case EXTID_NTFS:
+ if (sz < 32) // reserved 4 bytes + tag 2 bytes + size 2 bytes
+ break; // m[a|c]time 24 bytes
int pos = off + 4; // reserved 4 bytes
if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
break;
diff --git a/src/share/classes/java/util/zip/ZipFile.java b/src/share/classes/java/util/zip/ZipFile.java
index b101c33..e6b9f01 100644
--- a/src/share/classes/java/util/zip/ZipFile.java
+++ b/src/share/classes/java/util/zip/ZipFile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -46,7 +46,6 @@
import java.util.stream.StreamSupport;
import static java.util.zip.ZipConstants64.*;
-import static java.util.zip.ZipUtils.*;
/**
* This class is used to read entries from a zip file.
@@ -567,7 +566,7 @@
e.name = zc.toString(bname, bname.length);
}
}
- e.time = dosToJavaTime(getEntryTime(jzentry));
+ e.xdostime = getEntryTime(jzentry);
e.crc = getEntryCrc(jzentry);
e.size = getEntrySize(jzentry);
e.csize = getEntryCSize(jzentry);
diff --git a/src/share/classes/java/util/zip/ZipInputStream.java b/src/share/classes/java/util/zip/ZipInputStream.java
index 7b4ccc8..98526ef 100644
--- a/src/share/classes/java/util/zip/ZipInputStream.java
+++ b/src/share/classes/java/util/zip/ZipInputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -303,7 +303,7 @@
throw new ZipException("encrypted ZIP entry not supported");
}
e.method = get16(tmpbuf, LOCHOW);
- e.time = dosToJavaTime(get32(tmpbuf, LOCTIM));
+ e.xdostime = get32(tmpbuf, LOCTIM);
if ((flag & 8) == 8) {
/* "Data Descriptor" present */
if (e.method != DEFLATED) {
diff --git a/src/share/classes/java/util/zip/ZipOutputStream.java b/src/share/classes/java/util/zip/ZipOutputStream.java
index 0bd7580..6b480aa 100644
--- a/src/share/classes/java/util/zip/ZipOutputStream.java
+++ b/src/share/classes/java/util/zip/ZipOutputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -61,7 +61,6 @@
private static class XEntry {
final ZipEntry entry;
final long offset;
- long dostime; // last modification time in msdos format
public XEntry(ZipEntry entry, long offset) {
this.entry = entry;
this.offset = offset;
@@ -192,7 +191,7 @@
if (current != null) {
closeEntry(); // close previous entry
}
- if (e.time == -1) {
+ if (e.xdostime == -1) {
// by default, do NOT use extended timestamps in extra
// data, for now.
e.setTime(System.currentTimeMillis());
@@ -389,18 +388,12 @@
boolean hasZip64 = false;
int elen = getExtraLen(e.extra);
- // keep a copy of dostime for writeCEN(), otherwise the tz
- // sensitive local time entries in loc and cen might be
- // different if the default tz get changed during writeLOC()
- // and writeCEN()
- xentry.dostime = javaToDosTime(e.time);
-
writeInt(LOCSIG); // LOC header signature
if ((flag & 8) == 8) {
writeShort(version(e)); // version needed to extract
writeShort(flag); // general purpose bit flag
writeShort(e.method); // compression method
- writeInt(xentry.dostime); // last modification time
+ writeInt(e.xdostime); // last modification time
// store size, uncompressed size, and crc-32 in data descriptor
// immediately following compressed entry data
writeInt(0);
@@ -415,7 +408,7 @@
}
writeShort(flag); // general purpose bit flag
writeShort(e.method); // compression method
- writeInt(xentry.dostime); // last modification time
+ writeInt(e.xdostime); // last modification time
writeInt(e.crc); // crc-32
if (hasZip64) {
writeInt(ZIP64_MAGICVAL);
@@ -522,9 +515,7 @@
}
writeShort(flag); // general purpose bit flag
writeShort(e.method); // compression method
- // use the copy in xentry, which has been converted
- // from e.time in writeLOC()
- writeInt(xentry.dostime); // last modification time
+ writeInt(e.xdostime); // last modification time
writeInt(e.crc); // crc-32
writeInt(csize); // compressed size
writeInt(size); // uncompressed size
diff --git a/src/share/classes/java/util/zip/ZipUtils.java b/src/share/classes/java/util/zip/ZipUtils.java
index 5a5e9a0..cd8b052 100644
--- a/src/share/classes/java/util/zip/ZipUtils.java
+++ b/src/share/classes/java/util/zip/ZipUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -29,9 +29,6 @@
import java.util.Date;
import java.util.concurrent.TimeUnit;
-import static java.util.zip.ZipConstants.*;
-import static java.util.zip.ZipConstants64.*;
-
class ZipUtils {
// used to adjust values between Windows and java epoch
@@ -69,7 +66,7 @@
/**
* Converts DOS time to Java time (number of milliseconds since epoch).
*/
- public static long dosToJavaTime(long dtime) {
+ private static long dosToJavaTime(long dtime) {
@SuppressWarnings("deprecation") // Use of date constructor.
Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
(int)(((dtime >> 21) & 0x0f) - 1),
@@ -81,14 +78,26 @@
}
/**
+ * Converts extended DOS time to Java time, where up to 1999 milliseconds
+ * might be encoded into the upper half of the returned long.
+ *
+ * @param xdostime the extended DOS time value
+ * @return milliseconds since epoch
+ */
+ public static long extendedDosToJavaTime(long xdostime) {
+ long time = dosToJavaTime(xdostime);
+ return time + (xdostime >> 32);
+ }
+
+ /**
* Converts Java time to DOS time.
*/
@SuppressWarnings("deprecation") // Use of date methods
- public static long javaToDosTime(long time) {
+ private static long javaToDosTime(long time) {
Date d = new Date(time);
int year = d.getYear() + 1900;
if (year < 1980) {
- return (1 << 21) | (1 << 16);
+ return ZipEntry.DOSTIME_BEFORE_1980;
}
return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
@@ -96,6 +105,23 @@
}
/**
+ * Converts Java time to DOS time, encoding any milliseconds lost
+ * in the conversion into the upper half of the returned long.
+ *
+ * @param time milliseconds since epoch
+ * @return DOS time with 2s remainder encoded into upper half
+ */
+ public static long javaToExtendedDosTime(long time) {
+ if (time < 0) {
+ return ZipEntry.DOSTIME_BEFORE_1980;
+ }
+ long dostime = javaToDosTime(time);
+ return (dostime != ZipEntry.DOSTIME_BEFORE_1980)
+ ? dostime + ((time % 2000) << 32)
+ : ZipEntry.DOSTIME_BEFORE_1980;
+ }
+
+ /**
* Fetches unsigned 16-bit value from byte array at specified offset.
* The bytes are assumed to be in Intel (little-endian) byte order.
*/
diff --git a/src/share/classes/javax/crypto/spec/SecretKeySpec.java b/src/share/classes/javax/crypto/spec/SecretKeySpec.java
index 56ca9b5..767c0d2 100644
--- a/src/share/classes/javax/crypto/spec/SecretKeySpec.java
+++ b/src/share/classes/javax/crypto/spec/SecretKeySpec.java
@@ -27,6 +27,7 @@
import java.security.MessageDigest;
import java.security.spec.KeySpec;
+import java.util.Locale;
import javax.crypto.SecretKey;
/**
@@ -195,7 +196,8 @@
if (this.algorithm.equalsIgnoreCase("TripleDES"))
return (retval ^= "desede".hashCode());
else
- return (retval ^= this.algorithm.toLowerCase().hashCode());
+ return (retval ^=
+ this.algorithm.toLowerCase(Locale.ENGLISH).hashCode());
}
/**
diff --git a/src/share/classes/javax/imageio/stream/ImageInputStreamImpl.java b/src/share/classes/javax/imageio/stream/ImageInputStreamImpl.java
index 0a0be29..735bab8 100644
--- a/src/share/classes/javax/imageio/stream/ImageInputStreamImpl.java
+++ b/src/share/classes/javax/imageio/stream/ImageInputStreamImpl.java
@@ -225,7 +225,7 @@
}
public short readShort() throws IOException {
- if (read(byteBuf, 0, 2) < 0) {
+ if (read(byteBuf, 0, 2) != 2) {
throw new EOFException();
}
@@ -247,7 +247,7 @@
}
public int readInt() throws IOException {
- if (read(byteBuf, 0, 4) < 0) {
+ if (read(byteBuf, 0, 4) != 4) {
throw new EOFException();
}
diff --git a/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java b/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java
index d4cecba..33b765d 100644
--- a/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java
+++ b/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java
@@ -1258,10 +1258,11 @@
if (serverTerminated) {
// we must not call fetchNotifs() if the server is
// terminated (timeout elapsed).
- //
- return new NotificationResult(0L, 0L,
- new TargetedNotification[0]);
-
+ // returns null to force the client to stop fetching
+ if (logger.debugOn()) logger.debug("fetchNotifications",
+ "The notification server has been closed, "
+ + "returns null to force the client to stop fetching");
+ return null;
}
final long csn = clientSequenceNumber;
final int mn = maxNotifications;
diff --git a/src/share/classes/javax/script/ScriptEngineFactory.java b/src/share/classes/javax/script/ScriptEngineFactory.java
index 87d9315..b0bd4aa 100644
--- a/src/share/classes/javax/script/ScriptEngineFactory.java
+++ b/src/share/classes/javax/script/ScriptEngineFactory.java
@@ -85,7 +85,7 @@
public List<String> getNames();
/**
- * Returns the name of the scripting langauge supported by this
+ * Returns the name of the scripting language supported by this
* <code>ScriptEngine</code>.
* @return The name of the supported language.
*/
@@ -104,14 +104,15 @@
* <ul>
* <li>ScriptEngine.ENGINE</li>
* <li>ScriptEngine.ENGINE_VERSION</li>
- * <li>ScriptEngine.NAME</li>
* <li>ScriptEngine.LANGUAGE</li>
* <li>ScriptEngine.LANGUAGE_VERSION</li>
+ * <li>ScriptEngine.NAME</li>
* </ul>
* <p>
* The values for these keys are the Strings returned by <code>getEngineName</code>,
- * <code>getEngineVersion</code>, <code>getName</code>, <code>getLanguageName</code> and
- * <code>getLanguageVersion</code> respectively.<br><br>
+ * <code>getEngineVersion</code>, <code>getLanguageName</code>,
+ * <code>getLanguageVersion</code> for the first four keys respectively. For NAME, one of the Strings
+ * returned by <code>getNames</code> is returned.<br><br>
* A reserved key, <code><b>THREADING</b></code>, whose value describes the behavior of the engine
* with respect to concurrent execution of scripts and maintenance of state is also defined.
* These values for the <code><b>THREADING</b></code> key are:<br><br>
diff --git a/src/share/classes/javax/swing/AbstractButton.java b/src/share/classes/javax/swing/AbstractButton.java
index c4335fb..32e1219 100644
--- a/src/share/classes/javax/swing/AbstractButton.java
+++ b/src/share/classes/javax/swing/AbstractButton.java
@@ -1,5 +1,5 @@
/*
- * 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
@@ -2197,10 +2197,7 @@
*/
public boolean imageUpdate(Image img, int infoflags,
int x, int y, int w, int h) {
- Icon iconDisplayed = getIcon();
- if (iconDisplayed == null) {
- return false;
- }
+ Icon iconDisplayed = null;
if (!model.isEnabled()) {
if (model.isSelected()) {
@@ -2220,7 +2217,12 @@
iconDisplayed = getSelectedIcon();
}
- if (!SwingUtilities.doesIconReferenceImage(iconDisplayed, img)) {
+ if (iconDisplayed == null) {
+ iconDisplayed = getIcon();
+ }
+
+ if (iconDisplayed == null
+ || !SwingUtilities.doesIconReferenceImage(iconDisplayed, img)) {
// We don't know about this image, disable the notification so
// we don't keep repainting.
return false;
diff --git a/src/share/classes/javax/swing/JComponent.java b/src/share/classes/javax/swing/JComponent.java
index 940eb3e..cb64a4d 100644
--- a/src/share/classes/javax/swing/JComponent.java
+++ b/src/share/classes/javax/swing/JComponent.java
@@ -3738,12 +3738,6 @@
* @param listener the PropertyChangeListener to be added
*/
public void addPropertyChangeListener(PropertyChangeListener listener) {
- if (accessibleContainerHandler == null) {
- accessibleContainerHandler = new AccessibleContainerHandler();
- }
- if (propertyListenersCount++ == 0) {
- JComponent.this.addContainerListener(accessibleContainerHandler);
- }
super.addPropertyChangeListener(listener);
}
@@ -3755,9 +3749,6 @@
* @param listener the PropertyChangeListener to be removed
*/
public void removePropertyChangeListener(PropertyChangeListener listener) {
- if (--propertyListenersCount == 0) {
- JComponent.this.removeContainerListener(accessibleContainerHandler);
- }
super.removePropertyChangeListener(listener);
}
diff --git a/src/share/classes/javax/swing/JFormattedTextField.java b/src/share/classes/javax/swing/JFormattedTextField.java
index 16e89f5..645e397f 100644
--- a/src/share/classes/javax/swing/JFormattedTextField.java
+++ b/src/share/classes/javax/swing/JFormattedTextField.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -30,7 +30,6 @@
import java.io.*;
import java.text.*;
import java.util.*;
-import javax.swing.UIManager;
import javax.swing.event.*;
import javax.swing.plaf.UIResource;
import javax.swing.text.*;
@@ -151,7 +150,7 @@
* will be created to handle formatting of numbers:
* <pre>
* JFormattedTextField tf = new JFormattedTextField();
- * tf.setValue(new Number(100));
+ * tf.setValue(100);
* </pre>
* <p>
* <strong>Warning:</strong> As the <code>AbstractFormatter</code> will
diff --git a/src/share/classes/javax/swing/JMenu.java b/src/share/classes/javax/swing/JMenu.java
index e631152..0544e7b 100644
--- a/src/share/classes/javax/swing/JMenu.java
+++ b/src/share/classes/javax/swing/JMenu.java
@@ -475,7 +475,8 @@
}
// Then the y:
y = s.height + yOffset; // Prefer dropping down
- if (position.y + y + pmSize.height >= screenBounds.height &&
+ if (position.y + y + pmSize.height >= screenBounds.height
+ + screenBounds.y &&
// popup doesn't fit - place it wherever there's more room
screenBounds.height - s.height < 2*(position.y
- screenBounds.y)) {
diff --git a/src/share/classes/javax/swing/JTextArea.java b/src/share/classes/javax/swing/JTextArea.java
index 54457ee..e99a0ff 100644
--- a/src/share/classes/javax/swing/JTextArea.java
+++ b/src/share/classes/javax/swing/JTextArea.java
@@ -1,5 +1,5 @@
/*
- * 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
@@ -491,7 +491,6 @@
* @exception IllegalArgumentException if part of the range is an
* invalid position in the model
* @see #insert
- * @see #replaceRange
*/
public void replaceRange(String str, int start, int end) {
if (end < start) {
diff --git a/src/share/classes/javax/swing/JTree.java b/src/share/classes/javax/swing/JTree.java
index 9fe80f4..bd1e9c5 100644
--- a/src/share/classes/javax/swing/JTree.java
+++ b/src/share/classes/javax/swing/JTree.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, 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
@@ -872,9 +872,10 @@
if(treeModelListener != null)
treeModel.addTreeModelListener(treeModelListener);
// Mark the root as expanded, if it isn't a leaf.
- if(treeModel.getRoot() != null &&
- !treeModel.isLeaf(treeModel.getRoot())) {
- expandedState.put(new TreePath(treeModel.getRoot()),
+ Object treeRoot = treeModel.getRoot();
+ if(treeRoot != null &&
+ !treeModel.isLeaf(treeRoot)) {
+ expandedState.put(new TreePath(treeRoot),
Boolean.TRUE);
}
}
@@ -3223,6 +3224,9 @@
int count = indexs.length;
Object parent = model.getRoot();
+ if (parent == null)
+ return null;
+
TreePath parentPath = new TreePath(parent);
for(int counter = 0; counter < count; counter++) {
@@ -3798,8 +3802,9 @@
if (parent.getPathCount() == 1) {
// New root, remove everything!
clearToggledPaths();
- if(treeModel.getRoot() != null &&
- !treeModel.isLeaf(treeModel.getRoot())) {
+ Object treeRoot = treeModel.getRoot();
+ if(treeRoot != null &&
+ !treeModel.isLeaf(treeRoot)) {
// Mark the root as expanded, if it isn't a leaf.
expandedState.put(parent, Boolean.TRUE);
}
@@ -4283,7 +4288,11 @@
if (model == null) {
return null;
}
- TreePath path = new TreePath(model.getRoot());
+ Object treeRoot = model.getRoot();
+ if (treeRoot == null)
+ return null;
+
+ TreePath path = new TreePath(treeRoot);
if (JTree.this.isVisible(path)) {
TreeCellRenderer r = JTree.this.getCellRenderer();
TreeUI ui = JTree.this.getUI();
@@ -4296,8 +4305,8 @@
boolean expanded = JTree.this.isExpanded(path);
return r.getTreeCellRendererComponent(JTree.this,
- model.getRoot(), selected, expanded,
- model.isLeaf(model.getRoot()), row, hasFocus);
+ treeRoot, selected, expanded,
+ model.isLeaf(treeRoot), row, hasFocus);
}
}
return null;
@@ -4350,8 +4359,11 @@
return 1; // the root node
}
+ Object treeRoot = model.getRoot();
+ if (treeRoot == null)
+ return 0;
// return the root's first set of children count
- return model.getChildCount(model.getRoot());
+ return model.getChildCount(treeRoot);
}
/**
@@ -4365,9 +4377,17 @@
if (model == null) {
return null;
}
+
+ Object treeRoot = model.getRoot();
+ if (treeRoot == null) {
+ return null;
+ }
+
if (isRootVisible()) {
if (i == 0) { // return the root node Accessible
- Object[] objPath = { model.getRoot() };
+ Object[] objPath = { treeRoot };
+ if (objPath[0] == null)
+ return null;
TreePath path = new TreePath(objPath);
return new AccessibleJTreeNode(JTree.this, path, JTree.this);
} else {
@@ -4376,12 +4396,14 @@
}
// return Accessible for one of root's child nodes
- int count = model.getChildCount(model.getRoot());
+ int count = model.getChildCount(treeRoot);
if (i < 0 || i >= count) {
return null;
}
- Object obj = model.getChild(model.getRoot(), i);
- Object[] objPath = { model.getRoot(), obj };
+ Object obj = model.getChild(treeRoot, i);
+ if (obj == null)
+ return null;
+ Object[] objPath = { treeRoot, obj };
TreePath path = new TreePath(objPath);
return new AccessibleJTreeNode(JTree.this, path, JTree.this);
}
@@ -4420,6 +4442,9 @@
public int getAccessibleSelectionCount() {
Object[] rootPath = new Object[1];
rootPath[0] = treeModel.getRoot();
+ if (rootPath[0] == null)
+ return 0;
+
TreePath childPath = new TreePath(rootPath);
if (JTree.this.isPathSelected(childPath)) {
return 1;
@@ -4442,6 +4467,8 @@
if (i == 0) {
Object[] rootPath = new Object[1];
rootPath[0] = treeModel.getRoot();
+ if (rootPath[0] == null)
+ return null;
TreePath childPath = new TreePath(rootPath);
if (JTree.this.isPathSelected(childPath)) {
return new AccessibleJTreeNode(JTree.this, childPath, JTree.this);
@@ -4461,6 +4488,8 @@
if (i == 0) {
Object[] rootPath = new Object[1];
rootPath[0] = treeModel.getRoot();
+ if (rootPath[0] == null)
+ return false;
TreePath childPath = new TreePath(rootPath);
return JTree.this.isPathSelected(childPath);
} else {
@@ -4482,6 +4511,8 @@
if (model != null) {
if (i == 0) {
Object[] objPath = {model.getRoot()};
+ if (objPath[0] == null)
+ return;
TreePath path = new TreePath(objPath);
JTree.this.addSelectionPath(path);
}
@@ -4500,6 +4531,8 @@
if (model != null) {
if (i == 0) {
Object[] objPath = {model.getRoot()};
+ if (objPath[0] == null)
+ return;
TreePath path = new TreePath(objPath);
JTree.this.removeSelectionPath(path);
}
@@ -4525,6 +4558,8 @@
TreeModel model = JTree.this.getModel();
if (model != null) {
Object[] objPath = {model.getRoot()};
+ if (objPath[0] == null)
+ return;
TreePath path = new TreePath(objPath);
JTree.this.addSelectionPath(path);
}
diff --git a/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java b/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java
index c1383f6..d1de416 100644
--- a/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java
+++ b/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java
@@ -566,7 +566,10 @@
} else if (comp instanceof Container && comp != aContainer) {
Container cont = (Container)comp;
if (cont.isFocusTraversalPolicyProvider()) {
- return cont.getFocusTraversalPolicy().getLastComponent(cont);
+ Component retComp = cont.getFocusTraversalPolicy().getLastComponent(cont);
+ if (retComp != null) {
+ return retComp;
+ }
}
}
}
diff --git a/src/share/classes/javax/swing/UIDefaults.java b/src/share/classes/javax/swing/UIDefaults.java
index e346947..12c3814 100644
--- a/src/share/classes/javax/swing/UIDefaults.java
+++ b/src/share/classes/javax/swing/UIDefaults.java
@@ -44,9 +44,7 @@
import java.awt.Color;
import java.awt.Insets;
import java.awt.Dimension;
-import java.lang.reflect.Method;
import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeEvent;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
@@ -74,7 +72,7 @@
*/
public class UIDefaults extends Hashtable<Object,Object>
{
- private static final Object PENDING = "Pending";
+ private static final Object PENDING = new Object();
private SwingPropertyChangeSupport changeSupport;
@@ -168,7 +166,7 @@
* Looks up up the given key in our Hashtable and resolves LazyValues
* or ActiveValues.
*/
- private Object getFromHashtable(Object key) {
+ private Object getFromHashtable(final Object key) {
/* Quickly handle the common case, without grabbing
* a lock.
*/
diff --git a/src/share/classes/javax/swing/package.html b/src/share/classes/javax/swing/package.html
index 1b090f6..2cb98a4 100644
--- a/src/share/classes/javax/swing/package.html
+++ b/src/share/classes/javax/swing/package.html
@@ -3,7 +3,7 @@
<HEAD>
<!--
-Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1998, 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
@@ -68,6 +68,8 @@
the event dispatching thread. The following two examples work equally
well for transferring control and starting up a Swing application:
<pre>
+import javax.swing.SwingUtilities;
+
public class MyApp implements Runnable {
public void run() {
// Invoked on the event dispatching thread.
@@ -75,16 +77,18 @@
}
public static void main(String[] args) {
- SwingUtilities.invokeLater(new MyApp(args));
+ SwingUtilities.invokeLater(new MyApp());
}
}
</pre>
Or:
<pre>
+import javax.swing.SwingUtilities;
+
public class MyApp {
MyApp(String[] args) {
- // Invoked on the event dispatching thread. Do any initialization
- // here.
+ // Invoked on the event dispatching thread.
+ // Do any initialization here.
}
public void show() {
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicBorders.java b/src/share/classes/javax/swing/plaf/basic/BasicBorders.java
index be06927..5e58480 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicBorders.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicBorders.java
@@ -1,5 +1,5 @@
/*
- * 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
@@ -37,6 +37,8 @@
import java.awt.Color;
import java.awt.Graphics;
+import sun.swing.SwingUtilities2;
+
/**
* Factory object that can vend Borders appropriate for the basic L & F.
* @author Georges Saab
@@ -337,10 +339,10 @@
Color oldColor = g.getColor();
g.translate(x, y);
g.setColor(shadow);
- g.drawLine(0, height-2, width, height-2);
+ SwingUtilities2.drawHLine(g, 0, width - 1, height - 2);
g.setColor(highlight);
- g.drawLine(0, height-1, width, height-1);
- g.translate(-x,-y);
+ SwingUtilities2.drawHLine(g, 0, width - 1, height - 1);
+ g.translate(-x, -y);
g.setColor(oldColor);
}
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicDesktopPaneUI.java b/src/share/classes/javax/swing/plaf/basic/BasicDesktopPaneUI.java
index 2d00677..64dace3 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicDesktopPaneUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicDesktopPaneUI.java
@@ -1,5 +1,5 @@
/*
- * 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
@@ -36,10 +36,9 @@
import java.awt.Graphics;
import java.awt.KeyboardFocusManager;
import java.awt.*;
-import java.util.Vector;
+
import sun.swing.DefaultLookup;
import sun.swing.UIAction;
-import sun.awt.AppContext;
/**
* Basic L&F for a desktop.
@@ -49,9 +48,6 @@
public class BasicDesktopPaneUI extends DesktopPaneUI {
// Old actions forward to an instance of this.
private static final Actions SHARED_ACTION = new Actions();
- private static Dimension minSize = new Dimension(0,0);
- private static Dimension maxSize = new Dimension(Integer.MAX_VALUE,
- Integer.MAX_VALUE);
private Handler handler;
private PropertyChangeListener pcl;
@@ -264,13 +260,19 @@
public void paint(Graphics g, JComponent c) {}
- public Dimension getPreferredSize(JComponent c) {return null;}
+ @Override
+ public Dimension getPreferredSize(JComponent c) {
+ return null;
+ }
+ @Override
public Dimension getMinimumSize(JComponent c) {
- return minSize;
- }
- public Dimension getMaximumSize(JComponent c){
- return maxSize;
+ return new Dimension(0, 0);
+ }
+
+ @Override
+ public Dimension getMaximumSize(JComponent c) {
+ return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
/**
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java b/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java
index 89066d2..9c73734 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java
@@ -438,7 +438,7 @@
// to the button group or not
Component getFocusTransferBaseComponent(boolean next){
Component focusBaseComp = activeBtn;
- Window container = SwingUtilities.getWindowAncestor(activeBtn);
+ Container container = focusBaseComp.getFocusCycleRootAncestor();
if (container != null) {
FocusTraversalPolicy policy = container.getFocusTraversalPolicy();
Component comp = next ? policy.getComponentAfter(container, activeBtn)
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java b/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java
index 6462820..190b94b 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java
@@ -876,6 +876,12 @@
return;
}
orientation = SwingConstants.HORIZONTAL;
+ } else if(e.isShiftDown()){
+ JScrollBar hScroll = scrollpane.getHorizontalScrollBar();
+ if (hScroll != null && hScroll.isVisible()) {
+ toScroll = hScroll;
+ orientation = SwingConstants.HORIZONTAL;
+ }
}
e.consume();
diff --git a/src/share/classes/javax/swing/plaf/metal/MetalBorders.java b/src/share/classes/javax/swing/plaf/metal/MetalBorders.java
index 24c3d5a..f2b9245 100644
--- a/src/share/classes/javax/swing/plaf/metal/MetalBorders.java
+++ b/src/share/classes/javax/swing/plaf/metal/MetalBorders.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -40,6 +40,7 @@
import java.awt.Window;
import sun.swing.StringUIClientPropertyKey;
+import sun.swing.SwingUtilities2;
/**
@@ -528,25 +529,22 @@
protected static Insets borderInsets = new Insets( 1, 0, 1, 0 );
public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
- g.translate( x, y );
+ g.translate(x, y);
if (MetalLookAndFeel.usingOcean()) {
- // Only paint a border if we're not next to a horizontal
- // toolbar
- if ((c instanceof JMenuBar) && !MetalToolBarUI.doesMenuBarBorderToolBar((JMenuBar)c)) {
+ // Only paint a border if we're not next to a horizontal toolbar
+ if (c instanceof JMenuBar
+ && !MetalToolBarUI.doesMenuBarBorderToolBar((JMenuBar)c)) {
g.setColor(MetalLookAndFeel.getControl());
- g.drawLine(0, h - 2, w, h - 2);
+ SwingUtilities2.drawHLine(g, 0, w - 1, h - 2);
g.setColor(UIManager.getColor("MenuBar.borderColor"));
- g.drawLine(0, h - 1, w, h - 1);
+ SwingUtilities2.drawHLine(g, 0, w - 1, h - 1);
}
+ } else {
+ g.setColor(MetalLookAndFeel.getControlShadow());
+ SwingUtilities2.drawHLine(g, 0, w - 1, h - 1);
}
- else {
- g.setColor( MetalLookAndFeel.getControlShadow() );
- g.drawLine( 0, h-1, w, h-1 );
- }
-
- g.translate( -x, -y );
-
+ g.translate(-x, -y);
}
public Insets getBorderInsets(Component c, Insets newInsets) {
diff --git a/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java b/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java
index ddc70c9..a7b0f52 100644
--- a/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java
+++ b/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -92,8 +92,6 @@
private static int MIN_WIDTH = 500;
private static int MIN_HEIGHT = 326;
- private static Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT);
-
private static int LIST_PREF_WIDTH = 405;
private static int LIST_PREF_HEIGHT = 135;
private static Dimension LIST_PREF_SIZE = new Dimension(LIST_PREF_WIDTH, LIST_PREF_HEIGHT);
@@ -565,6 +563,7 @@
* @return a <code>Dimension</code> specifying the preferred
* width and height of the file chooser
*/
+ @Override
public Dimension getPreferredSize(JComponent c) {
int prefWidth = PREF_SIZE.width;
Dimension d = c.getLayout().preferredLayoutSize(c);
@@ -583,8 +582,9 @@
* @return a <code>Dimension</code> specifying the minimum
* width and height of the file chooser
*/
+ @Override
public Dimension getMinimumSize(JComponent c) {
- return MIN_SIZE;
+ return new Dimension(MIN_WIDTH, MIN_HEIGHT);
}
/**
@@ -594,6 +594,7 @@
* @return a <code>Dimension</code> specifying the maximum
* width and height of the file chooser
*/
+ @Override
public Dimension getMaximumSize(JComponent c) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
@@ -604,7 +605,8 @@
} else {
JFileChooser fc = getFileChooser();
if ((fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) ||
- (fc.isDirectorySelectionEnabled() && fc.isFileSelectionEnabled() && fc.getFileSystemView().isFileSystemRoot(file))) {
+ (fc.isDirectorySelectionEnabled() && fc.isFileSelectionEnabled()
+ && fc.getFileSystemView().isFileSystemRoot(file))) {
return file.getPath();
} else {
return file.getName();
diff --git a/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java b/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java
index 01aa45f..47a737f 100644
--- a/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java
+++ b/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java
@@ -625,6 +625,9 @@
// check if we can scale to the requested size
Dimension canvas = ctx.canvasSize;
Insets insets = ctx.stretchingInsets;
+ if (insets.left + insets.right > w || insets.top + insets.bottom > h) {
+ return;
+ }
if (w <= (canvas.width * ctx.maxHorizontalScaleFactor) && h <= (canvas.height * ctx.maxVerticalScaleFactor)) {
// get image at canvas size
diff --git a/src/share/classes/javax/swing/text/html/parser/ContentModel.java b/src/share/classes/javax/swing/text/html/parser/ContentModel.java
index c23b1bc..98a279a 100644
--- a/src/share/classes/javax/swing/text/html/parser/ContentModel.java
+++ b/src/share/classes/javax/swing/text/html/parser/ContentModel.java
@@ -169,10 +169,9 @@
case '|':
case '&': {
Element e = (Element) token;
- if (valSet == null) {
+ if (valSet == null || valSet.length <= Element.getMaxIndex()) {
valSet = new boolean[Element.getMaxIndex() + 1];
val = new boolean[valSet.length];
- // All Element instances are created before this ever executes
}
if (valSet[e.index]) {
return val[e.index];
diff --git a/src/share/classes/sun/applet/AppletPanel.java b/src/share/classes/sun/applet/AppletPanel.java
index f5879ef..618e1bb 100644
--- a/src/share/classes/sun/applet/AppletPanel.java
+++ b/src/share/classes/sun/applet/AppletPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -682,7 +682,12 @@
if (toFocus != null) {
if (parent instanceof EmbeddedFrame) {
- ((EmbeddedFrame)parent).synthesizeWindowActivation(true);
+ // JDK-8056915: Try to request focus to the embedder first and
+ // activate the embedded frame through it
+ if (!((EmbeddedFrame) parent).requestFocusToEmbedder()) {
+ // Otherwise activate the embedded frame directly
+ ((EmbeddedFrame) parent).synthesizeWindowActivation(true);
+ }
}
// EmbeddedFrame might have focus before the applet was added.
// Thus after its activation the most recent focus owner will be
diff --git a/src/share/classes/sun/awt/EmbeddedFrame.java b/src/share/classes/sun/awt/EmbeddedFrame.java
index 5ad4293..e214ca6 100644
--- a/src/share/classes/sun/awt/EmbeddedFrame.java
+++ b/src/share/classes/sun/awt/EmbeddedFrame.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -361,6 +361,15 @@
public void synthesizeWindowActivation(boolean doActivate) {}
/**
+ * Requests the focus to the embedder.
+ *
+ * @return {@code true} if focus request was successful, and {@code false} otherwise.
+ */
+ public boolean requestFocusToEmbedder() {
+ return false;
+ }
+
+ /**
* Moves this embedded frame to a new location. The top-left corner of
* the new location is specified by the <code>x</code> and <code>y</code>
* parameters relative to the native parent component.
diff --git a/src/share/classes/sun/awt/SunToolkit.java b/src/share/classes/sun/awt/SunToolkit.java
index e546e00..737c8c6 100644
--- a/src/share/classes/sun/awt/SunToolkit.java
+++ b/src/share/classes/sun/awt/SunToolkit.java
@@ -889,14 +889,17 @@
}
protected static boolean imageExists(String filename) {
- checkPermissions(filename);
- return filename != null && new File(filename).exists();
+ if (filename != null) {
+ checkPermissions(filename);
+ return new File(filename).exists();
+ }
+ return false;
}
@SuppressWarnings("try")
protected static boolean imageExists(URL url) {
- checkPermissions(url);
if (url != null) {
+ checkPermissions(url);
try (InputStream is = url.openStream()) {
return true;
}catch(IOException e){
diff --git a/src/share/classes/sun/awt/datatransfer/SunClipboard.java b/src/share/classes/sun/awt/datatransfer/SunClipboard.java
index da186ed..5cdb4b7 100644
--- a/src/share/classes/sun/awt/datatransfer/SunClipboard.java
+++ b/src/share/classes/sun/awt/datatransfer/SunClipboard.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -39,7 +39,7 @@
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-
+import java.util.Arrays;
import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;
@@ -75,12 +75,11 @@
private volatile int numberOfFlavorListeners = 0;
/**
- * A set of <code>DataFlavor</code>s that is available on
- * this clipboard. It is used for tracking changes
- * of <code>DataFlavor</code>s available on this clipboard.
+ * A set of {@code DataFlavor}s that is available on this clipboard. It is
+ * used for tracking changes of {@code DataFlavor}s available on this
+ * clipboard. Can be {@code null}.
*/
- private volatile Set currentDataFlavors;
-
+ private volatile long[] currentFormats;
public SunClipboard(String name) {
super(name);
@@ -367,11 +366,11 @@
try {
openClipboard(null);
currentFormats = getClipboardFormats();
- } catch (IllegalStateException exc) {
+ } catch (final IllegalStateException ignored) {
} finally {
closeClipboard();
}
- currentDataFlavors = formatArrayAsDataFlavorSet(currentFormats);
+ this.currentFormats = currentFormats;
registerClipboardViewerChecked();
}
@@ -391,7 +390,7 @@
if (contextFlavorListeners.remove(listener) &&
--numberOfFlavorListeners == 0) {
unregisterClipboardViewerChecked();
- currentDataFlavors = null;
+ currentFormats = null;
}
}
@@ -420,17 +419,15 @@
* @param formats data formats that have just been retrieved from
* this clipboard
*/
- public void checkChange(long[] formats) {
- Set prevDataFlavors = currentDataFlavors;
- currentDataFlavors = formatArrayAsDataFlavorSet(formats);
-
- if ((prevDataFlavors != null) && (currentDataFlavors != null) &&
- prevDataFlavors.equals(currentDataFlavors)) {
+ protected final void checkChange(final long[] formats) {
+ if (Arrays.equals(formats, currentFormats)) {
// we've been able to successfully get available on the clipboard
// DataFlavors this and previous time and they are coincident;
// don't notify
return;
}
+ currentFormats = formats;
+
class SunFlavorChangeNotifier implements Runnable {
private final FlavorListener flavorListener;
diff --git a/src/share/classes/sun/launcher/resources/launcher.properties b/src/share/classes/sun/launcher/resources/launcher.properties
index cfdf9a9..a0129bd 100644
--- a/src/share/classes/sun/launcher/resources/launcher.properties
+++ b/src/share/classes/sun/launcher/resources/launcher.properties
@@ -47,9 +47,13 @@
\ enable verbose output\n\
\ -version print product version and exit\n\
\ -version:<value>\n\
+\ Warning: this feature is deprecated and will be removed\n\
+\ in a future release.\n\
\ require the specified version to run\n\
\ -showversion print product version and continue\n\
\ -jre-restrict-search | -no-jre-restrict-search\n\
+\ Warning: this feature is deprecated and will be removed\n\
+\ in a future release.\n\
\ include/exclude user private JREs in the version search\n\
\ -? -help print this help message\n\
\ -X print help on non-standard options\n\
diff --git a/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java b/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
index a2f0563..e4d1c2f 100644
--- a/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
+++ b/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
@@ -767,7 +767,7 @@
JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
connServer.start();
} catch (IOException e) {
- if (connServer == null) {
+ if (connServer == null || connServer.getAddress() == null) {
throw new AgentConfigurationError(CONNECTOR_SERVER_IO_ERROR,
e, url.toString());
} else {
diff --git a/src/share/classes/sun/misc/Unsafe.java b/src/share/classes/sun/misc/Unsafe.java
index 1a2e915..99e4658 100644
--- a/src/share/classes/sun/misc/Unsafe.java
+++ b/src/share/classes/sun/misc/Unsafe.java
@@ -846,12 +846,14 @@
throws InstantiationException;
/** Lock the object. It must get unlocked via {@link #monitorExit}. */
+ @Deprecated
public native void monitorEnter(Object o);
/**
* Unlock the object. It must have been locked via {@link
* #monitorEnter}.
*/
+ @Deprecated
public native void monitorExit(Object o);
/**
@@ -859,6 +861,7 @@
* whether the lock succeeded. If it did, the object must be
* unlocked via {@link #monitorExit}.
*/
+ @Deprecated
public native boolean tryMonitorEnter(Object o);
/** Throw the exception without telling the verifier. */
diff --git a/src/share/classes/sun/net/httpserver/Code.java b/src/share/classes/sun/net/httpserver/Code.java
index 032dbb7..6b86b8f 100644
--- a/src/share/classes/sun/net/httpserver/Code.java
+++ b/src/share/classes/sun/net/httpserver/Code.java
@@ -103,7 +103,7 @@
case HTTP_UNAVAILABLE: return " Service Unavailable";
case HTTP_GATEWAY_TIMEOUT: return " Gateway Timeout";
case HTTP_VERSION: return " HTTP Version Not Supported";
- default: return "";
+ default: return " ";
}
}
}
diff --git a/src/share/classes/sun/net/www/protocol/https/HttpsClient.java b/src/share/classes/sun/net/www/protocol/https/HttpsClient.java
index 19a2010..30e9fb0 100644
--- a/src/share/classes/sun/net/www/protocol/https/HttpsClient.java
+++ b/src/share/classes/sun/net/www/protocol/https/HttpsClient.java
@@ -192,22 +192,6 @@
return userAgent;
}
- // should remove once HttpClient.newHttpProxy is putback
- private static Proxy newHttpProxy(String proxyHost, int proxyPort) {
- InetSocketAddress saddr = null;
- final String phost = proxyHost;
- final int pport = proxyPort < 0 ? httpsPortNumber : proxyPort;
- try {
- saddr = java.security.AccessController.doPrivileged(new
- java.security.PrivilegedExceptionAction<InetSocketAddress>() {
- public InetSocketAddress run() {
- return new InetSocketAddress(phost, pport);
- }});
- } catch (java.security.PrivilegedActionException pae) {
- }
- return new Proxy(Proxy.Type.HTTP, saddr);
- }
-
// CONSTRUCTOR, FACTORY
@@ -251,7 +235,7 @@
throws IOException {
this(sf, url,
(proxyHost == null? null:
- HttpsClient.newHttpProxy(proxyHost, proxyPort)),
+ HttpClient.newHttpProxy(proxyHost, proxyPort, "https")),
connectTimeout);
}
@@ -261,6 +245,11 @@
HttpsClient(SSLSocketFactory sf, URL url, Proxy proxy,
int connectTimeout)
throws IOException {
+ PlatformLogger logger = HttpURLConnection.getHttpLogger();
+ if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
+ logger.finest("Creating new HttpsClient with url:" + url + " and proxy:" + proxy +
+ " with connect timeout:" + connectTimeout);
+ }
this.proxy = proxy;
setSSLSocketFactory(sf);
this.proxyDisabled = true;
@@ -317,7 +306,7 @@
return HttpsClient.New(sf, url, hv,
(proxyHost == null? null :
- HttpsClient.newHttpProxy(proxyHost, proxyPort)),
+ HttpClient.newHttpProxy(proxyHost, proxyPort, "https")),
useCache, connectTimeout, httpuc);
}
@@ -329,6 +318,11 @@
if (p == null) {
p = Proxy.NO_PROXY;
}
+ PlatformLogger logger = HttpURLConnection.getHttpLogger();
+ if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
+ logger.finest("Looking for HttpClient for URL " + url +
+ " and proxy value of " + p);
+ }
HttpsClient ret = null;
if (useCache) {
/* see if one's already around */
@@ -342,14 +336,13 @@
if (ret != null) {
if ((ret.proxy != null && ret.proxy.equals(p)) ||
- (ret.proxy == null && p == null)) {
+ (ret.proxy == null && p == Proxy.NO_PROXY)) {
synchronized (ret) {
ret.cachedHttpClient = true;
assert ret.inCache;
ret.inCache = false;
if (httpuc != null && ret.needsTunneling())
httpuc.setTunnelState(TUNNELING);
- PlatformLogger logger = HttpURLConnection.getHttpLogger();
if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
logger.finest("KeepAlive stream retrieved from the cache, " + ret);
}
@@ -360,6 +353,9 @@
// This should be fine as it is very rare that a connection
// to the same host will not use the same proxy.
synchronized(ret) {
+ if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
+ logger.finest("Not returning this connection to cache: " + ret);
+ }
ret.inCache = false;
ret.closeServer();
}
diff --git a/src/share/classes/sun/nio/ch/FileChannelImpl.java b/src/share/classes/sun/nio/ch/FileChannelImpl.java
index bb127e8..88ddab4 100644
--- a/src/share/classes/sun/nio/ch/FileChannelImpl.java
+++ b/src/share/classes/sun/nio/ch/FileChannelImpl.java
@@ -38,6 +38,7 @@
import java.nio.channels.NonWritableChannelException;
import java.nio.channels.OverlappingFileLockException;
import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.SelectableChannel;
import java.nio.channels.WritableByteChannel;
import java.security.AccessController;
import java.util.ArrayList;
@@ -407,30 +408,13 @@
//
private static volatile boolean fileSupported = true;
- private long transferToDirectly(long position, int icount,
- WritableByteChannel target)
+ private long transferToDirectlyInternal(long position, int icount,
+ WritableByteChannel target,
+ FileDescriptor targetFD)
throws IOException
{
- if (!transferSupported)
- return IOStatus.UNSUPPORTED;
-
- FileDescriptor targetFD = null;
- if (target instanceof FileChannelImpl) {
- if (!fileSupported)
- return IOStatus.UNSUPPORTED_CASE;
- targetFD = ((FileChannelImpl)target).fd;
- } else if (target instanceof SelChImpl) {
- // Direct transfer to pipe causes EINVAL on some configurations
- if ((target instanceof SinkChannelImpl) && !pipeSupported)
- return IOStatus.UNSUPPORTED_CASE;
- targetFD = ((SelChImpl)target).getFD();
- }
- if (targetFD == null)
- return IOStatus.UNSUPPORTED;
- int thisFDVal = IOUtil.fdVal(fd);
- int targetFDVal = IOUtil.fdVal(targetFD);
- if (thisFDVal == targetFDVal) // Not supported on some configurations
- return IOStatus.UNSUPPORTED;
+ assert !nd.transferToDirectlyNeedsPositionLock() ||
+ Thread.holdsLock(positionLock);
long n = -1;
int ti = -1;
@@ -440,7 +424,7 @@
if (!isOpen())
return -1;
do {
- n = transferTo0(thisFDVal, position, icount, targetFDVal);
+ n = transferTo0(fd, position, icount, targetFD);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
if (n == IOStatus.UNSUPPORTED_CASE) {
if (target instanceof SinkChannelImpl)
@@ -461,6 +445,54 @@
}
}
+ private long transferToDirectly(long position, int icount,
+ WritableByteChannel target)
+ throws IOException
+ {
+ if (!transferSupported)
+ return IOStatus.UNSUPPORTED;
+
+ FileDescriptor targetFD = null;
+ if (target instanceof FileChannelImpl) {
+ if (!fileSupported)
+ return IOStatus.UNSUPPORTED_CASE;
+ targetFD = ((FileChannelImpl)target).fd;
+ } else if (target instanceof SelChImpl) {
+ // Direct transfer to pipe causes EINVAL on some configurations
+ if ((target instanceof SinkChannelImpl) && !pipeSupported)
+ return IOStatus.UNSUPPORTED_CASE;
+
+ // Platform-specific restrictions. Now there is only one:
+ // Direct transfer to non-blocking channel could be forbidden
+ SelectableChannel sc = (SelectableChannel)target;
+ if (!nd.canTransferToDirectly(sc))
+ return IOStatus.UNSUPPORTED_CASE;
+
+ targetFD = ((SelChImpl)target).getFD();
+ }
+
+ if (targetFD == null)
+ return IOStatus.UNSUPPORTED;
+ int thisFDVal = IOUtil.fdVal(fd);
+ int targetFDVal = IOUtil.fdVal(targetFD);
+ if (thisFDVal == targetFDVal) // Not supported on some configurations
+ return IOStatus.UNSUPPORTED;
+
+ if (nd.transferToDirectlyNeedsPositionLock()) {
+ synchronized (positionLock) {
+ long pos = position();
+ try {
+ return transferToDirectlyInternal(position, icount,
+ target, targetFD);
+ } finally {
+ position(pos);
+ }
+ }
+ } else {
+ return transferToDirectlyInternal(position, icount, target, targetFD);
+ }
+ }
+
// Maximum size to map when using a mapped buffer
private static final long MAPPED_TRANSFER_SIZE = 8L*1024L*1024L;
@@ -1176,7 +1208,8 @@
private static native int unmap0(long address, long length);
// Transfers from src to dst, or returns -2 if kernel can't do that
- private native long transferTo0(int src, long position, long count, int dst);
+ private native long transferTo0(FileDescriptor src, long position,
+ long count, FileDescriptor dst);
// Sets or reports this file's position
// If offset is -1, the current position is returned
diff --git a/src/share/classes/sun/nio/ch/FileDispatcher.java b/src/share/classes/sun/nio/ch/FileDispatcher.java
index 6e5df22..5e9f82f 100644
--- a/src/share/classes/sun/nio/ch/FileDispatcher.java
+++ b/src/share/classes/sun/nio/ch/FileDispatcher.java
@@ -25,7 +25,9 @@
package sun.nio.ch;
-import java.io.*;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.nio.channels.SelectableChannel;
abstract class FileDispatcher extends NativeDispatcher {
@@ -53,4 +55,8 @@
*/
abstract FileDescriptor duplicateForMapping(FileDescriptor fd)
throws IOException;
+
+ abstract boolean canTransferToDirectly(SelectableChannel sc);
+
+ abstract boolean transferToDirectlyNeedsPositionLock();
}
diff --git a/src/share/classes/sun/nio/ch/Net.java b/src/share/classes/sun/nio/ch/Net.java
index 37823e9..598b484 100644
--- a/src/share/classes/sun/nio/ch/Net.java
+++ b/src/share/classes/sun/nio/ch/Net.java
@@ -50,30 +50,8 @@
// set to true if exclusive binding is on for Windows
private static final boolean exclusiveBind;
- static {
- int availLevel = isExclusiveBindAvailable();
- if (availLevel >= 0) {
- String exclBindProp =
- java.security.AccessController.doPrivileged(
- new PrivilegedAction<String>() {
- @Override
- public String run() {
- return System.getProperty(
- "sun.net.useExclusiveBind");
- }
- });
- if (exclBindProp != null) {
- exclusiveBind = exclBindProp.length() == 0 ?
- true : Boolean.parseBoolean(exclBindProp);
- } else if (availLevel == 1) {
- exclusiveBind = true;
- } else {
- exclusiveBind = false;
- }
- } else {
- exclusiveBind = false;
- }
- }
+ // set to true if the fast tcp loopback should be enabled on Windows
+ private static final boolean fastLoopback;
// -- Miscellaneous utilities --
@@ -391,6 +369,23 @@
}
}
+ public static boolean isFastTcpLoopbackRequested() {
+ String loopbackProp = java.security.AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ @Override
+ public String run() {
+ return System.getProperty("jdk.net.useFastTcpLoopback");
+ }
+ });
+ boolean enable;
+ if ("".equals(loopbackProp)) {
+ enable = true;
+ } else {
+ enable = Boolean.parseBoolean(loopbackProp);
+ }
+ return enable;
+ }
+
// -- Socket operations --
private static native boolean isIPv6Available0();
@@ -413,15 +408,16 @@
throws IOException {
boolean preferIPv6 = isIPv6Available() &&
(family != StandardProtocolFamily.INET);
- return IOUtil.newFD(socket0(preferIPv6, stream, false));
+ return IOUtil.newFD(socket0(preferIPv6, stream, false, fastLoopback));
}
static FileDescriptor serverSocket(boolean stream) {
- return IOUtil.newFD(socket0(isIPv6Available(), stream, true));
+ return IOUtil.newFD(socket0(isIPv6Available(), stream, true, fastLoopback));
}
// Due to oddities SO_REUSEADDR on windows reuse is ignored
- private static native int socket0(boolean preferIPv6, boolean stream, boolean reuse);
+ private static native int socket0(boolean preferIPv6, boolean stream, boolean reuse,
+ boolean fastLoopback);
public static void bind(FileDescriptor fd, InetAddress addr, int port)
throws IOException
@@ -634,4 +630,30 @@
POLLCONN = pollconnValue();
}
+ static {
+ int availLevel = isExclusiveBindAvailable();
+ if (availLevel >= 0) {
+ String exclBindProp =
+ java.security.AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ @Override
+ public String run() {
+ return System.getProperty(
+ "sun.net.useExclusiveBind");
+ }
+ });
+ if (exclBindProp != null) {
+ exclusiveBind = exclBindProp.length() == 0 ?
+ true : Boolean.parseBoolean(exclBindProp);
+ } else if (availLevel == 1) {
+ exclusiveBind = true;
+ } else {
+ exclusiveBind = false;
+ }
+ } else {
+ exclusiveBind = false;
+ }
+
+ fastLoopback = isFastTcpLoopbackRequested();
+ }
}
diff --git a/src/share/classes/sun/nio/ch/SocketAdaptor.java b/src/share/classes/sun/nio/ch/SocketAdaptor.java
index 9fd494b..d115b7a 100644
--- a/src/share/classes/sun/nio/ch/SocketAdaptor.java
+++ b/src/share/classes/sun/nio/ch/SocketAdaptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -321,12 +321,9 @@
}
public void sendUrgentData(int data) throws IOException {
- synchronized (sc.blockingLock()) {
- if (!sc.isBlocking())
- throw new IllegalBlockingModeException();
- int n = sc.sendOutOfBandData((byte)data);
- assert n == 1;
- }
+ int n = sc.sendOutOfBandData((byte) data);
+ if (n == 0)
+ throw new IOException("Socket buffer full");
}
public void setOOBInline(boolean on) throws SocketException {
diff --git a/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java b/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java
index 1d46e46..348fda5 100644
--- a/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java
+++ b/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java
@@ -1031,6 +1031,14 @@
"ebcdic-s-871+euro"
});
+ charset("x-IBM1166", "IBM1166",
+ new String[] {
+ "cp1166", // JDK historical
+ "ibm1166",
+ "ibm-1166",
+ "1166"
+ });
+
charset("IBM290", "IBM290",
new String[] {
"cp290",
diff --git a/src/share/classes/sun/print/RasterPrinterJob.java b/src/share/classes/sun/print/RasterPrinterJob.java
index 8d16510..1bb3dad 100644
--- a/src/share/classes/sun/print/RasterPrinterJob.java
+++ b/src/share/classes/sun/print/RasterPrinterJob.java
@@ -560,18 +560,8 @@
}
Media media = (Media)attSet.get(Media.class);
- if (media == null) {
- media =
- (Media)service.getDefaultAttributeValue(Media.class);
- }
- if (!(media instanceof MediaSizeName)) {
- media = MediaSizeName.NA_LETTER;
- }
- MediaSize size =
- MediaSize.getMediaSizeForName((MediaSizeName)media);
- if (size == null) {
- size = MediaSize.NA.LETTER;
- }
+ MediaSize size = getMediaSize(media, service, page);
+
Paper paper = new Paper();
float dim[] = size.getSize(1); //units == 1 to avoid FP error
double w = Math.rint((dim[0]*72.0)/Size2DSyntax.INCH);
@@ -580,9 +570,11 @@
MediaPrintableArea area =
(MediaPrintableArea)
attSet.get(MediaPrintableArea.class);
- double ix, iw, iy, ih;
+ if (area == null) {
+ area = getDefaultPrintableArea(page, w, h);
+ }
- if (area != null) {
+ double ix, iw, iy, ih;
// Should pass in same unit as updatePageAttributes
// to avoid rounding off errors.
ix = Math.rint(
@@ -593,8 +585,25 @@
area.getWidth(MediaPrintableArea.INCH) * DPI);
ih = Math.rint(
area.getHeight(MediaPrintableArea.INCH) * DPI);
+ paper.setImageableArea(ix, iy, iw, ih);
+ page.setPaper(paper);
+ return page;
}
- else {
+ protected MediaSize getMediaSize(Media media, PrintService service,
+ PageFormat page) {
+ if (media == null) {
+ media = (Media)service.getDefaultAttributeValue(Media.class);
+ }
+ if (!(media instanceof MediaSizeName)) {
+ media = MediaSizeName.NA_LETTER;
+ }
+ MediaSize size = MediaSize.getMediaSizeForName((MediaSizeName) media);
+ return size != null ? size : MediaSize.NA.LETTER;
+ }
+
+ protected MediaPrintableArea getDefaultPrintableArea(PageFormat page,
+ double w, double h) {
+ double ix, iw, iy, ih;
if (w >= 72.0 * 6.0) {
ix = 72.0;
iw = w - 2 * 72.0;
@@ -609,10 +618,9 @@
iy = h / 6.0;
ih = h * 0.75;
}
- }
- paper.setImageableArea(ix, iy, iw, ih);
- page.setPaper(paper);
- return page;
+
+ return new MediaPrintableArea((float) (ix / DPI), (float) (iy / DPI),
+ (float) (iw / DPI), (float) (ih / DPI), MediaPrintableArea.INCH);
}
protected void updatePageAttributes(PrintService service,
@@ -811,7 +819,7 @@
}
protected PageFormat getPageFormatFromAttributes() {
- if (attributes == null) {
+ if (attributes == null || attributes.isEmpty()) {
return null;
}
return attributeToPageFormat(getPrintService(), this.attributes);
diff --git a/src/share/classes/sun/reflect/generics/repository/ClassRepository.java b/src/share/classes/sun/reflect/generics/repository/ClassRepository.java
index d3b5451..edcdc86 100644
--- a/src/share/classes/sun/reflect/generics/repository/ClassRepository.java
+++ b/src/share/classes/sun/reflect/generics/repository/ClassRepository.java
@@ -42,8 +42,11 @@
public static final ClassRepository NONE = ClassRepository.make("Ljava/lang/Object;", null);
- private volatile Type superclass; // caches the generic superclass info
- private volatile Type[] superInterfaces; // caches the generic superinterface info
+ /** The generic superclass info. Lazily initialized. */
+ private volatile Type superclass;
+
+ /** The generic superinterface info. Lazily initialized. */
+ private volatile Type[] superInterfaces;
// private, to enforce use of static factory
private ClassRepository(String rawSig, GenericsFactory f) {
@@ -79,7 +82,7 @@
* with which the repository was created.
*/
- public Type getSuperclass(){
+ public Type getSuperclass() {
Type superclass = this.superclass;
if (superclass == null) { // lazily initialize superclass
Reifier r = getReifier(); // obtain visitor
@@ -88,25 +91,24 @@
// extract result from visitor and cache it
superclass = r.getResult();
this.superclass = superclass;
- }
+ }
return superclass; // return cached result
}
- public Type[] getSuperInterfaces(){
+ public Type[] getSuperInterfaces() {
Type[] superInterfaces = this.superInterfaces;
if (superInterfaces == null) { // lazily initialize super interfaces
// first, extract super interface subtree(s) from AST
TypeTree[] ts = getTree().getSuperInterfaces();
// create array to store reified subtree(s)
- Type[] sis = new Type[ts.length];
+ superInterfaces = new Type[ts.length];
// reify all subtrees
for (int i = 0; i < ts.length; i++) {
Reifier r = getReifier(); // obtain visitor
ts[i].accept(r);// reify subtree
// extract result from visitor and store it
- sis[i] = r.getResult();
+ superInterfaces[i] = r.getResult();
}
- superInterfaces = sis; // cache overall result
this.superInterfaces = superInterfaces;
}
return superInterfaces.clone(); // return cached result
diff --git a/src/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java b/src/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java
index 38af520..e530d57 100644
--- a/src/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java
+++ b/src/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java
@@ -42,7 +42,8 @@
public abstract class GenericDeclRepository<S extends Signature>
extends AbstractRepository<S> {
- private volatile TypeVariable<?>[] typeParams; // caches the formal type parameters
+ /** The formal type parameters. Lazily initialized. */
+ private volatile TypeVariable<?>[] typeParams;
protected GenericDeclRepository(String rawSig, GenericsFactory f) {
super(rawSig, f);
@@ -55,8 +56,7 @@
* If the corresponding field is non-null, it is returned.
* If not, it is created lazily. This is done by selecting the appropriate
* part of the tree and transforming it into a reflective object
- * using a visitor.
- * a visitor, which is created by feeding it the factory
+ * using a visitor, which is created by feeding it the factory
* with which the repository was created.
*/
@@ -64,22 +64,21 @@
* Return the formal type parameters of this generic declaration.
* @return the formal type parameters of this generic declaration
*/
- public TypeVariable<?>[] getTypeParameters(){
- TypeVariable[] typeParams = this.typeParams;
+ public TypeVariable<?>[] getTypeParameters() {
+ TypeVariable<?>[] typeParams = this.typeParams;
if (typeParams == null) { // lazily initialize type parameters
// first, extract type parameter subtree(s) from AST
FormalTypeParameter[] ftps = getTree().getFormalTypeParameters();
// create array to store reified subtree(s)
- TypeVariable<?>[] tps = new TypeVariable<?>[ftps.length];
+ typeParams = new TypeVariable<?>[ftps.length];
// reify all subtrees
for (int i = 0; i < ftps.length; i++) {
Reifier r = getReifier(); // obtain visitor
ftps[i].accept(r); // reify subtree
// extract result from visitor and store it
- tps[i] = (TypeVariable<?>) r.getResult();
+ typeParams[i] = (TypeVariable<?>) r.getResult();
}
- typeParams = tps; // cache overall result
- this.typeParams = typeParams;
+ this.typeParams = typeParams; // cache overall result
}
return typeParams.clone(); // return cached result
}
diff --git a/src/share/classes/sun/reflect/generics/scope/AbstractScope.java b/src/share/classes/sun/reflect/generics/scope/AbstractScope.java
index 872360b..6a18271 100644
--- a/src/share/classes/sun/reflect/generics/scope/AbstractScope.java
+++ b/src/share/classes/sun/reflect/generics/scope/AbstractScope.java
@@ -42,7 +42,9 @@
implements Scope {
private final D recvr; // the declaration whose scope this instance represents
- private volatile Scope enclosingScope; // the enclosing scope of this scope
+
+ /** The enclosing scope of this scope. Lazily initialized. */
+ private volatile Scope enclosingScope;
/**
* Constructor. Takes a reflective object whose scope the newly
diff --git a/src/share/classes/sun/security/krb5/KrbApReq.java b/src/share/classes/sun/security/krb5/KrbApReq.java
index b88e42d..fbd0557 100644
--- a/src/share/classes/sun/security/krb5/KrbApReq.java
+++ b/src/share/classes/sun/security/krb5/KrbApReq.java
@@ -60,22 +60,12 @@
private static boolean DEBUG = Krb5.DEBUG;
private static final char[] hexConst = "0123456789ABCDEF".toCharArray();
- private static final MessageDigest md;
-
- static {
- try {
- md = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException ex) {
- throw new RuntimeException("Impossible");
- }
- }
-
/**
* Constructs an AP-REQ message to send to the peer.
* @param tgsCred the <code>Credentials</code> to be used to construct the
* AP Request protocol message.
* @param mutualRequired Whether mutual authentication is required
- * @param useSubkey Whether the subkey is to be used to protect this
+ * @param useSubKey Whether the subkey is to be used to protect this
* specific application session. If this is not set then the
* session key from the ticket will be used.
* @throws KrbException for any Kerberos protocol specific error
@@ -99,10 +89,10 @@
* @param tgsCred the <code>Credentials</code> to be used to construct the
* AP Request protocol message.
* @param mutualRequired Whether mutual authentication is required
- * @param useSubkey Whether the subkey is to be used to protect this
+ * @param useSubKey Whether the subkey is to be used to protect this
* specific application session. If this is not set then the
* session key from the ticket will be used.
- * @param checksum checksum of the the application data that accompanies
+ * @param cksum checksum of the the application data that accompanies
* the KRB_AP_REQ.
* @throws KrbException for any Kerberos protocol specific error
* @throws IOException for any IO related errors
@@ -142,8 +132,8 @@
* Constructs an AP-REQ message from the bytes received from the
* peer.
* @param message The message received from the peer
- * @param keys <code>EncrtyptionKey</code>s to decrypt the message;
- * key selected will depend on etype used to encrypte data
+ * @param cred <code>KrbAcceptCredential</code> containing keys to decrypt
+ * the message; key selected will depend on etype used to encrypt data
* @throws KrbException for any Kerberos protocol specific error
* @throws IOException for any IO related errors
* (e.g. socket operations)
@@ -311,7 +301,14 @@
if (!authenticator.ctime.inClockSkew())
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
- byte[] hash = md.digest(apReqMessg.authenticator.cipher);
+ byte[] hash;
+ try {
+ hash = MessageDigest.getInstance("MD5")
+ .digest(apReqMessg.authenticator.cipher);
+ } catch (NoSuchAlgorithmException ex) {
+ throw new AssertionError("Impossible");
+ }
+
char[] h = new char[hash.length * 2];
for (int i=0; i<hash.length; i++) {
h[2*i] = hexConst[(hash[i]&0xff)>>4];
diff --git a/src/share/classes/sun/security/pkcs11/Config.java b/src/share/classes/sun/security/pkcs11/Config.java
index f4bcc58..01d3b37 100644
--- a/src/share/classes/sun/security/pkcs11/Config.java
+++ b/src/share/classes/sun/security/pkcs11/Config.java
@@ -584,16 +584,24 @@
}
private String parseLine() throws IOException {
- String s = parseWord();
+ // allow quoted string as part of line
+ String s = null;
while (true) {
int token = nextToken();
if ((token == TT_EOL) || (token == TT_EOF)) {
break;
}
- if (token != TT_WORD) {
+ if (token != TT_WORD && token != '\"') {
throw excToken("Unexpected value");
}
- s = s + " " + st.sval;
+ if (s == null) {
+ s = st.sval;
+ } else {
+ s = s + " " + st.sval;
+ }
+ }
+ if (s == null) {
+ throw excToken("Unexpected empty line");
}
return s;
}
@@ -653,7 +661,9 @@
//
private String parseLibrary(String keyword) throws IOException {
- String lib = parseStringEntry(keyword);
+ checkDup(keyword);
+ parseEquals();
+ String lib = parseLine();
lib = expand(lib);
int i = lib.indexOf("/$ISA/");
if (i != -1) {
diff --git a/src/share/classes/sun/security/pkcs11/SessionManager.java b/src/share/classes/sun/security/pkcs11/SessionManager.java
index 798624c..571f001 100644
--- a/src/share/classes/sun/security/pkcs11/SessionManager.java
+++ b/src/share/classes/sun/security/pkcs11/SessionManager.java
@@ -90,6 +90,7 @@
// maximum number of active sessions during this invocation, for debugging
private int maxActiveSessions;
+ private Object maxActiveSessionsLock;
// flags to use in the C_OpenSession() call
private final long openSessionFlags;
@@ -113,6 +114,9 @@
this.token = token;
this.objSessions = new Pool(this);
this.opSessions = new Pool(this);
+ if (debug != null) {
+ maxActiveSessionsLock = new Object();
+ }
}
// returns whether only a fairly low number of sessions are
@@ -212,7 +216,7 @@
Session session = new Session(token, id);
activeSessions.incrementAndGet();
if (debug != null) {
- synchronized(this) {
+ synchronized(maxActiveSessionsLock) {
if (activeSessions.get() > maxActiveSessions) {
maxActiveSessions = activeSessions.get();
if (maxActiveSessions % 10 == 0) {
diff --git a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
index b63ed6b..e3759c1 100644
--- a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
+++ b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
@@ -905,7 +905,7 @@
private static ObjectIdentifier mapPBEAlgorithmToOID(String algorithm)
throws NoSuchAlgorithmException {
// Check for PBES2 algorithms
- if (algorithm.toLowerCase().startsWith("pbewithhmacsha")) {
+ if (algorithm.toLowerCase(Locale.ENGLISH).startsWith("pbewithhmacsha")) {
return pbes2_OID;
}
return AlgorithmId.get(algorithm).getOID();
@@ -1600,23 +1600,22 @@
Entry entry = entries.get(alias);
// certificate chain
- int chainLen = 1;
- Certificate[] certs = null;
+ Certificate[] certs;
if (entry instanceof PrivateKeyEntry) {
PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
- if (keyEntry.chain == null) {
- chainLen = 0;
- } else {
- chainLen = keyEntry.chain.length;
- }
- certs = keyEntry.chain;
-
+ if (keyEntry.chain != null) {
+ certs = keyEntry.chain;
+ } else {
+ certs = new Certificate[0];
+ }
} else if (entry instanceof CertEntry) {
- certs = new Certificate[]{((CertEntry) entry).cert};
+ certs = new Certificate[]{((CertEntry) entry).cert};
+ } else {
+ certs = new Certificate[0];
}
- for (int i = 0; i < chainLen; i++) {
+ for (int i = 0; i < certs.length; i++) {
// create SafeBag of Type CertBag
DerOutputStream safeBag = new DerOutputStream();
safeBag.putOID(CertBag_OID);
diff --git a/src/share/classes/sun/security/provider/ConfigFile.java b/src/share/classes/sun/security/provider/ConfigFile.java
index f3c041a..6e243c4 100644
--- a/src/share/classes/sun/security/provider/ConfigFile.java
+++ b/src/share/classes/sun/security/provider/ConfigFile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -451,7 +451,7 @@
// controlFlag (required, optional, etc)
LoginModuleControlFlag controlFlag;
- String sflag = match("controlFlag").toUpperCase();
+ String sflag = match("controlFlag").toUpperCase(Locale.ENGLISH);
switch (sflag) {
case "REQUIRED":
controlFlag = LoginModuleControlFlag.REQUIRED;
diff --git a/src/share/classes/sun/security/provider/PolicyParser.java b/src/share/classes/sun/security/provider/PolicyParser.java
index b13345f..8d037b4 100644
--- a/src/share/classes/sun/security/provider/PolicyParser.java
+++ b/src/share/classes/sun/security/provider/PolicyParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -707,7 +707,7 @@
} catch (PropertyExpander.ExpandException peee) {
throw new IOException(peee.getLocalizedMessage());
}
- properties.put(key.toLowerCase(), value);
+ properties.put(key.toLowerCase(Locale.ENGLISH), value);
}
return properties;
diff --git a/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java b/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java
index d05d22f..db36c0e 100644
--- a/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java
+++ b/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java
@@ -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
@@ -224,7 +224,8 @@
if (extVal == null) {
if (debug != null) {
debug.println("AdaptableX509CertSelector.match: "
- + "no subject key ID extension");
+ + "no subject key ID extension. Subject: "
+ + xcert.getSubjectX500Principal());
}
return true;
}
@@ -234,7 +235,9 @@
!Arrays.equals(ski, certSubjectKeyID)) {
if (debug != null) {
debug.println("AdaptableX509CertSelector.match: "
- + "subject key IDs don't match");
+ + "subject key IDs don't match. "
+ + "Expected: " + Arrays.toString(ski) + " "
+ + "Cert's: " + Arrays.toString(certSubjectKeyID));
}
return false;
}
diff --git a/src/share/classes/sun/security/provider/certpath/Builder.java b/src/share/classes/sun/security/provider/certpath/Builder.java
index e053b20..84cbe66 100644
--- a/src/share/classes/sun/security/provider/certpath/Builder.java
+++ b/src/share/classes/sun/security/provider/certpath/Builder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -435,7 +435,12 @@
if (selector.match(targetCert) && !X509CertImpl.isSelfSigned
(targetCert, buildParams.sigProvider())) {
if (debug != null) {
- debug.println("Builder.addMatchingCerts: adding target cert");
+ debug.println("Builder.addMatchingCerts: " +
+ "adding target cert" +
+ "\n SN: " + Debug.toHexString(
+ targetCert.getSerialNumber()) +
+ "\n Subject: " + targetCert.getSubjectX500Principal() +
+ "\n Issuer: " + targetCert.getIssuerX500Principal());
}
return resultCerts.add(targetCert);
}
diff --git a/src/share/classes/sun/security/provider/certpath/ConstraintsChecker.java b/src/share/classes/sun/security/provider/certpath/ConstraintsChecker.java
index a08c990..28fb322 100644
--- a/src/share/classes/sun/security/provider/certpath/ConstraintsChecker.java
+++ b/src/share/classes/sun/security/provider/certpath/ConstraintsChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -145,8 +145,8 @@
if (prevNC != null && ((i == certPathLength) ||
!X509CertImpl.isSelfIssued(currCert))) {
if (debug != null) {
- debug.println("prevNC = " + prevNC);
- debug.println("currDN = " + currCert.getSubjectX500Principal());
+ debug.println("prevNC = " + prevNC +
+ ", currDN = " + currCert.getSubjectX500Principal());
}
try {
@@ -184,8 +184,8 @@
currCertImpl.getNameConstraintsExtension();
if (debug != null) {
- debug.println("prevNC = " + prevNC);
- debug.println("newNC = " + String.valueOf(newConstraints));
+ debug.println("prevNC = " + prevNC +
+ ", newNC = " + String.valueOf(newConstraints));
}
// if there are no previous name constraints, we just return the
@@ -225,8 +225,8 @@
String msg = "basic constraints";
if (debug != null) {
debug.println("---checking " + msg + "...");
- debug.println("i = " + i);
- debug.println("maxPathLength = " + maxPathLength);
+ debug.println("i = " + i +
+ ", maxPathLength = " + maxPathLength);
}
/* check if intermediate cert */
diff --git a/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java b/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java
index 8ce1076..7b1076e 100644
--- a/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java
+++ b/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java
@@ -320,6 +320,14 @@
Set<TrustAnchor> trustAnchors, List<CertStore> certStores,
Date validity) throws CRLException, IOException {
+ if (debug != null) {
+ debug.println("DistributionPointFetcher.verifyCRL: " +
+ "checking revocation status for" +
+ "\n SN: " + Debug.toHexString(certImpl.getSerialNumber()) +
+ "\n Subject: " + certImpl.getSubjectX500Principal() +
+ "\n Issuer: " + certImpl.getIssuerX500Principal());
+ }
+
boolean indirectCRL = false;
X509CRLImpl crlImpl = X509CRLImpl.toImpl(crl);
IssuingDistributionPointExtension idpExt =
@@ -363,7 +371,9 @@
}
} else if (crlIssuer.equals(certIssuer) == false) {
if (debug != null) {
- debug.println("crl issuer does not equal cert issuer");
+ debug.println("crl issuer does not equal cert issuer.\n" +
+ "crl issuer: " + crlIssuer + "\n" +
+ "cert issuer: " + certIssuer);
}
return false;
} else {
diff --git a/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java
index 16892c4..7f30d3b 100644
--- a/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java
+++ b/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -209,7 +209,8 @@
* getMatchingEECerts
*/
if (debug != null) {
- debug.println("ForwardBuilder.getMatchingCACerts(): ca is target");
+ debug.println("ForwardBuilder.getMatchingCACerts(): " +
+ "the target is a CA");
}
if (caTargetSelector == null) {
@@ -291,8 +292,14 @@
for (X509Certificate trustedCert : trustedCerts) {
if (sel.match(trustedCert)) {
if (debug != null) {
- debug.println("ForwardBuilder.getMatchingCACerts: "
- + "found matching trust anchor");
+ debug.println("ForwardBuilder.getMatchingCACerts: " +
+ "found matching trust anchor." +
+ "\n SN: " +
+ Debug.toHexString(trustedCert.getSerialNumber()) +
+ "\n Subject: " +
+ trustedCert.getSubjectX500Principal() +
+ "\n Issuer: " +
+ trustedCert.getIssuerX500Principal());
}
if (caCerts.add(trustedCert) && !searchAllCertStores) {
return;
diff --git a/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java b/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java
index db5edda..cfffba8 100644
--- a/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java
+++ b/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -30,6 +30,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Set;
+import java.util.StringJoiner;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidatorException;
import java.security.cert.PKIXCertPathChecker;
@@ -88,20 +89,25 @@
* current certificate of this loop to be the previous certificate
* of the next loop. The state is initialized during first loop.
*/
- if (debug != null)
- debug.println("Checking cert" + (i+1) + " ...");
-
X509Certificate currCert = reversedCertList.get(i);
+
+ if (debug != null) {
+ debug.println("Checking cert" + (i+1) + " - Subject: " +
+ currCert.getSubjectX500Principal());
+ }
+
Set<String> unresCritExts = currCert.getCriticalExtensionOIDs();
if (unresCritExts == null) {
unresCritExts = Collections.<String>emptySet();
}
if (debug != null && !unresCritExts.isEmpty()) {
- debug.println("Set of critical extensions:");
+ StringJoiner joiner = new StringJoiner(", ", "{", "}");
for (String oid : unresCritExts) {
- debug.println(oid);
+ joiner.add(oid);
}
+ debug.println("Set of critical extensions: " +
+ joiner.toString());
}
for (int j = 0; j < certPathCheckers.size(); j++) {
diff --git a/src/share/classes/sun/security/provider/certpath/RevocationChecker.java b/src/share/classes/sun/security/provider/certpath/RevocationChecker.java
index f38e7dc..61d5fd7 100644
--- a/src/share/classes/sun/security/provider/certpath/RevocationChecker.java
+++ b/src/share/classes/sun/security/provider/certpath/RevocationChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -343,11 +343,17 @@
PublicKey pubKey, boolean crlSignFlag)
throws CertPathValidatorException
{
+ if (debug != null) {
+ debug.println("RevocationChecker.check: checking cert" +
+ "\n SN: " + Debug.toHexString(xcert.getSerialNumber()) +
+ "\n Subject: " + xcert.getSubjectX500Principal() +
+ "\n Issuer: " + xcert.getIssuerX500Principal());
+ }
try {
if (onlyEE && xcert.getBasicConstraints() != -1) {
if (debug != null) {
- debug.println("Skipping revocation check, not end " +
- "entity cert");
+ debug.println("Skipping revocation check; cert is not " +
+ "an end entity cert");
}
return;
}
diff --git a/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java b/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java
index 3950760..3f802e2 100644
--- a/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java
+++ b/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -136,7 +136,8 @@
PKIXCertPathBuilderResult result = buildCertPath(false, adjList);
if (result == null) {
if (debug != null) {
- debug.println("SunCertPathBuilder.engineBuild: 2nd pass");
+ debug.println("SunCertPathBuilder.engineBuild: 2nd pass; " +
+ "try building again searching all certstores");
}
// try again
adjList.clear();
diff --git a/src/share/classes/sun/security/ssl/ClientHandshaker.java b/src/share/classes/sun/security/ssl/ClientHandshaker.java
index fcbcf72..4b887cb 100644
--- a/src/share/classes/sun/security/ssl/ClientHandshaker.java
+++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java
@@ -59,6 +59,10 @@
*/
final class ClientHandshaker extends Handshaker {
+ // constants for subject alt names of type DNS and IP
+ private final static int ALTNAME_DNS = 2;
+ private final static int ALTNAME_IP = 7;
+
// the server's public key from its certificate.
private PublicKey serverKey;
@@ -837,6 +841,11 @@
} else {
warningSE(Alerts.alert_no_certificate);
}
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println(
+ "Warning: no suitable certificate found - " +
+ "continuing without client authentication");
+ }
}
//
@@ -1516,20 +1525,49 @@
return true;
}
- // check the iPAddress field in subjectAltName extension
- Object thisIPAddress = getSubjectAltName(thisCert, 7); // 7: iPAddress
- Object prevIPAddress = getSubjectAltName(prevCert, 7);
- if (thisIPAddress != null && prevIPAddress!= null) {
- // only allow the exactly match
- return Objects.equals(thisIPAddress, prevIPAddress);
+ // check subject alternative names
+ Collection<List<?>> thisSubjectAltNames = null;
+ try {
+ thisSubjectAltNames = thisCert.getSubjectAlternativeNames();
+ } catch (CertificateParsingException cpe) {
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println(
+ "Attempt to obtain subjectAltNames extension failed!");
+ }
}
- // check the dNSName field in subjectAltName extension
- Object thisDNSName = getSubjectAltName(thisCert, 2); // 2: dNSName
- Object prevDNSName = getSubjectAltName(prevCert, 2);
- if (thisDNSName != null && prevDNSName!= null) {
- // only allow the exactly match
- return Objects.equals(thisDNSName, prevDNSName);
+ Collection<List<?>> prevSubjectAltNames = null;
+ try {
+ prevSubjectAltNames = prevCert.getSubjectAlternativeNames();
+ } catch (CertificateParsingException cpe) {
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println(
+ "Attempt to obtain subjectAltNames extension failed!");
+ }
+ }
+
+ if ((thisSubjectAltNames != null) && (prevSubjectAltNames != null)) {
+ // check the iPAddress field in subjectAltName extension
+ Collection<String> thisSubAltIPAddrs =
+ getSubjectAltNames(thisSubjectAltNames, ALTNAME_IP);
+ Collection<String> prevSubAltIPAddrs =
+ getSubjectAltNames(prevSubjectAltNames, ALTNAME_IP);
+ if ((thisSubAltIPAddrs != null) && (prevSubAltIPAddrs != null) &&
+ (isEquivalent(thisSubAltIPAddrs, prevSubAltIPAddrs))) {
+
+ return true;
+ }
+
+ // check the dNSName field in subjectAltName extension
+ Collection<String> thisSubAltDnsNames =
+ getSubjectAltNames(thisSubjectAltNames, ALTNAME_DNS);
+ Collection<String> prevSubAltDnsNames =
+ getSubjectAltNames(prevSubjectAltNames, ALTNAME_DNS);
+ if ((thisSubAltDnsNames != null) && (prevSubAltDnsNames != null) &&
+ (isEquivalent(thisSubAltDnsNames, prevSubAltDnsNames))) {
+
+ return true;
+ }
}
// check the certificate subject and issuer
@@ -1550,29 +1588,43 @@
/*
* Returns the subject alternative name of the specified type in the
* subjectAltNames extension of a certificate.
+ *
+ * Note that only those subjectAltName types that use String data
+ * should be passed into this function.
*/
- private static Object getSubjectAltName(X509Certificate cert, int type) {
- Collection<List<?>> subjectAltNames;
+ private static Collection<String> getSubjectAltNames(
+ Collection<List<?>> subjectAltNames, int type) {
- try {
- subjectAltNames = cert.getSubjectAlternativeNames();
- } catch (CertificateParsingException cpe) {
- if (debug != null && Debug.isOn("handshake")) {
- System.out.println(
- "Attempt to obtain subjectAltNames extension failed!");
- }
- return null;
- }
-
- if (subjectAltNames != null) {
- for (List<?> subjectAltName : subjectAltNames) {
- int subjectAltNameType = (Integer)subjectAltName.get(0);
- if (subjectAltNameType == type) {
- return subjectAltName.get(1);
+ HashSet<String> subAltDnsNames = null;
+ for (List<?> subjectAltName : subjectAltNames) {
+ int subjectAltNameType = (Integer)subjectAltName.get(0);
+ if (subjectAltNameType == type) {
+ String subAltDnsName = (String)subjectAltName.get(1);
+ if ((subAltDnsName != null) && !subAltDnsName.isEmpty()) {
+ if (subAltDnsNames == null) {
+ subAltDnsNames =
+ new HashSet<>(subjectAltNames.size());
+ }
+ subAltDnsNames.add(subAltDnsName);
}
}
}
- return null;
+ return subAltDnsNames;
+ }
+
+ private static boolean isEquivalent(Collection<String> thisSubAltNames,
+ Collection<String> prevSubAltNames) {
+
+ for (String thisSubAltName : thisSubAltNames) {
+ for (String prevSubAltName : prevSubAltNames) {
+ // Only allow the exactly match. Check no wildcard character.
+ if (thisSubAltName.equalsIgnoreCase(prevSubAltName)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
}
}
diff --git a/src/share/classes/sun/security/ssl/HandshakeMessage.java b/src/share/classes/sun/security/ssl/HandshakeMessage.java
index cc910a2..59b4b90 100644
--- a/src/share/classes/sun/security/ssl/HandshakeMessage.java
+++ b/src/share/classes/sun/security/ssl/HandshakeMessage.java
@@ -243,6 +243,7 @@
protocolVersion = ProtocolVersion.valueOf(s.getInt8(), s.getInt8());
clnt_random = new RandomCookie(s);
sessionId = new SessionId(s.getBytes8());
+ sessionId.checkLength(protocolVersion);
cipherSuites = new CipherSuiteList(s);
compression_methods = s.getBytes8();
if (messageLength() != messageLength) {
@@ -355,6 +356,7 @@
input.getInt8());
svr_random = new RandomCookie(input);
sessionId = new SessionId(input.getBytes8());
+ sessionId.checkLength(protocolVersion);
cipherSuite = CipherSuite.valueOf(input.getInt8(), input.getInt8());
compression_method = (byte)input.getInt8();
if (messageLength() != messageLength) {
@@ -490,11 +492,14 @@
void print(PrintStream s) throws IOException {
s.println("*** Certificate chain");
- if (debug != null && Debug.isOn("verbose")) {
- for (int i = 0; i < chain.length; i++)
+ if (chain.length == 0) {
+ s.println("<Empty>");
+ } else if (debug != null && Debug.isOn("verbose")) {
+ for (int i = 0; i < chain.length; i++) {
s.println("chain [" + i + "] = " + chain[i]);
- s.println("***");
+ }
}
+ s.println("***");
}
X509Certificate[] getCertificateChain() {
diff --git a/src/share/classes/sun/security/ssl/SessionId.java b/src/share/classes/sun/security/ssl/SessionId.java
index 39bdd67..063e86d 100644
--- a/src/share/classes/sun/security/ssl/SessionId.java
+++ b/src/share/classes/sun/security/ssl/SessionId.java
@@ -27,6 +27,7 @@
package sun.security.ssl;
import java.security.SecureRandom;
+import javax.net.ssl.SSLProtocolException;
/**
* Encapsulates an SSL session ID. SSL Session IDs are not reused by
@@ -41,6 +42,7 @@
final
class SessionId
{
+ static int MAX_LENGTH = 32;
private byte sessionId []; // max 32 bytes
/** Constructs a new session ID ... perhaps for a rejoinable session */
@@ -114,4 +116,19 @@
}
return true;
}
+
+ /**
+ * Checks the length of the session ID to make sure it sits within
+ * the range called out in the specification
+ */
+ void checkLength(ProtocolVersion pv) throws SSLProtocolException {
+ // As of today all versions of TLS have a 32-byte maximum length.
+ // In the future we can do more here to support protocol versions
+ // that may have longer max lengths.
+ if (sessionId.length > MAX_LENGTH) {
+ throw new SSLProtocolException("Invalid session ID length (" +
+ sessionId.length + " bytes)");
+ }
+ }
+
}
diff --git a/src/share/classes/sun/security/tools/keytool/Main.java b/src/share/classes/sun/security/tools/keytool/Main.java
index 7cd92d6..efbbf5b 100644
--- a/src/share/classes/sun/security/tools/keytool/Main.java
+++ b/src/share/classes/sun/security/tools/keytool/Main.java
@@ -1494,7 +1494,7 @@
boolean useDefaultPBEAlgorithm = true;
SecretKey secKey = null;
- if (keyAlgName.toUpperCase().startsWith("PBE")) {
+ if (keyAlgName.toUpperCase(Locale.ENGLISH).startsWith("PBE")) {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");
// User is prompted for PBE credential
diff --git a/src/share/classes/sun/swing/SwingUtilities2.java b/src/share/classes/sun/swing/SwingUtilities2.java
index 399a2fc..af8f626 100644
--- a/src/share/classes/sun/swing/SwingUtilities2.java
+++ b/src/share/classes/sun/swing/SwingUtilities2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2014, 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
@@ -33,6 +33,7 @@
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.print.PrinterGraphics;
+import java.text.BreakIterator;
import java.text.CharacterIterator;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
@@ -464,16 +465,15 @@
}
}
if (needsTextLayout) {
- FontRenderContext frc = getFontRenderContext(c, fm);
AttributedString aString = new AttributedString(string);
if (c != null) {
aString.addAttribute(TextAttribute.NUMERIC_SHAPING,
c.getClientProperty(TextAttribute.NUMERIC_SHAPING));
}
- LineBreakMeasurer measurer =
- new LineBreakMeasurer(aString.getIterator(), frc);
- int nChars = measurer.nextOffset(availTextWidth);
- string = string.substring(0, nChars);
+ LineBreakMeasurer measurer = new LineBreakMeasurer(
+ aString.getIterator(), BreakIterator.getCharacterInstance(),
+ getFontRenderContext(c, fm));
+ string = string.substring(0, measurer.nextOffset(availTextWidth));
}
return string + clipString;
diff --git a/src/share/classes/sun/swing/plaf/synth/DefaultSynthStyle.java b/src/share/classes/sun/swing/plaf/synth/DefaultSynthStyle.java
index 7d25806..2262ef8 100644
--- a/src/share/classes/sun/swing/plaf/synth/DefaultSynthStyle.java
+++ b/src/share/classes/sun/swing/plaf/synth/DefaultSynthStyle.java
@@ -28,7 +28,6 @@
import java.awt.*;
import java.util.*;
import javax.swing.*;
-import javax.swing.border.Border;
import javax.swing.plaf.*;
/**
@@ -44,7 +43,8 @@
* @author Scott Violet
*/
public class DefaultSynthStyle extends SynthStyle implements Cloneable {
- private static final String PENDING = "Pending";
+
+ private static final Object PENDING = new Object();
/**
* Should the component be opaque?
diff --git a/src/share/classes/sun/text/resources/de/FormatData_de.java b/src/share/classes/sun/text/resources/de/FormatData_de.java
index 435a797..85c079c 100644
--- a/src/share/classes/sun/text/resources/de/FormatData_de.java
+++ b/src/share/classes/sun/text/resources/de/FormatData_de.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -142,7 +142,7 @@
new String[] {
"Jan", // abb january
"Feb", // abb february
- "Mrz", // abb march
+ "M\u00e4r", // abb march
"Apr", // abb april
"Mai", // abb may
"Jun", // abb june
diff --git a/src/share/classes/sun/text/resources/fi/FormatData_fi.java b/src/share/classes/sun/text/resources/fi/FormatData_fi.java
index f80df88..c9a520a 100644
--- a/src/share/classes/sun/text/resources/fi/FormatData_fi.java
+++ b/src/share/classes/sun/text/resources/fi/FormatData_fi.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -295,8 +295,8 @@
},
{ "DatePatterns",
new String[] {
- "d. MMMM'ta 'yyyy", // full date pattern
- "d. MMMM'ta 'yyyy", // long date pattern
+ "d. MMMM yyyy", // full date pattern
+ "d. MMMM yyyy", // long date pattern
"d.M.yyyy", // medium date pattern
"d.M.yyyy", // short date pattern
}
diff --git a/src/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java b/src/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java
index 77f7b84..49729c8 100644
--- a/src/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java
+++ b/src/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -30,6 +30,7 @@
import java.security.PrivilegedAction;
import java.text.spi.BreakIteratorProvider;
import java.text.spi.CollatorProvider;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.ResourceBundle;
@@ -103,6 +104,9 @@
protected Set<String> createLanguageTagSet(String category) {
ResourceBundle rb = ResourceBundle.getBundle("sun.util.cldr.CLDRLocaleDataMetaInfo", Locale.ROOT);
String supportedLocaleString = rb.getString(category);
+ if (supportedLocaleString == null) {
+ return Collections.emptySet();
+ }
Set<String> tagset = new HashSet<>();
StringTokenizer tokens = new StringTokenizer(supportedLocaleString);
while (tokens.hasMoreTokens()) {
diff --git a/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java b/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
index 50473cd..934606e 100644
--- a/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
+++ b/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -34,6 +34,7 @@
import java.text.spi.DateFormatSymbolsProvider;
import java.text.spi.DecimalFormatSymbolsProvider;
import java.text.spi.NumberFormatProvider;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
@@ -356,6 +357,9 @@
protected Set<String> createLanguageTagSet(String category) {
String supportedLocaleString = LocaleDataMetaInfo.getSupportedLocaleString(category);
+ if (supportedLocaleString == null) {
+ return Collections.emptySet();
+ }
Set<String> tagset = new HashSet<>();
StringTokenizer tokens = new StringTokenizer(supportedLocaleString);
while (tokens.hasMoreTokens()) {
diff --git a/src/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template b/src/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
index 17d9af6..885e659 100644
--- a/src/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
+++ b/src/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -57,6 +57,12 @@
resourceNameToLocales.put("CollationData",
" #CollationData_ENLocales# | #CollationData_NonENLocales# ");
+ resourceNameToLocales.put("BreakIteratorInfo",
+ " #BreakIteratorInfo_ENLocales# | #BreakIteratorInfo_NonENLocales# ");
+
+ resourceNameToLocales.put("BreakIteratorRules",
+ " #BreakIteratorRules_ENLocales# | #BreakIteratorRules_NonENLocales# ");
+
resourceNameToLocales.put("TimeZoneNames",
" #TimeZoneNames_ENLocales# | #TimeZoneNames_NonENLocales# ");
diff --git a/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java b/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
index b7ba736..26dfe13 100644
--- a/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
+++ b/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -295,7 +295,7 @@
* A utility method for implementing the default LocaleServiceProvider.isSupportedLocale
* for the JRE, CLDR, and FALLBACK adapters.
*/
- static boolean isSupportedLocale(Locale locale, LocaleProviderAdapter.Type type, Set<String> langtags) {
+ public static boolean isSupportedLocale(Locale locale, LocaleProviderAdapter.Type type, Set<String> langtags) {
assert type == Type.JRE || type == Type.CLDR || type == Type.FALLBACK;
if (Locale.ROOT.equals(locale)) {
return true;
diff --git a/src/share/classes/sun/util/locale/provider/LocaleResources.java b/src/share/classes/sun/util/locale/provider/LocaleResources.java
index d89a885..5622078 100644
--- a/src/share/classes/sun/util/locale/provider/LocaleResources.java
+++ b/src/share/classes/sun/util/locale/provider/LocaleResources.java
@@ -47,6 +47,7 @@
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -250,17 +251,17 @@
return (String) localeName;
}
- String[] getTimeZoneNames(String key, int size) {
+ String[] getTimeZoneNames(String key) {
String[] names = null;
- String cacheKey = TIME_ZONE_NAMES + size + '.' + key;
+ String cacheKey = TIME_ZONE_NAMES + '.' + key;
removeEmptyReferences();
ResourceReference data = cache.get(cacheKey);
- if (data == null || ((names = (String[]) data.get()) == null)) {
+ if (Objects.isNull(data) || Objects.isNull((names = (String[]) data.get()))) {
TimeZoneNamesBundle tznb = localeData.getTimeZoneNames(locale);
if (tznb.containsKey(key)) {
- names = tznb.getStringArray(key, size);
+ names = tznb.getStringArray(key);
cache.put(cacheKey,
new ResourceReference(cacheKey, (Object) names, referenceQueue));
}
diff --git a/src/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java b/src/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java
index 105af9c..cf60965 100644
--- a/src/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java
+++ b/src/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java
@@ -26,6 +26,7 @@
package sun.util.locale.provider;
import java.util.Locale;
+import java.util.Objects;
import java.util.Set;
import java.util.TimeZone;
import java.util.spi.TimeZoneNameProvider;
@@ -95,8 +96,9 @@
*/
@Override
public String getDisplayName(String id, boolean daylight, int style, Locale locale) {
- String[] names = getDisplayNameArray(id, 5, locale);
- if (names != null) {
+ String[] names = getDisplayNameArray(id, locale);
+ if (Objects.nonNull(names)) {
+ assert names.length >= 7;
int index = daylight ? 3 : 1;
if (style == TimeZone.SHORT) {
index++;
@@ -108,18 +110,18 @@
@Override
public String getGenericDisplayName(String id, int style, Locale locale) {
- String[] names = getDisplayNameArray(id, 7, locale);
- if (names != null && names.length >= 7) {
+ String[] names = getDisplayNameArray(id, locale);
+ if (Objects.nonNull(names)) {
+ assert names.length >= 7;
return names[(style == TimeZone.LONG) ? 5 : 6];
}
return null;
}
- private String[] getDisplayNameArray(String id, int n, Locale locale) {
- if (id == null || locale == null) {
- throw new NullPointerException();
- }
- return LocaleProviderAdapter.forType(type).getLocaleResources(locale).getTimeZoneNames(id, n);
+ private String[] getDisplayNameArray(String id, Locale locale) {
+ Objects.requireNonNull(id);
+ Objects.requireNonNull(locale);
+ return LocaleProviderAdapter.forType(type).getLocaleResources(locale).getTimeZoneNames(id);
}
/**
diff --git a/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java b/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java
index c999780..688fb2e 100644
--- a/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java
+++ b/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java
@@ -30,6 +30,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.spi.TimeZoneNameProvider;
@@ -100,9 +101,9 @@
* Retrieve display names for a time zone ID.
*/
public static String[] retrieveDisplayNames(String id, Locale locale) {
- if (id == null || locale == null) {
- throw new NullPointerException();
- }
+ Objects.requireNonNull(id);
+ Objects.requireNonNull(locale);
+
return retrieveDisplayNamesImpl(id, locale);
}
@@ -115,9 +116,12 @@
* @return the requested generic time zone display name, or null if not found.
*/
public static String retrieveGenericDisplayName(String id, int style, Locale locale) {
- LocaleServiceProviderPool pool =
- LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class);
- return pool.getLocalizedObject(TimeZoneNameGetter.INSTANCE, locale, "generic", style, id);
+ String[] names = retrieveDisplayNamesImpl(id, locale);
+ if (Objects.nonNull(names)) {
+ return names[6 - style];
+ } else {
+ return null;
+ }
}
/**
@@ -130,140 +134,53 @@
* @return the requested time zone name, or null if not found.
*/
public static String retrieveDisplayName(String id, boolean daylight, int style, Locale locale) {
- LocaleServiceProviderPool pool =
- LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class);
- return pool.getLocalizedObject(TimeZoneNameGetter.INSTANCE, locale, daylight ? "dst" : "std", style, id);
+ String[] names = retrieveDisplayNamesImpl(id, locale);
+ if (Objects.nonNull(names)) {
+ return names[(daylight ? 4 : 2) - style];
+ } else {
+ return null;
+ }
}
private static String[] retrieveDisplayNamesImpl(String id, Locale locale) {
LocaleServiceProviderPool pool =
LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class);
+ String[] names;
+ Map<Locale, String[]> perLocale = null;
SoftReference<Map<Locale, String[]>> ref = cachedDisplayNames.get(id);
- if (ref != null) {
- Map<Locale, String[]> perLocale = ref.get();
- if (perLocale != null) {
- String[] names = perLocale.get(locale);
- if (names != null) {
+ if (Objects.nonNull(ref)) {
+ perLocale = ref.get();
+ if (Objects.nonNull(perLocale)) {
+ names = perLocale.get(locale);
+ if (Objects.nonNull(names)) {
return names;
}
- names = pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id);
- if (names != null) {
- perLocale.put(locale, names);
- }
- return names;
}
}
- String[] names = pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id);
- if (names != null) {
- Map<Locale, String[]> perLocale = new ConcurrentHashMap<>();
- perLocale.put(locale, names);
- ref = new SoftReference<>(perLocale);
- cachedDisplayNames.put(id, ref);
+ // build names array
+ names = new String[7];
+ names[0] = id;
+ for (int i = 1; i <= 6; i ++) {
+ names[i] = pool.getLocalizedObject(TimeZoneNameGetter.INSTANCE, locale,
+ i<5 ? (i<3 ? "std" : "dst") : "generic", i%2, id);
}
+
+ if (Objects.isNull(perLocale)) {
+ perLocale = new ConcurrentHashMap<>();
+ }
+ perLocale.put(locale, names);
+ ref = new SoftReference<>(perLocale);
+ cachedDisplayNames.put(id, ref);
return names;
}
+
/**
* Obtains a localized time zone strings from a TimeZoneNameProvider
* implementation.
*/
- private static class TimeZoneNameArrayGetter
- implements LocaleServiceProviderPool.LocalizedObjectGetter<TimeZoneNameProvider,
- String[]>{
- private static final TimeZoneNameArrayGetter INSTANCE =
- new TimeZoneNameArrayGetter();
-
- @Override
- public String[] getObject(TimeZoneNameProvider timeZoneNameProvider,
- Locale locale,
- String requestID,
- Object... params) {
- assert params.length == 0;
-
- // First, try to get names with the request ID
- String[] names = buildZoneStrings(timeZoneNameProvider, locale, requestID);
-
- if (names == null) {
- Map<String, String> aliases = ZoneInfo.getAliasTable();
-
- if (aliases != null) {
- // Check whether this id is an alias, if so,
- // look for the standard id.
- String canonicalID = aliases.get(requestID);
- if (canonicalID != null) {
- names = buildZoneStrings(timeZoneNameProvider, locale, canonicalID);
- }
- if (names == null) {
- // There may be a case that a standard id has become an
- // alias. so, check the aliases backward.
- names = examineAliases(timeZoneNameProvider, locale,
- canonicalID == null ? requestID : canonicalID, aliases);
- }
- }
- }
-
- if (names != null) {
- names[0] = requestID;
- }
-
- return names;
- }
-
- private static String[] examineAliases(TimeZoneNameProvider tznp, Locale locale,
- String id,
- Map<String, String> aliases) {
- if (aliases.containsValue(id)) {
- for (Map.Entry<String, String> entry : aliases.entrySet()) {
- if (entry.getValue().equals(id)) {
- String alias = entry.getKey();
- String[] names = buildZoneStrings(tznp, locale, alias);
- if (names != null) {
- return names;
- }
- names = examineAliases(tznp, locale, alias, aliases);
- if (names != null) {
- return names;
- }
- }
- }
- }
-
- return null;
- }
-
- private static String[] buildZoneStrings(TimeZoneNameProvider tznp,
- Locale locale, String id) {
- String[] names = new String[5];
-
- for (int i = 1; i <= 4; i ++) {
- names[i] = tznp.getDisplayName(id, i>=3, i%2, locale);
-
- if (names[i] == null) {
- switch (i) {
- case 1:
- // this id seems not localized by this provider
- return null;
- case 2:
- case 4:
- // If the display name for SHORT is not supplied,
- // copy the LONG name.
- names[i] = names[i-1];
- break;
- case 3:
- // If the display name for DST is not supplied,
- // copy the "standard" name.
- names[3] = names[1];
- break;
- }
- }
- }
-
- return names;
- }
- }
-
private static class TimeZoneNameGetter
implements LocaleServiceProviderPool.LocalizedObjectGetter<TimeZoneNameProvider,
String> {
@@ -299,18 +216,16 @@
private static String examineAliases(TimeZoneNameProvider tznp, Locale locale,
String requestID, String tzid, int style,
Map<String, String> aliases) {
- if (aliases.containsValue(tzid)) {
- for (Map.Entry<String, String> entry : aliases.entrySet()) {
- if (entry.getValue().equals(tzid)) {
- String alias = entry.getKey();
- String name = getName(tznp, locale, requestID, style, alias);
- if (name != null) {
- return name;
- }
- name = examineAliases(tznp, locale, requestID, alias, style, aliases);
- if (name != null) {
- return name;
- }
+ for (Map.Entry<String, String> entry : aliases.entrySet()) {
+ if (entry.getValue().equals(tzid)) {
+ String alias = entry.getKey();
+ String name = getName(tznp, locale, requestID, style, alias);
+ if (name != null) {
+ return name;
+ }
+ name = examineAliases(tznp, locale, requestID, alias, style, aliases);
+ if (name != null) {
+ return name;
}
}
}
diff --git a/src/share/classes/sun/util/resources/LocaleData.java b/src/share/classes/sun/util/resources/LocaleData.java
index 00ba6de..24265f3 100644
--- a/src/share/classes/sun/util/resources/LocaleData.java
+++ b/src/share/classes/sun/util/resources/LocaleData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -48,8 +48,11 @@
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
+import java.util.Set;
+import sun.util.locale.provider.JRELocaleProviderAdapter;
import sun.util.locale.provider.LocaleDataMetaInfo;
import sun.util.locale.provider.LocaleProviderAdapter;
+import static sun.util.locale.provider.LocaleProviderAdapter.Type.CLDR;
import static sun.util.locale.provider.LocaleProviderAdapter.Type.JRE;
/**
@@ -204,35 +207,23 @@
@Override
public List<Locale> getCandidateLocales(String baseName, Locale locale) {
List<Locale> candidates = super.getCandidateLocales(baseName, locale);
- /* Get the locale string list from LocaleDataMetaInfo class. */
- String localeString = LocaleDataMetaInfo.getSupportedLocaleString(baseName);
-
- if (localeString != null && localeString.length() != 0) {
- for (Iterator<Locale> l = candidates.iterator(); l.hasNext();) {
- Locale loc = l.next();
- String lstr;
- if (loc.getScript().length() > 0) {
- lstr = loc.toLanguageTag().replace('-', '_');
- } else {
- lstr = loc.toString();
- int idx = lstr.indexOf("_#");
- if (idx >= 0) {
- lstr = lstr.substring(0, idx);
- }
- }
- /* Every locale string in the locale string list returned from
- the above getSupportedLocaleString is enclosed
- within two white spaces so that we could check some locale
- such as "en".
- */
- if (lstr.length() != 0 && localeString.indexOf(" " + lstr + " ") == -1) {
- l.remove();
+ // Weed out Locales which are known to have no resource bundles
+ int lastDot = baseName.lastIndexOf('.');
+ String category = (lastDot >= 0) ? baseName.substring(lastDot + 1) : baseName;
+ LocaleProviderAdapter.Type type = baseName.contains(DOTCLDR) ? CLDR : JRE;
+ LocaleProviderAdapter adapter = LocaleProviderAdapter.forType(type);
+ Set<String> langtags = ((JRELocaleProviderAdapter)adapter).getLanguageTagSet(category);
+ if (!langtags.isEmpty()) {
+ for (Iterator<Locale> itr = candidates.iterator(); itr.hasNext();) {
+ if (!LocaleProviderAdapter.isSupportedLocale(itr.next(), type, langtags)) {
+ itr.remove();
}
}
}
+
// Force fallback to Locale.ENGLISH for CLDR time zone names support
if (locale.getLanguage() != "en"
- && baseName.contains(CLDR) && baseName.endsWith("TimeZoneNames")) {
+ && type == CLDR && category.equals("TimeZoneNames")) {
candidates.add(candidates.size() - 1, Locale.ENGLISH);
}
return candidates;
@@ -254,7 +245,7 @@
return null;
}
- private static final String CLDR = ".cldr";
+ private static final String DOTCLDR = ".cldr";
/**
* Changes baseName to its per-language package name and
@@ -275,8 +266,8 @@
assert JRE.getUtilResourcesPackage().length()
== JRE.getTextResourcesPackage().length();
int index = JRE.getUtilResourcesPackage().length();
- if (baseName.indexOf(CLDR, index) > 0) {
- index += CLDR.length();
+ if (baseName.indexOf(DOTCLDR, index) > 0) {
+ index += DOTCLDR.length();
}
newBaseName = baseName.substring(0, index + 1) + lang
+ baseName.substring(index);
diff --git a/src/share/classes/sun/util/resources/TimeZoneNamesBundle.java b/src/share/classes/sun/util/resources/TimeZoneNamesBundle.java
index 6dcc1ee..58aa118 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNamesBundle.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNamesBundle.java
@@ -44,6 +44,7 @@
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.MissingResourceException;
+import java.util.Objects;
import java.util.Set;
/**
@@ -61,26 +62,6 @@
public abstract class TimeZoneNamesBundle extends OpenListResourceBundle {
/**
- * Returns a String array containing time zone names. The String array has
- * at most size elements.
- *
- * @param key the time zone ID for which names are obtained
- * @param size the requested size of array for names
- * @return a String array containing names
- */
- public String[] getStringArray(String key, int size) {
- String[] names = handleGetObject(key, size);
- if ((names == null || names.length != size) && parent != null) {
- names = ((TimeZoneNamesBundle)parent).getStringArray(key, size);
- }
- if (names == null) {
- throw new MissingResourceException("no time zone names", getClass().getName(), key);
- }
- return names;
-
- }
-
- /**
* Maps time zone IDs to locale-specific names.
* The value returned is an array of five strings:
* <ul>
@@ -89,6 +70,8 @@
* <li>The short name of the time zone in standard time (localized).
* <li>The long name of the time zone in daylight savings time (localized).
* <li>The short name of the time zone in daylight savings time (localized).
+ * <li>The long name of the time zone in generic form (localized).
+ * <li>The short name of the time zone in generic form (localized).
* </ul>
* The localized names come from the subclasses's
* <code>getContents</code> implementations, while the time zone
@@ -96,16 +79,12 @@
*/
@Override
public Object handleGetObject(String key) {
- return handleGetObject(key, 5);
- }
-
- private String[] handleGetObject(String key, int n) {
String[] contents = (String[]) super.handleGetObject(key);
- if (contents == null) {
+ if (Objects.isNull(contents)) {
return null;
}
- int clen = Math.min(n - 1, contents.length);
- String[] tmpobj = new String[clen+1];
+ int clen = contents.length;
+ String[] tmpobj = new String[7];
tmpobj[0] = key;
System.arraycopy(contents, 0, tmpobj, 1, clen);
return tmpobj;
diff --git a/src/share/classes/sun/util/resources/en/TimeZoneNames_en_IE.java b/src/share/classes/sun/util/resources/en/TimeZoneNames_en_IE.java
index ce91613..14a74e8 100644
--- a/src/share/classes/sun/util/resources/en/TimeZoneNames_en_IE.java
+++ b/src/share/classes/sun/util/resources/en/TimeZoneNames_en_IE.java
@@ -47,7 +47,8 @@
protected final Object[][] getContents() {
return new Object[][] {
{"Europe/London", new String[] {"Greenwich Mean Time", "GMT",
- "Irish Summer Time", "IST" /*Dublin*/}},
+ "Irish Summer Time", "IST", /*Dublin*/
+ "Irish Time", "IT" /*Dublin*/}},
};
}
}
diff --git a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java
index 9101f56..929361c 100644
--- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java
+++ b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java
@@ -2252,6 +2252,8 @@
}
break;
case EXTID_NTFS:
+ if (sz < 32)
+ break;
pos += 4; // reserved 4 bytes
if (SH(extra, pos) != 0x0001)
break;
diff --git a/src/share/lib/security/java.security-aix b/src/share/lib/security/java.security-aix
index fa0ce4c..c0f9d5f 100644
--- a/src/share/lib/security/java.security-aix
+++ b/src/share/lib/security/java.security-aix
@@ -500,7 +500,7 @@
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, DH keySize < 768
+jdk.tls.disabledAlgorithms=SSLv3, RC4, DH keySize < 768
# Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
# processing in JSSE implementation.
diff --git a/src/share/lib/security/java.security-linux b/src/share/lib/security/java.security-linux
index fa0ce4c..c0f9d5f 100644
--- a/src/share/lib/security/java.security-linux
+++ b/src/share/lib/security/java.security-linux
@@ -500,7 +500,7 @@
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, DH keySize < 768
+jdk.tls.disabledAlgorithms=SSLv3, RC4, DH keySize < 768
# Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
# processing in JSSE implementation.
diff --git a/src/share/lib/security/java.security-macosx b/src/share/lib/security/java.security-macosx
index e10b2e6..329a1c5 100644
--- a/src/share/lib/security/java.security-macosx
+++ b/src/share/lib/security/java.security-macosx
@@ -503,7 +503,7 @@
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, DH keySize < 768
+jdk.tls.disabledAlgorithms=SSLv3, RC4, DH keySize < 768
# Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
# processing in JSSE implementation.
diff --git a/src/share/lib/security/java.security-solaris b/src/share/lib/security/java.security-solaris
index efac5cf..51a4203 100644
--- a/src/share/lib/security/java.security-solaris
+++ b/src/share/lib/security/java.security-solaris
@@ -502,7 +502,7 @@
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, DH keySize < 768
+jdk.tls.disabledAlgorithms=SSLv3, RC4, DH keySize < 768
# Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
# processing in JSSE implementation.
diff --git a/src/share/lib/security/java.security-windows b/src/share/lib/security/java.security-windows
index a1d8a7f..df27a5d 100644
--- a/src/share/lib/security/java.security-windows
+++ b/src/share/lib/security/java.security-windows
@@ -503,7 +503,7 @@
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, DH keySize < 768
+jdk.tls.disabledAlgorithms=SSLv3, RC4, DH keySize < 768
# Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
# processing in JSSE implementation.
diff --git a/src/share/native/java/net/net_util.h b/src/share/native/java/net/net_util.h
index 246c054..60d63fc 100644
--- a/src/share/native/java/net/net_util.h
+++ b/src/share/native/java/net/net_util.h
@@ -182,9 +182,13 @@
JNIEXPORT int JNICALL
NET_MapSocketOptionV6(jint cmd, int *level, int *optname);
+JNIEXPORT jint JNICALL
+NET_EnableFastTcpLoopback(int fd);
+
int getScopeID (struct sockaddr *);
int cmpScopeID (unsigned int, struct sockaddr *);
unsigned short in_cksum(unsigned short *addr, int len);
+
#endif /* NET_UTILS_H */
diff --git a/src/share/native/java/util/zip/Deflater.c b/src/share/native/java/util/zip/Deflater.c
index a9f403d..c19211c 100644
--- a/src/share/native/java/util/zip/Deflater.c
+++ b/src/share/native/java/util/zip/Deflater.c
@@ -68,10 +68,11 @@
JNU_ThrowOutOfMemoryError(env, 0);
return jlong_zero;
} else {
- char *msg;
- switch (deflateInit2(strm, level, Z_DEFLATED,
- nowrap ? -MAX_WBITS : MAX_WBITS,
- DEF_MEM_LEVEL, strategy)) {
+ const char *msg;
+ int ret = deflateInit2(strm, level, Z_DEFLATED,
+ nowrap ? -MAX_WBITS : MAX_WBITS,
+ DEF_MEM_LEVEL, strategy);
+ switch (ret) {
case Z_OK:
return ptr_to_jlong(strm);
case Z_MEM_ERROR:
@@ -83,7 +84,11 @@
JNU_ThrowIllegalArgumentException(env, 0);
return jlong_zero;
default:
- msg = strm->msg;
+ msg = ((strm->msg != NULL) ? strm->msg :
+ (ret == Z_VERSION_ERROR) ?
+ "zlib returned Z_VERSION_ERROR: "
+ "compile time and runtime zlib implementations differ" :
+ "unknown error initializing zlib library");
free(strm);
JNU_ThrowInternalError(env, msg);
return jlong_zero;
diff --git a/src/share/native/sun/awt/giflib/COPYING b/src/share/native/sun/awt/giflib/COPYING
new file mode 100644
index 0000000..b9c0b50
--- /dev/null
+++ b/src/share/native/sun/awt/giflib/COPYING
@@ -0,0 +1,19 @@
+The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/share/native/sun/awt/giflib/dgif_lib.c b/src/share/native/sun/awt/giflib/dgif_lib.c
index d6d2a3c..2d3d882 100644
--- a/src/share/native/sun/awt/giflib/dgif_lib.c
+++ b/src/share/native/sun/awt/giflib/dgif_lib.c
@@ -23,219 +23,211 @@
*/
/******************************************************************************
- * "Gif-Lib" - Yet another gif library.
- *
- * Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990
- ******************************************************************************
- * The kernel of the GIF Decoding process can be found here.
- ******************************************************************************
- * History:
- * 16 Jun 89 - Version 1.0 by Gershon Elber.
- * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names).
- *****************************************************************************/
-/* !!!! */
+dgif_lib.c - GIF decoding
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+The functions here and in egif_lib.c are partitioned carefully so that
+if you only require one of read and write capability, only one of these
+two modules will be linked. Preserve this property!
+
+*****************************************************************************/
#include <stdlib.h>
-#if defined (__MSDOS__) && !defined(__DJGPP__) && !defined(__GNUC__)
-#include <io.h>
-#include <alloc.h>
-#include <sys\stat.h>
-#else
-#include <sys/types.h>
-#include <sys/stat.h>
-#endif /* __MSDOS__ */
+#include <limits.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
#ifdef _WIN32
#include <io.h>
-#define _OPEN_BINARY
#else
#include <unistd.h>
-#endif
+#endif /* _WIN32 */
-#include <fcntl.h>
-
-#include <stdio.h>
-#include <string.h>
#include "gif_lib.h"
#include "gif_lib_private.h"
-#define COMMENT_EXT_FUNC_CODE 0xfe /* Extension function code for
- comment. */
+/* compose unsigned little endian value */
+#define UNSIGNED_LITTLE_ENDIAN(lo, hi) ((lo) | ((hi) << 8))
/* avoid extra function call in case we use fread (TVT) */
#define READ(_gif,_buf,_len) \
(((GifFilePrivateType*)_gif->Private)->Read ? \
- (size_t)((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \
+ ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \
fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File))
-static int DGifGetWord(GifFileType *GifFile, int *Word);
+static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
static int DGifSetupDecompress(GifFileType *GifFile);
static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
int LineLen);
-static int DGifGetPrefixChar(unsigned int *Prefix, int Code, int ClearCode);
+static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
static int DGifDecompressInput(GifFileType *GifFile, int *Code);
static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
GifByteType *NextByte);
/******************************************************************************
- * Open a new gif file for read, given by its name.
- * Returns GifFileType pointer dynamically allocated which serves as the gif
- * info record. _GifError is cleared if succesfull.
- *****************************************************************************/
+ Open a new GIF file for read, given by its name.
+ Returns dynamically allocated GifFileType pointer which serves as the GIF
+ info record.
+******************************************************************************/
GifFileType *
-DGifOpenFileName(const char *FileName) {
+DGifOpenFileName(const char *FileName, int *Error)
+{
int FileHandle;
GifFileType *GifFile;
- if ((FileHandle = open(FileName, O_RDONLY
-#if defined(__MSDOS__) || defined(_OPEN_BINARY)
- | O_BINARY
-#endif /* __MSDOS__ || _OPEN_BINARY */
- )) == -1) {
- _GifError = D_GIF_ERR_OPEN_FAILED;
+ if ((FileHandle = open(FileName, O_RDONLY)) == -1) {
+ if (Error != NULL)
+ *Error = D_GIF_ERR_OPEN_FAILED;
return NULL;
}
- GifFile = DGifOpenFileHandle(FileHandle);
- if (GifFile == (GifFileType *)NULL)
- close(FileHandle);
+ GifFile = DGifOpenFileHandle(FileHandle, Error);
return GifFile;
}
/******************************************************************************
- * Update a new gif file, given its file handle.
- * Returns GifFileType pointer dynamically allocated which serves as the gif
- * info record. _GifError is cleared if succesfull.
- *****************************************************************************/
+ Update a new GIF file, given its file handle.
+ Returns dynamically allocated GifFileType pointer which serves as the GIF
+ info record.
+******************************************************************************/
GifFileType *
-DGifOpenFileHandle(int FileHandle) {
-
- unsigned char Buf[GIF_STAMP_LEN + 1];
+DGifOpenFileHandle(int FileHandle, int *Error)
+{
+ char Buf[GIF_STAMP_LEN + 1];
GifFileType *GifFile;
GifFilePrivateType *Private;
FILE *f;
GifFile = (GifFileType *)malloc(sizeof(GifFileType));
if (GifFile == NULL) {
- _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
+ if (Error != NULL)
+ *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
+ (void)close(FileHandle);
return NULL;
}
- memset(GifFile, '\0', sizeof(GifFileType));
+ /*@i1@*/memset(GifFile, '\0', sizeof(GifFileType));
+
+ /* Belt and suspenders, in case the null pointer isn't zero */
+ GifFile->SavedImages = NULL;
+ GifFile->SColorMap = NULL;
Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
if (Private == NULL) {
- _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
+ if (Error != NULL)
+ *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
+ (void)close(FileHandle);
free((char *)GifFile);
return NULL;
}
-#ifdef __MSDOS__
- setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
-#endif /* __MSDOS__ */
+#ifdef _WIN32
+ _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
+#endif /* _WIN32 */
f = fdopen(FileHandle, "rb"); /* Make it into a stream: */
-#ifdef __MSDOS__
- setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream
- buffer. */
-#endif /* __MSDOS__ */
-
- GifFile->Private = (VoidPtr)Private;
+ /*@-mustfreeonly@*/
+ GifFile->Private = (void *)Private;
Private->FileHandle = FileHandle;
Private->File = f;
Private->FileState = FILE_STATE_READ;
- Private->Read = 0; /* don't use alternate input method (TVT) */
- GifFile->UserData = 0; /* TVT */
+ Private->Read = NULL; /* don't use alternate input method (TVT) */
+ GifFile->UserData = NULL; /* TVT */
+ /*@=mustfreeonly@*/
- /* Lets see if this is a GIF file: */
- if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
- _GifError = D_GIF_ERR_READ_FAILED;
- fclose(f);
+ /* Let's see if this is a GIF file: */
+ /* coverity[check_return] */
+ if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
+ if (Error != NULL)
+ *Error = D_GIF_ERR_READ_FAILED;
+ (void)fclose(f);
free((char *)Private);
free((char *)GifFile);
return NULL;
}
- /* The GIF Version number is ignored at this time. Maybe we should do
- * something more useful with it. */
+ /* Check for GIF prefix at start of file */
Buf[GIF_STAMP_LEN] = 0;
- if (strncmp(GIF_STAMP, (const char*)Buf, GIF_VERSION_POS) != 0) {
- _GifError = D_GIF_ERR_NOT_GIF_FILE;
- fclose(f);
+ if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
+ if (Error != NULL)
+ *Error = D_GIF_ERR_NOT_GIF_FILE;
+ (void)fclose(f);
free((char *)Private);
free((char *)GifFile);
return NULL;
}
if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
- fclose(f);
+ (void)fclose(f);
free((char *)Private);
free((char *)GifFile);
return NULL;
}
- _GifError = 0;
+ GifFile->Error = 0;
+
+ /* What version of GIF? */
+ Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
return GifFile;
}
/******************************************************************************
- * GifFileType constructor with user supplied input function (TVT)
- *****************************************************************************/
+ GifFileType constructor with user supplied input function (TVT)
+******************************************************************************/
GifFileType *
-DGifOpen(void *userData,
- InputFunc readFunc) {
-
- unsigned char Buf[GIF_STAMP_LEN + 1];
+DGifOpen(void *userData, InputFunc readFunc, int *Error)
+{
+ char Buf[GIF_STAMP_LEN + 1];
GifFileType *GifFile;
GifFilePrivateType *Private;
- if (!readFunc) {
- _GifError = D_GIF_ERR_READ_FAILED;
- return NULL;
- }
-
GifFile = (GifFileType *)malloc(sizeof(GifFileType));
if (GifFile == NULL) {
- _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
+ if (Error != NULL)
+ *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return NULL;
}
memset(GifFile, '\0', sizeof(GifFileType));
+ /* Belt and suspenders, in case the null pointer isn't zero */
+ GifFile->SavedImages = NULL;
+ GifFile->SColorMap = NULL;
+
Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
if (!Private) {
- _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
+ if (Error != NULL)
+ *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
free((char *)GifFile);
return NULL;
}
- GifFile->Private = (VoidPtr)Private;
+ GifFile->Private = (void *)Private;
Private->FileHandle = 0;
- Private->File = 0;
+ Private->File = NULL;
Private->FileState = FILE_STATE_READ;
Private->Read = readFunc; /* TVT */
GifFile->UserData = userData; /* TVT */
/* Lets see if this is a GIF file: */
- if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ /* coverity[check_return] */
+ if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
+ if (Error != NULL)
+ *Error = D_GIF_ERR_READ_FAILED;
free((char *)Private);
free((char *)GifFile);
return NULL;
}
- /* The GIF Version number is ignored at this time. Maybe we should do
- * something more useful with it. */
- Buf[GIF_STAMP_LEN] = 0;
- if (strncmp(GIF_STAMP, (const char*)Buf, GIF_VERSION_POS) != 0) {
- _GifError = D_GIF_ERR_NOT_GIF_FILE;
+ /* Check for GIF prefix at start of file */
+ Buf[GIF_STAMP_LEN] = '\0';
+ if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
+ if (Error != NULL)
+ *Error = D_GIF_ERR_NOT_GIF_FILE;
free((char *)Private);
free((char *)GifFile);
return NULL;
@@ -244,28 +236,34 @@
if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
free((char *)Private);
free((char *)GifFile);
+ if (Error != NULL)
+ *Error = D_GIF_ERR_NO_SCRN_DSCR;
return NULL;
}
- _GifError = 0;
+ GifFile->Error = 0;
+
+ /* What version of GIF? */
+ Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
return GifFile;
}
/******************************************************************************
- * This routine should be called before any other DGif calls. Note that
- * this routine is called automatically from DGif file open routines.
- *****************************************************************************/
+ This routine should be called before any other DGif calls. Note that
+ this routine is called automatically from DGif file open routines.
+******************************************************************************/
int
-DGifGetScreenDesc(GifFileType * GifFile) {
-
- int i, BitsPerPixel;
+DGifGetScreenDesc(GifFileType *GifFile)
+{
+ int BitsPerPixel;
+ bool SortFlag;
GifByteType Buf[3];
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
- _GifError = D_GIF_ERR_NOT_READABLE;
+ GifFile->Error = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
@@ -275,25 +273,33 @@
return GIF_ERROR;
if (READ(GifFile, Buf, 3) != 3) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
+ GifFreeMapObject(GifFile->SColorMap);
+ GifFile->SColorMap = NULL;
return GIF_ERROR;
}
GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
+ SortFlag = (Buf[0] & 0x08) != 0;
BitsPerPixel = (Buf[0] & 0x07) + 1;
GifFile->SBackGroundColor = Buf[1];
+ GifFile->AspectByte = Buf[2];
if (Buf[0] & 0x80) { /* Do we have global color map? */
+ int i;
- GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
+ GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
if (GifFile->SColorMap == NULL) {
- _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
+ GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return GIF_ERROR;
}
/* Get the global color map: */
+ GifFile->SColorMap->SortFlag = SortFlag;
for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
+ /* coverity[check_return] */
if (READ(GifFile, Buf, 3) != 3) {
- FreeMapObject(GifFile->SColorMap);
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFreeMapObject(GifFile->SColorMap);
+ GifFile->SColorMap = NULL;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
GifFile->SColorMap->Colors[i].Red = Buf[0];
@@ -308,39 +314,39 @@
}
/******************************************************************************
- * This routine should be called before any attempt to read an image.
- *****************************************************************************/
+ This routine should be called before any attempt to read an image.
+******************************************************************************/
int
-DGifGetRecordType(GifFileType * GifFile,
- GifRecordType * Type) {
-
+DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
+{
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
- _GifError = D_GIF_ERR_NOT_READABLE;
+ GifFile->Error = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
+ /* coverity[check_return] */
if (READ(GifFile, &Buf, 1) != 1) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
switch (Buf) {
- case ',':
+ case DESCRIPTOR_INTRODUCER:
*Type = IMAGE_DESC_RECORD_TYPE;
break;
- case '!':
+ case EXTENSION_INTRODUCER:
*Type = EXTENSION_RECORD_TYPE;
break;
- case ';':
+ case TERMINATOR_INTRODUCER:
*Type = TERMINATE_RECORD_TYPE;
break;
default:
*Type = UNDEFINED_RECORD_TYPE;
- _GifError = D_GIF_ERR_WRONG_RECORD;
+ GifFile->Error = D_GIF_ERR_WRONG_RECORD;
return GIF_ERROR;
}
@@ -348,20 +354,20 @@
}
/******************************************************************************
- * This routine should be called before any attempt to read an image.
- * Note it is assumed the Image desc. header (',') has been read.
- *****************************************************************************/
+ This routine should be called before any attempt to read an image.
+ Note it is assumed the Image desc. header has been read.
+******************************************************************************/
int
-DGifGetImageDesc(GifFileType * GifFile) {
-
- int i, BitsPerPixel;
+DGifGetImageDesc(GifFileType *GifFile)
+{
+ unsigned int BitsPerPixel;
GifByteType Buf[3];
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
SavedImage *sp;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
- _GifError = D_GIF_ERR_NOT_READABLE;
+ GifFile->Error = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
@@ -371,51 +377,57 @@
DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
return GIF_ERROR;
if (READ(GifFile, Buf, 1) != 1) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
+ GifFreeMapObject(GifFile->Image.ColorMap);
+ GifFile->Image.ColorMap = NULL;
return GIF_ERROR;
}
BitsPerPixel = (Buf[0] & 0x07) + 1;
- GifFile->Image.Interlace = (Buf[0] & 0x40);
- if (Buf[0] & 0x80) { /* Does this image have local color map? */
+ GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false;
- /*** FIXME: Why do we check both of these in order to do this?
- * Why do we have both Image and SavedImages? */
- if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL)
- FreeMapObject(GifFile->Image.ColorMap);
+ /* Setup the colormap */
+ if (GifFile->Image.ColorMap) {
+ GifFreeMapObject(GifFile->Image.ColorMap);
+ GifFile->Image.ColorMap = NULL;
+ }
+ /* Does this image have local color map? */
+ if (Buf[0] & 0x80) {
+ unsigned int i;
- GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
+ GifFile->Image.ColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
if (GifFile->Image.ColorMap == NULL) {
- _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
+ GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return GIF_ERROR;
}
/* Get the image local color map: */
for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
+ /* coverity[check_return] */
if (READ(GifFile, Buf, 3) != 3) {
- FreeMapObject(GifFile->Image.ColorMap);
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFreeMapObject(GifFile->Image.ColorMap);
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
+ GifFile->Image.ColorMap = NULL;
return GIF_ERROR;
}
GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
}
- } else if (GifFile->Image.ColorMap) {
- FreeMapObject(GifFile->Image.ColorMap);
- GifFile->Image.ColorMap = NULL;
}
if (GifFile->SavedImages) {
- if ((GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
- sizeof(SavedImage) *
- (GifFile->ImageCount + 1))) == NULL) {
- _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
+ SavedImage* new_saved_images =
+ (SavedImage *)realloc(GifFile->SavedImages,
+ sizeof(SavedImage) * (GifFile->ImageCount + 1));
+ if (new_saved_images == NULL) {
+ GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return GIF_ERROR;
}
+ GifFile->SavedImages = new_saved_images;
} else {
if ((GifFile->SavedImages =
(SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
- _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
+ GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return GIF_ERROR;
}
}
@@ -423,11 +435,11 @@
sp = &GifFile->SavedImages[GifFile->ImageCount];
memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
if (GifFile->Image.ColorMap != NULL) {
- sp->ImageDesc.ColorMap = MakeMapObject(
+ sp->ImageDesc.ColorMap = GifMakeMapObject(
GifFile->Image.ColorMap->ColorCount,
GifFile->Image.ColorMap->Colors);
if (sp->ImageDesc.ColorMap == NULL) {
- _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
+ GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return GIF_ERROR;
}
}
@@ -440,43 +452,40 @@
Private->PixelCount = (long)GifFile->Image.Width *
(long)GifFile->Image.Height;
- return DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */
+ /* Reset decompress algorithm parameters. */
+ return DGifSetupDecompress(GifFile);
}
/******************************************************************************
- * Get one full scanned line (Line) of length LineLen from GIF file.
- *****************************************************************************/
+ Get one full scanned line (Line) of length LineLen from GIF file.
+******************************************************************************/
int
-DGifGetLine(GifFileType * GifFile,
- GifPixelType * Line,
- int LineLen) {
-
+DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
+{
GifByteType *Dummy;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
- _GifError = D_GIF_ERR_NOT_READABLE;
+ GifFile->Error = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
if (!LineLen)
LineLen = GifFile->Image.Width;
-#if defined(__MSDOS__) || defined(__GNUC__)
if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
-#else
- if ((Private->PixelCount -= LineLen) > 0xffff0000) {
-#endif /* __MSDOS__ */
- _GifError = D_GIF_ERR_DATA_TOO_BIG;
+ GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
return GIF_ERROR;
}
if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
if (Private->PixelCount == 0) {
- /* We probably would not be called any more, so lets clean
- * everything before we return: need to flush out all rest of
- * image until empty block (size 0) detected. We use GetCodeNext. */
+ /* We probably won't be called any more, so let's clean up
+ * everything before we return: need to flush out all the
+ * rest of image until an empty block (size 0)
+ * detected. We use GetCodeNext.
+ */
do
if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
return GIF_ERROR;
@@ -488,35 +497,32 @@
}
/******************************************************************************
- * Put one pixel (Pixel) into GIF file.
- *****************************************************************************/
+ Put one pixel (Pixel) into GIF file.
+******************************************************************************/
int
-DGifGetPixel(GifFileType * GifFile,
- GifPixelType Pixel) {
-
+DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
+{
GifByteType *Dummy;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
- _GifError = D_GIF_ERR_NOT_READABLE;
+ GifFile->Error = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
-#if defined(__MSDOS__) || defined(__GNUC__)
if (--Private->PixelCount > 0xffff0000UL)
-#else
- if (--Private->PixelCount > 0xffff0000)
-#endif /* __MSDOS__ */
{
- _GifError = D_GIF_ERR_DATA_TOO_BIG;
+ GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
return GIF_ERROR;
}
if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
if (Private->PixelCount == 0) {
- /* We probably would not be called any more, so lets clean
- * everything before we return: need to flush out all rest of
- * image until empty block (size 0) detected. We use GetCodeNext. */
+ /* We probably won't be called any more, so let's clean up
+ * everything before we return: need to flush out all the
+ * rest of image until an empty block (size 0)
+ * detected. We use GetCodeNext.
+ */
do
if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
return GIF_ERROR;
@@ -528,28 +534,27 @@
}
/******************************************************************************
- * Get an extension block (see GIF manual) from gif file. This routine only
- * returns the first data block, and DGifGetExtensionNext should be called
- * after this one until NULL extension is returned.
- * The Extension should NOT be freed by the user (not dynamically allocated).
- * Note it is assumed the Extension desc. header ('!') has been read.
- *****************************************************************************/
+ Get an extension block (see GIF manual) from GIF file. This routine only
+ returns the first data block, and DGifGetExtensionNext should be called
+ after this one until NULL extension is returned.
+ The Extension should NOT be freed by the user (not dynamically allocated).
+ Note it is assumed the Extension description header has been read.
+******************************************************************************/
int
-DGifGetExtension(GifFileType * GifFile,
- int *ExtCode,
- GifByteType ** Extension) {
-
+DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
+{
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
- _GifError = D_GIF_ERR_NOT_READABLE;
+ GifFile->Error = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
+ /* coverity[check_return] */
if (READ(GifFile, &Buf, 1) != 1) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
*ExtCode = Buf;
@@ -558,26 +563,26 @@
}
/******************************************************************************
- * Get a following extension block (see GIF manual) from gif file. This
- * routine should be called until NULL Extension is returned.
- * The Extension should NOT be freed by the user (not dynamically allocated).
- *****************************************************************************/
+ Get a following extension block (see GIF manual) from GIF file. This
+ routine should be called until NULL Extension is returned.
+ The Extension should NOT be freed by the user (not dynamically allocated).
+******************************************************************************/
int
-DGifGetExtensionNext(GifFileType * GifFile,
- GifByteType ** Extension) {
-
+DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
+{
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
if (READ(GifFile, &Buf, 1) != 1) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
if (Buf > 0) {
*Extension = Private->Buf; /* Use private unused buffer. */
(*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
+ /* coverity[tainted_data,check_return] */
if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
} else
@@ -587,91 +592,141 @@
}
/******************************************************************************
- * This routine should be called last, to close the GIF file.
- *****************************************************************************/
-int
-DGifCloseFile(GifFileType * GifFile) {
+ Extract a Graphics Control Block from raw extension data
+******************************************************************************/
- GifFilePrivateType *Private;
- FILE *File;
-
- if (GifFile == NULL)
+int DGifExtensionToGCB(const size_t GifExtensionLength,
+ const GifByteType *GifExtension,
+ GraphicsControlBlock *GCB)
+{
+ if (GifExtensionLength != 4) {
return GIF_ERROR;
+ }
+
+ GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07;
+ GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0;
+ GCB->DelayTime = UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
+ if (GifExtension[0] & 0x01)
+ GCB->TransparentColor = (int)GifExtension[3];
+ else
+ GCB->TransparentColor = NO_TRANSPARENT_COLOR;
+
+ return GIF_OK;
+}
+
+/******************************************************************************
+ Extract the Graphics Control Block for a saved image, if it exists.
+******************************************************************************/
+
+int DGifSavedExtensionToGCB(GifFileType *GifFile,
+ int ImageIndex, GraphicsControlBlock *GCB)
+{
+ int i;
+
+ if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1)
+ return GIF_ERROR;
+
+ GCB->DisposalMode = DISPOSAL_UNSPECIFIED;
+ GCB->UserInputFlag = false;
+ GCB->DelayTime = 0;
+ GCB->TransparentColor = NO_TRANSPARENT_COLOR;
+
+ for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount; i++) {
+ ExtensionBlock *ep = &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i];
+ if (ep->Function == GRAPHICS_EXT_FUNC_CODE)
+ return DGifExtensionToGCB(ep->ByteCount, ep->Bytes, GCB);
+ }
+
+ return GIF_ERROR;
+}
+
+/******************************************************************************
+ This routine should be called last, to close the GIF file.
+******************************************************************************/
+int
+DGifCloseFile(GifFileType *GifFile, int *ErrorCode)
+{
+ GifFilePrivateType *Private;
+
+ if (GifFile == NULL || GifFile->Private == NULL)
+ return GIF_ERROR;
+
+ if (GifFile->Image.ColorMap) {
+ GifFreeMapObject(GifFile->Image.ColorMap);
+ GifFile->Image.ColorMap = NULL;
+ }
+
+ if (GifFile->SColorMap) {
+ GifFreeMapObject(GifFile->SColorMap);
+ GifFile->SColorMap = NULL;
+ }
+
+ if (GifFile->SavedImages) {
+ GifFreeSavedImages(GifFile);
+ GifFile->SavedImages = NULL;
+ }
+
+ GifFreeExtensions(&GifFile->ExtensionBlockCount, &GifFile->ExtensionBlocks);
Private = (GifFilePrivateType *) GifFile->Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
- _GifError = D_GIF_ERR_NOT_READABLE;
+ if (ErrorCode != NULL)
+ *ErrorCode = D_GIF_ERR_NOT_READABLE;
+ free((char *)GifFile->Private);
+ free(GifFile);
return GIF_ERROR;
}
- File = Private->File;
-
- if (GifFile->Image.ColorMap) {
- FreeMapObject(GifFile->Image.ColorMap);
- GifFile->Image.ColorMap = NULL;
+ if (Private->File && (fclose(Private->File) != 0)) {
+ if (ErrorCode != NULL)
+ *ErrorCode = D_GIF_ERR_CLOSE_FAILED;
+ free((char *)GifFile->Private);
+ free(GifFile);
+ return GIF_ERROR;
}
- if (GifFile->SColorMap) {
- FreeMapObject(GifFile->SColorMap);
- GifFile->SColorMap = NULL;
- }
-
- if (Private) {
- free((char *)Private);
- Private = NULL;
- }
-
- if (GifFile->SavedImages) {
- FreeSavedImages(GifFile);
- GifFile->SavedImages = NULL;
- }
-
+ free((char *)GifFile->Private);
free(GifFile);
-
- if (File && (fclose(File) != 0)) {
- _GifError = D_GIF_ERR_CLOSE_FAILED;
- return GIF_ERROR;
- }
+ if (ErrorCode != NULL)
+ *ErrorCode = D_GIF_SUCCEEDED;
return GIF_OK;
}
/******************************************************************************
- * Get 2 bytes (word) from the given file:
- *****************************************************************************/
+ Get 2 bytes (word) from the given file:
+******************************************************************************/
static int
-DGifGetWord(GifFileType * GifFile,
- int *Word) {
-
+DGifGetWord(GifFileType *GifFile, GifWord *Word)
+{
unsigned char c[2];
+ /* coverity[check_return] */
if (READ(GifFile, c, 2) != 2) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
- *Word = (((unsigned int)c[1]) << 8) + c[0];
+ *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]);
return GIF_OK;
}
/******************************************************************************
- * Get the image code in compressed form. This routine can be called if the
- * information needed to be piped out as is. Obviously this is much faster
- * than decoding and encoding again. This routine should be followed by calls
- * to DGifGetCodeNext, until NULL block is returned.
- * The block should NOT be freed by the user (not dynamically allocated).
- *****************************************************************************/
+ Get the image code in compressed form. This routine can be called if the
+ information needed to be piped out as is. Obviously this is much faster
+ than decoding and encoding again. This routine should be followed by calls
+ to DGifGetCodeNext, until NULL block is returned.
+ The block should NOT be freed by the user (not dynamically allocated).
+******************************************************************************/
int
-DGifGetCode(GifFileType * GifFile,
- int *CodeSize,
- GifByteType ** CodeBlock) {
-
+DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
+{
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
- _GifError = D_GIF_ERR_NOT_READABLE;
+ GifFile->Error = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
@@ -681,27 +736,30 @@
}
/******************************************************************************
- * Continue to get the image code in compressed form. This routine should be
- * called until NULL block is returned.
- * The block should NOT be freed by the user (not dynamically allocated).
- *****************************************************************************/
+ Continue to get the image code in compressed form. This routine should be
+ called until NULL block is returned.
+ The block should NOT be freed by the user (not dynamically allocated).
+******************************************************************************/
int
-DGifGetCodeNext(GifFileType * GifFile,
- GifByteType ** CodeBlock) {
-
+DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
+{
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
+ /* coverity[tainted_data_argument] */
+ /* coverity[check_return] */
if (READ(GifFile, &Buf, 1) != 1) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
+ /* coverity[lower_bounds] */
if (Buf > 0) {
*CodeBlock = Private->Buf; /* Use private unused buffer. */
(*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
+ /* coverity[tainted_data] */
if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
} else {
@@ -714,20 +772,19 @@
}
/******************************************************************************
- * Setup the LZ decompression for this image:
- *****************************************************************************/
+ Setup the LZ decompression for this image:
+******************************************************************************/
static int
-DGifSetupDecompress(GifFileType * GifFile) {
-
+DGifSetupDecompress(GifFileType *GifFile)
+{
int i, BitsPerPixel;
GifByteType CodeSize;
- unsigned int *Prefix;
+ GifPrefixType *Prefix;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
- READ(GifFile, &CodeSize, 1); /* Read Code size from file. */
- if (CodeSize >= 12) {
- /* Invalid initial code size: report failure */
- return GIF_ERROR;
+ /* coverity[check_return] */
+ if (READ(GifFile, &CodeSize, 1) < 1) { /* Read Code size from file. */
+ return GIF_ERROR; /* Failed to read Code size. */
}
BitsPerPixel = CodeSize;
@@ -751,20 +808,18 @@
}
/******************************************************************************
- * The LZ decompression routine:
- * This version decompress the given gif file into Line of length LineLen.
- * This routine can be called few times (one per scan line, for example), in
- * order the complete the whole image.
- *****************************************************************************/
+ The LZ decompression routine:
+ This version decompress the given GIF file into Line of length LineLen.
+ This routine can be called few times (one per scan line, for example), in
+ order the complete the whole image.
+******************************************************************************/
static int
-DGifDecompressLine(GifFileType * GifFile,
- GifPixelType * Line,
- int LineLen) {
-
+DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
+{
int i = 0;
int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
GifByteType *Stack, *Suffix;
- unsigned int *Prefix;
+ GifPrefixType *Prefix;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
StackPtr = Private->StackPtr;
@@ -775,8 +830,12 @@
ClearCode = Private->ClearCode;
LastCode = Private->LastCode;
+ if (StackPtr > LZ_MAX_CODE) {
+ return GIF_ERROR;
+ }
+
if (StackPtr != 0) {
- /* Let pop the stack off before continueing to read the gif file: */
+ /* Let pop the stack off before continueing to read the GIF file: */
while (StackPtr != 0 && i < LineLen)
Line[i++] = Stack[--StackPtr];
}
@@ -789,11 +848,8 @@
/* Note however that usually we will not be here as we will stop
* decoding as soon as we got all the pixel, or EOF code will
* not be read at all, and DGifGetLine/Pixel clean everything. */
- if (i != LineLen - 1 || Private->PixelCount != 0) {
- _GifError = D_GIF_ERR_EOF_TOO_SOON;
- return GIF_ERROR;
- }
- i++;
+ GifFile->Error = D_GIF_ERR_EOF_TOO_SOON;
+ return GIF_ERROR;
} else if (CrntCode == ClearCode) {
/* We need to start over again: */
for (j = 0; j <= LZ_MAX_CODE; j++)
@@ -815,36 +871,37 @@
* pixels on our stack. If we done, pop the stack in reverse
* (thats what stack is good for!) order to output. */
if (Prefix[CrntCode] == NO_SUCH_CODE) {
+ CrntPrefix = LastCode;
+
/* Only allowed if CrntCode is exactly the running code:
* In that case CrntCode = XXXCode, CrntCode or the
* prefix code is last code and the suffix char is
* exactly the prefix of last code! */
if (CrntCode == Private->RunningCode - 2) {
- CrntPrefix = LastCode;
Suffix[Private->RunningCode - 2] =
Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
LastCode,
ClearCode);
} else {
- _GifError = D_GIF_ERR_IMAGE_DEFECT;
- return GIF_ERROR;
+ Suffix[Private->RunningCode - 2] =
+ Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
+ CrntCode,
+ ClearCode);
}
} else
CrntPrefix = CrntCode;
- /* Now (if image is O.K.) we should not get an NO_SUCH_CODE
- * During the trace. As we might loop forever, in case of
- * defective image, we count the number of loops we trace
- * and stop if we got LZ_MAX_CODE. obviously we can not
- * loop more than that. */
- j = 0;
- while (j++ <= LZ_MAX_CODE &&
+ /* Now (if image is O.K.) we should not get a NO_SUCH_CODE
+ * during the trace. As we might loop forever, in case of
+ * defective image, we use StackPtr as loop counter and stop
+ * before overflowing Stack[]. */
+ while (StackPtr < LZ_MAX_CODE &&
CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
Stack[StackPtr++] = Suffix[CrntPrefix];
CrntPrefix = Prefix[CrntPrefix];
}
- if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
- _GifError = D_GIF_ERR_IMAGE_DEFECT;
+ if (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
+ GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
return GIF_ERROR;
}
/* Push the last character on stack: */
@@ -854,7 +911,7 @@
while (StackPtr != 0 && i < LineLen)
Line[i++] = Stack[--StackPtr];
}
- if (LastCode != NO_SUCH_CODE) {
+ if (LastCode != NO_SUCH_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
Prefix[Private->RunningCode - 2] = LastCode;
if (CrntCode == Private->RunningCode - 2) {
@@ -880,37 +937,38 @@
}
/******************************************************************************
- * Routine to trace the Prefixes linked list until we get a prefix which is
- * not code, but a pixel value (less than ClearCode). Returns that pixel value.
- * If image is defective, we might loop here forever, so we limit the loops to
- * the maximum possible if image O.k. - LZ_MAX_CODE times.
- *****************************************************************************/
+ Routine to trace the Prefixes linked list until we get a prefix which is
+ not code, but a pixel value (less than ClearCode). Returns that pixel value.
+ If image is defective, we might loop here forever, so we limit the loops to
+ the maximum possible if image O.k. - LZ_MAX_CODE times.
+******************************************************************************/
static int
-DGifGetPrefixChar(unsigned int *Prefix,
- int Code,
- int ClearCode) {
-
+DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode)
+{
int i = 0;
- while (Code > ClearCode && i++ <= LZ_MAX_CODE)
+ while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
+ if (Code > LZ_MAX_CODE) {
+ return NO_SUCH_CODE;
+ }
Code = Prefix[Code];
+ }
return Code;
}
/******************************************************************************
- * Interface for accessing the LZ codes directly. Set Code to the real code
- * (12bits), or to -1 if EOF code is returned.
- *****************************************************************************/
+ Interface for accessing the LZ codes directly. Set Code to the real code
+ (12bits), or to -1 if EOF code is returned.
+******************************************************************************/
int
-DGifGetLZCodes(GifFileType * GifFile,
- int *Code) {
-
+DGifGetLZCodes(GifFileType *GifFile, int *Code)
+{
GifByteType *CodeBlock;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
- _GifError = D_GIF_ERR_NOT_READABLE;
+ GifFile->Error = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
@@ -936,32 +994,38 @@
}
/******************************************************************************
- * The LZ decompression input routine:
- * This routine is responsable for the decompression of the bit stream from
- * 8 bits (bytes) packets, into the real codes.
- * Returns GIF_OK if read succesfully.
- *****************************************************************************/
+ The LZ decompression input routine:
+ This routine is responsable for the decompression of the bit stream from
+ 8 bits (bytes) packets, into the real codes.
+ Returns GIF_OK if read successfully.
+******************************************************************************/
static int
-DGifDecompressInput(GifFileType * GifFile,
- int *Code) {
-
- GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
-
- GifByteType NextByte;
- static unsigned int CodeMasks[] = {
+DGifDecompressInput(GifFileType *GifFile, int *Code)
+{
+ static const unsigned short CodeMasks[] = {
0x0000, 0x0001, 0x0003, 0x0007,
0x000f, 0x001f, 0x003f, 0x007f,
0x00ff, 0x01ff, 0x03ff, 0x07ff,
0x0fff
};
+ GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
+
+ GifByteType NextByte;
+
+ /* The image can't contain more than LZ_BITS per code. */
+ if (Private->RunningBits > LZ_BITS) {
+ GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
+ return GIF_ERROR;
+ }
+
while (Private->CrntShiftState < Private->RunningBits) {
/* Needs to get more bytes from input stream for next code: */
if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
return GIF_ERROR;
}
Private->CrntShiftDWord |=
- ((unsigned long)NextByte) << Private->CrntShiftState;
+ ((unsigned long)NextByte) << Private->CrntShiftState;
Private->CrntShiftState += 8;
}
*Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
@@ -970,37 +1034,45 @@
Private->CrntShiftState -= Private->RunningBits;
/* If code cannot fit into RunningBits bits, must raise its size. Note
- * however that codes above 4095 are used for special signaling. */
- if (++Private->RunningCode > Private->MaxCode1) {
- if (Private->RunningBits < LZ_BITS) {
- Private->MaxCode1 <<= 1;
- Private->RunningBits++;
- } else {
- Private->RunningCode = Private->MaxCode1;
- }
+ * however that codes above 4095 are used for special signaling.
+ * If we're using LZ_BITS bits already and we're at the max code, just
+ * keep using the table as it is, don't increment Private->RunningCode.
+ */
+ if (Private->RunningCode < LZ_MAX_CODE + 2 &&
+ ++Private->RunningCode > Private->MaxCode1 &&
+ Private->RunningBits < LZ_BITS) {
+ Private->MaxCode1 <<= 1;
+ Private->RunningBits++;
}
return GIF_OK;
}
/******************************************************************************
- * This routines read one gif data block at a time and buffers it internally
- * so that the decompression routine could access it.
- * The routine returns the next byte from its internal buffer (or read next
- * block in if buffer empty) and returns GIF_OK if succesful.
- *****************************************************************************/
+ This routines read one GIF data block at a time and buffers it internally
+ so that the decompression routine could access it.
+ The routine returns the next byte from its internal buffer (or read next
+ block in if buffer empty) and returns GIF_OK if succesful.
+******************************************************************************/
static int
-DGifBufferedInput(GifFileType * GifFile,
- GifByteType * Buf,
- GifByteType * NextByte) {
-
+DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
+{
if (Buf[0] == 0) {
/* Needs to read the next buffer - this one is empty: */
+ /* coverity[check_return] */
if (READ(GifFile, Buf, 1) != 1) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
+ return GIF_ERROR;
+ }
+ /* There shouldn't be any empty data blocks here as the LZW spec
+ * says the LZW termination code should come first. Therefore we
+ * shouldn't be inside this routine at that point.
+ */
+ if (Buf[0] == 0) {
+ GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
return GIF_ERROR;
}
if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
- _GifError = D_GIF_ERR_READ_FAILED;
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
*NextByte = Buf[1];
@@ -1015,21 +1087,21 @@
}
/******************************************************************************
- * This routine reads an entire GIF into core, hanging all its state info off
- * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
- * first to initialize I/O. Its inverse is EGifSpew().
- ******************************************************************************/
+ This routine reads an entire GIF into core, hanging all its state info off
+ the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
+ first to initialize I/O. Its inverse is EGifSpew().
+*******************************************************************************/
int
-DGifSlurp(GifFileType * GifFile) {
-
- int ImageSize;
+DGifSlurp(GifFileType *GifFile)
+{
+ size_t ImageSize;
GifRecordType RecordType;
SavedImage *sp;
GifByteType *ExtData;
- SavedImage temp_save;
+ int ExtFunction;
- temp_save.ExtensionBlocks = NULL;
- temp_save.ExtensionBlockCount = 0;
+ GifFile->ExtensionBlocks = NULL;
+ GifFile->ExtensionBlockCount = 0;
do {
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
@@ -1041,44 +1113,77 @@
return (GIF_ERROR);
sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
+ /* Allocate memory for the image */
+ if (sp->ImageDesc.Width < 0 && sp->ImageDesc.Height < 0 &&
+ sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) {
+ return GIF_ERROR;
+ }
ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
+ if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
+ return GIF_ERROR;
+ }
sp->RasterBits = (unsigned char *)malloc(ImageSize *
- sizeof(GifPixelType));
+ sizeof(GifPixelType));
+
if (sp->RasterBits == NULL) {
return GIF_ERROR;
}
- if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) ==
- GIF_ERROR)
- return (GIF_ERROR);
- if (temp_save.ExtensionBlocks) {
- sp->ExtensionBlocks = temp_save.ExtensionBlocks;
- sp->ExtensionBlockCount = temp_save.ExtensionBlockCount;
- temp_save.ExtensionBlocks = NULL;
- temp_save.ExtensionBlockCount = 0;
+ if (sp->ImageDesc.Interlace) {
+ int i, j;
+ /*
+ * The way an interlaced image should be read -
+ * offsets and jumps...
+ */
+ int InterlacedOffset[] = { 0, 4, 2, 1 };
+ int InterlacedJumps[] = { 8, 8, 4, 2 };
+ /* Need to perform 4 passes on the image */
+ for (i = 0; i < 4; i++)
+ for (j = InterlacedOffset[i];
+ j < sp->ImageDesc.Height;
+ j += InterlacedJumps[i]) {
+ if (DGifGetLine(GifFile,
+ sp->RasterBits+j*sp->ImageDesc.Width,
+ sp->ImageDesc.Width) == GIF_ERROR)
+ return GIF_ERROR;
+ }
+ }
+ else {
+ if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR)
+ return (GIF_ERROR);
+ }
- /* FIXME: The following is wrong. It is left in only for
- * backwards compatibility. Someday it should go away. Use
- * the sp->ExtensionBlocks->Function variable instead. */
- sp->Function = sp->ExtensionBlocks[0].Function;
+ if (GifFile->ExtensionBlocks) {
+ sp->ExtensionBlocks = GifFile->ExtensionBlocks;
+ sp->ExtensionBlockCount = GifFile->ExtensionBlockCount;
+
+ GifFile->ExtensionBlocks = NULL;
+ GifFile->ExtensionBlockCount = 0;
}
break;
case EXTENSION_RECORD_TYPE:
- if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) ==
- GIF_ERROR)
+ if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)
return (GIF_ERROR);
- while (ExtData != NULL) {
-
- /* Create an extension block with our data */
- if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1])
+ /* Create an extension block with our data */
+ if (ExtData != NULL) {
+ if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
+ &GifFile->ExtensionBlocks,
+ ExtFunction, ExtData[0], &ExtData[1])
== GIF_ERROR)
return (GIF_ERROR);
-
+ }
+ while (ExtData != NULL) {
if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
return (GIF_ERROR);
- temp_save.Function = 0;
+ /* Continue the extension block */
+ if (ExtData != NULL)
+ if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
+ &GifFile->ExtensionBlocks,
+ CONTINUE_EXT_FUNC_CODE,
+ ExtData[0], &ExtData[1]) == GIF_ERROR)
+ return (GIF_ERROR);
}
break;
@@ -1090,12 +1195,13 @@
}
} while (RecordType != TERMINATE_RECORD_TYPE);
- /* Just in case the Gif has an extension block without an associated
- * image... (Should we save this into a savefile structure with no image
- * instead? Have to check if the present writing code can handle that as
- * well.... */
- if (temp_save.ExtensionBlocks)
- FreeExtension(&temp_save);
+ /* Sanity check for corrupted file */
+ if (GifFile->ImageCount == 0) {
+ GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR;
+ return(GIF_ERROR);
+ }
return (GIF_OK);
}
+
+/* end */
diff --git a/src/share/native/sun/awt/giflib/gif_err.c b/src/share/native/sun/awt/giflib/gif_err.c
index 253ab1a..cbe6406 100644
--- a/src/share/native/sun/awt/giflib/gif_err.c
+++ b/src/share/native/sun/awt/giflib/gif_err.c
@@ -23,71 +23,81 @@
*/
/*****************************************************************************
- * "Gif-Lib" - Yet another gif library.
- *
- * Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989
- *****************************************************************************
- * Handle error reporting for the GIF library.
- *****************************************************************************
- * History:
- * 17 Jun 89 - Version 1.0 by Gershon Elber.
- ****************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+gif_err.c - handle error reporting for the GIF library.
+
+****************************************************************************/
#include <stdio.h>
+
#include "gif_lib.h"
-
-int _GifError = 0;
+#include "gif_lib_private.h"
/*****************************************************************************
- * Return the last GIF error (0 if none) and reset the error.
- ****************************************************************************/
-int
-GifLastError(void) {
- int i = _GifError;
+ Return a string description of the last GIF error
+*****************************************************************************/
+const char *
+GifErrorString(int ErrorCode)
+{
+ const char *Err;
- _GifError = 0;
-
- return i;
-}
-
-/*****************************************************************************
- * Print the last GIF error to stderr.
- ****************************************************************************/
-void
-PrintGifError(void) {
- char *Err;
-
- switch (_GifError) {
+ switch (ErrorCode) {
+ case E_GIF_ERR_OPEN_FAILED:
+ Err = "Failed to open given file";
+ break;
+ case E_GIF_ERR_WRITE_FAILED:
+ Err = "Failed to write to given file";
+ break;
+ case E_GIF_ERR_HAS_SCRN_DSCR:
+ Err = "Screen descriptor has already been set";
+ break;
+ case E_GIF_ERR_HAS_IMAG_DSCR:
+ Err = "Image descriptor is still active";
+ break;
+ case E_GIF_ERR_NO_COLOR_MAP:
+ Err = "Neither global nor local color map";
+ break;
+ case E_GIF_ERR_DATA_TOO_BIG:
+ Err = "Number of pixels bigger than width * height";
+ break;
+ case E_GIF_ERR_NOT_ENOUGH_MEM:
+ Err = "Failed to allocate required memory";
+ break;
+ case E_GIF_ERR_DISK_IS_FULL:
+ Err = "Write failed (disk full?)";
+ break;
+ case E_GIF_ERR_CLOSE_FAILED:
+ Err = "Failed to close given file";
+ break;
+ case E_GIF_ERR_NOT_WRITEABLE:
+ Err = "Given file was not opened for write";
+ break;
case D_GIF_ERR_OPEN_FAILED:
Err = "Failed to open given file";
break;
case D_GIF_ERR_READ_FAILED:
- Err = "Failed to Read from given file";
+ Err = "Failed to read from given file";
break;
case D_GIF_ERR_NOT_GIF_FILE:
- Err = "Given file is NOT GIF file";
+ Err = "Data is not in GIF format";
break;
case D_GIF_ERR_NO_SCRN_DSCR:
- Err = "No Screen Descriptor detected";
+ Err = "No screen descriptor detected";
break;
case D_GIF_ERR_NO_IMAG_DSCR:
Err = "No Image Descriptor detected";
break;
case D_GIF_ERR_NO_COLOR_MAP:
- Err = "Neither Global Nor Local color map";
+ Err = "Neither global nor local color map";
break;
case D_GIF_ERR_WRONG_RECORD:
Err = "Wrong record type detected";
break;
case D_GIF_ERR_DATA_TOO_BIG:
- Err = "#Pixels bigger than Width * Height";
+ Err = "Number of pixels bigger than width * height";
break;
case D_GIF_ERR_NOT_ENOUGH_MEM:
- Err = "Fail to allocate required memory";
+ Err = "Failed to allocate required memory";
break;
case D_GIF_ERR_CLOSE_FAILED:
Err = "Failed to close given file";
@@ -99,14 +109,13 @@
Err = "Image is defective, decoding aborted";
break;
case D_GIF_ERR_EOF_TOO_SOON:
- Err = "Image EOF detected, before image complete";
+ Err = "Image EOF detected before image complete";
break;
default:
Err = NULL;
break;
}
- if (Err != NULL)
- fprintf(stderr, "\nGIF-LIB error: %s.\n", Err);
- else
- fprintf(stderr, "\nGIF-LIB undefined error %d.\n", _GifError);
+ return Err;
}
+
+/* end */
diff --git a/src/share/native/sun/awt/giflib/gif_hash.h b/src/share/native/sun/awt/giflib/gif_hash.h
new file mode 100644
index 0000000..5896875
--- /dev/null
+++ b/src/share/native/sun/awt/giflib/gif_hash.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/******************************************************************************
+
+gif_hash.h - magfic constants and declarations for GIF LZW
+
+******************************************************************************/
+
+#ifndef _GIF_HASH_H_
+#define _GIF_HASH_H_
+
+#include <stdint.h>
+
+#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */
+#define HT_KEY_MASK 0x1FFF /* 13bits keys */
+#define HT_KEY_NUM_BITS 13 /* 13bits keys */
+#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */
+#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
+
+/* The 32 bits of the long are divided into two parts for the key & code: */
+/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */
+/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */
+/* The key is the upper 20 bits. The code is the lower 12. */
+#define HT_GET_KEY(l) (l >> 12)
+#define HT_GET_CODE(l) (l & 0x0FFF)
+#define HT_PUT_KEY(l) (l << 12)
+#define HT_PUT_CODE(l) (l & 0x0FFF)
+
+typedef struct GifHashTableType {
+ uint32_t HTable[HT_SIZE];
+} GifHashTableType;
+
+GifHashTableType *_InitHashTable(void);
+void _ClearHashTable(GifHashTableType *HashTable);
+void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code);
+int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key);
+
+#endif /* _GIF_HASH_H_ */
+
+/* end */
diff --git a/src/share/native/sun/awt/giflib/gif_lib.h b/src/share/native/sun/awt/giflib/gif_lib.h
index 54fb321..aa35636 100644
--- a/src/share/native/sun/awt/giflib/gif_lib.h
+++ b/src/share/native/sun/awt/giflib/gif_lib.h
@@ -23,21 +23,10 @@
*/
/******************************************************************************
- * In order to make life a little bit easier when using the GIF file format,
- * this library was written, and which does all the dirty work...
- *
- * Written by Gershon Elber, Jun. 1989
- * Hacks by Eric S. Raymond, Sep. 1992
- ******************************************************************************
- * History:
- * 14 Jun 89 - Version 1.0 by Gershon Elber.
- * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names)
- * 15 Sep 90 - Version 2.0 by Eric S. Raymond (Changes to suoport GIF slurp)
- * 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support)
- * 17 Dec 98 - Version 4.0 by Toshio Kuratomi (Fix extension writing code)
- *****************************************************************************/
-/* all encoding functionality stripped */
+gif_lib.h - service library for decoding and encoding GIF images
+
+*****************************************************************************/
#ifndef _GIF_LIB_H_
#define _GIF_LIB_H_ 1
@@ -46,21 +35,21 @@
extern "C" {
#endif /* __cplusplus */
-#define GIF_LIB_VERSION " Version 4.1, "
+#define GIFLIB_MAJOR 5
+#define GIFLIB_MINOR 1
+#define GIFLIB_RELEASE 1
#define GIF_ERROR 0
#define GIF_OK 1
-#ifndef TRUE
-#define TRUE 1
-#endif /* TRUE */
-#ifndef FALSE
-#define FALSE 0
-#endif /* FALSE */
+#include <stddef.h>
-#ifndef NULL
-#define NULL 0
-#endif /* NULL */
+#ifdef bool
+#undef bool
+#endif
+typedef int bool;
+#define false 0
+#define true 1
#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */
#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1
@@ -68,21 +57,11 @@
#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */
#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */
-#define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */
-
-typedef int GifBooleanType;
typedef unsigned char GifPixelType;
typedef unsigned char *GifRowType;
typedef unsigned char GifByteType;
-
-#define GIF_MESSAGE(Msg) fprintf(stderr, "\n%s: %s\n", PROGRAM_NAME, Msg)
-#define GIF_EXIT(Msg) { GIF_MESSAGE(Msg); exit(-3); }
-
-#ifdef SYSV
-#define VoidPtr char *
-#else
-#define VoidPtr void *
-#endif /* SYSV */
+typedef unsigned int GifPrefixType;
+typedef int GifWord;
typedef struct GifColorType {
GifByteType Red, Green, Blue;
@@ -91,27 +70,52 @@
typedef struct ColorMapObject {
int ColorCount;
int BitsPerPixel;
+ bool SortFlag;
GifColorType *Colors; /* on malloc(3) heap */
} ColorMapObject;
typedef struct GifImageDesc {
- int Left, Top, Width, Height, /* Current image dimensions. */
- Interlace; /* Sequential/Interlaced lines. */
- ColorMapObject *ColorMap; /* The local color map */
+ GifWord Left, Top, Width, Height; /* Current image dimensions. */
+ bool Interlace; /* Sequential/Interlaced lines. */
+ ColorMapObject *ColorMap; /* The local color map */
} GifImageDesc;
+typedef struct ExtensionBlock {
+ int ByteCount;
+ GifByteType *Bytes; /* on malloc(3) heap */
+ int Function; /* The block function code */
+#define CONTINUE_EXT_FUNC_CODE 0x00 /* continuation subblock */
+#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
+#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control (GIF89) */
+#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
+#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */
+} ExtensionBlock;
+
+typedef struct SavedImage {
+ GifImageDesc ImageDesc;
+ GifByteType *RasterBits; /* on malloc(3) heap */
+ int ExtensionBlockCount; /* Count of extensions before image */
+ ExtensionBlock *ExtensionBlocks; /* Extensions before image */
+} SavedImage;
+
typedef struct GifFileType {
- int SWidth, SHeight, /* Screen dimensions. */
- SColorResolution, /* How many colors can we generate? */
- SBackGroundColor; /* I hope you understand this one... */
- ColorMapObject *SColorMap; /* NULL if not exists. */
- int ImageCount; /* Number of current image */
- GifImageDesc Image; /* Block describing current image */
- struct SavedImage *SavedImages; /* Use this to accumulate file state */
- VoidPtr UserData; /* hook to attach user data (TVT) */
- VoidPtr Private; /* Don't mess with this! */
+ GifWord SWidth, SHeight; /* Size of virtual canvas */
+ GifWord SColorResolution; /* How many colors can we generate? */
+ GifWord SBackGroundColor; /* Background color for virtual canvas */
+ GifByteType AspectByte; /* Used to compute pixel aspect ratio */
+ ColorMapObject *SColorMap; /* Global colormap, NULL if nonexistent. */
+ int ImageCount; /* Number of current image (both APIs) */
+ GifImageDesc Image; /* Current image (low-level API) */
+ SavedImage *SavedImages; /* Image sequence (high-level API) */
+ int ExtensionBlockCount; /* Count extensions past last image */
+ ExtensionBlock *ExtensionBlocks; /* Extensions past last image */
+ int Error; /* Last error condition reported */
+ void *UserData; /* hook to attach user data (TVT) */
+ void *Private; /* Don't mess with this! */
} GifFileType;
+#define GIF_ASPECT_RATIO(n) ((n)+15.0/64.0)
+
typedef enum {
UNDEFINED_RECORD_TYPE,
SCREEN_DESC_RECORD_TYPE,
@@ -120,58 +124,95 @@
TERMINATE_RECORD_TYPE /* Begin with ';' */
} GifRecordType;
-/* DumpScreen2Gif routine constants identify type of window/screen to dump.
- * Note all values below 1000 are reserved for the IBMPC different display
- * devices (it has many!) and are compatible with the numbering TC2.0
- * (Turbo C 2.0 compiler for IBM PC) gives to these devices.
- */
-typedef enum {
- GIF_DUMP_SGI_WINDOW = 1000,
- GIF_DUMP_X_WINDOW = 1001
-} GifScreenDumpType;
-
/* func type to read gif data from arbitrary sources (TVT) */
typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
-/* func type to write gif data ro arbitrary targets.
+/* func type to write gif data to arbitrary targets.
* Returns count of bytes written. (MRB)
*/
typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int);
/******************************************************************************
- * GIF89 extension function codes
+ GIF89 structures
******************************************************************************/
-#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
-#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control */
-#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
-#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */
+typedef struct GraphicsControlBlock {
+ int DisposalMode;
+#define DISPOSAL_UNSPECIFIED 0 /* No disposal specified. */
+#define DISPOSE_DO_NOT 1 /* Leave image in place */
+#define DISPOSE_BACKGROUND 2 /* Set area too background color */
+#define DISPOSE_PREVIOUS 3 /* Restore to previous content */
+ bool UserInputFlag; /* User confirmation required before disposal */
+ int DelayTime; /* pre-display delay in 0.01sec units */
+ int TransparentColor; /* Palette index for transparency, -1 if none */
+#define NO_TRANSPARENT_COLOR -1
+} GraphicsControlBlock;
/******************************************************************************
- * O.K., here are the routines one can access in order to decode GIF file:
- * (GIF_LIB file DGIF_LIB.C).
- *****************************************************************************/
+ GIF encoding routines
+******************************************************************************/
-GifFileType *DGifOpenFileName(const char *GifFileName);
-GifFileType *DGifOpenFileHandle(int GifFileHandle);
-GifFileType *DGifOpen(void *userPtr, InputFunc readFunc); /* new one
- * (TVT) */
+/* Main entry points */
+GifFileType *EGifOpenFileName(const char *GifFileName,
+ const bool GifTestExistence, int *Error);
+GifFileType *EGifOpenFileHandle(const int GifFileHandle, int *Error);
+GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *Error);
+int EGifSpew(GifFileType * GifFile);
+const char *EGifGetGifVersion(GifFileType *GifFile); /* new in 5.x */
+int EGifCloseFile(GifFileType *GifFile, int *ErrorCode);
+
+#define E_GIF_SUCCEEDED 0
+#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */
+#define E_GIF_ERR_WRITE_FAILED 2
+#define E_GIF_ERR_HAS_SCRN_DSCR 3
+#define E_GIF_ERR_HAS_IMAG_DSCR 4
+#define E_GIF_ERR_NO_COLOR_MAP 5
+#define E_GIF_ERR_DATA_TOO_BIG 6
+#define E_GIF_ERR_NOT_ENOUGH_MEM 7
+#define E_GIF_ERR_DISK_IS_FULL 8
+#define E_GIF_ERR_CLOSE_FAILED 9
+#define E_GIF_ERR_NOT_WRITEABLE 10
+
+/* These are legacy. You probably do not want to call them directly */
+int EGifPutScreenDesc(GifFileType *GifFile,
+ const int GifWidth, const int GifHeight,
+ const int GifColorRes,
+ const int GifBackGround,
+ const ColorMapObject *GifColorMap);
+int EGifPutImageDesc(GifFileType *GifFile,
+ const int GifLeft, const int GifTop,
+ const int GifWidth, const int GifHeight,
+ const bool GifInterlace,
+ const ColorMapObject *GifColorMap);
+void EGifSetGifVersion(GifFileType *GifFile, const bool gif89);
+int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine,
+ int GifLineLen);
+int EGifPutPixel(GifFileType *GifFile, const GifPixelType GifPixel);
+int EGifPutComment(GifFileType *GifFile, const char *GifComment);
+int EGifPutExtensionLeader(GifFileType *GifFile, const int GifExtCode);
+int EGifPutExtensionBlock(GifFileType *GifFile,
+ const int GifExtLen, const void *GifExtension);
+int EGifPutExtensionTrailer(GifFileType *GifFile);
+int EGifPutExtension(GifFileType *GifFile, const int GifExtCode,
+ const int GifExtLen,
+ const void *GifExtension);
+int EGifPutCode(GifFileType *GifFile, int GifCodeSize,
+ const GifByteType *GifCodeBlock);
+int EGifPutCodeNext(GifFileType *GifFile,
+ const GifByteType *GifCodeBlock);
+
+/******************************************************************************
+ GIF decoding routines
+******************************************************************************/
+
+/* Main entry points */
+GifFileType *DGifOpenFileName(const char *GifFileName, int *Error);
+GifFileType *DGifOpenFileHandle(int GifFileHandle, int *Error);
int DGifSlurp(GifFileType * GifFile);
-int DGifGetScreenDesc(GifFileType * GifFile);
-int DGifGetRecordType(GifFileType * GifFile, GifRecordType * GifType);
-int DGifGetImageDesc(GifFileType * GifFile);
-int DGifGetLine(GifFileType * GifFile, GifPixelType * GifLine, int GifLineLen);
-int DGifGetPixel(GifFileType * GifFile, GifPixelType GifPixel);
-int DGifGetComment(GifFileType * GifFile, char *GifComment);
-int DGifGetExtension(GifFileType * GifFile, int *GifExtCode,
- GifByteType ** GifExtension);
-int DGifGetExtensionNext(GifFileType * GifFile, GifByteType ** GifExtension);
-int DGifGetCode(GifFileType * GifFile, int *GifCodeSize,
- GifByteType ** GifCodeBlock);
-int DGifGetCodeNext(GifFileType * GifFile, GifByteType ** GifCodeBlock);
-int DGifGetLZCodes(GifFileType * GifFile, int *GifCode);
-int DGifCloseFile(GifFileType * GifFile);
+GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *Error); /* new one (TVT) */
+ int DGifCloseFile(GifFileType * GifFile, int *ErrorCode);
+#define D_GIF_SUCCEEDED 0
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
#define D_GIF_ERR_READ_FAILED 102
#define D_GIF_ERR_NOT_GIF_FILE 103
@@ -186,68 +227,113 @@
#define D_GIF_ERR_IMAGE_DEFECT 112
#define D_GIF_ERR_EOF_TOO_SOON 113
+/* These are legacy. You probably do not want to call them directly */
+int DGifGetScreenDesc(GifFileType *GifFile);
+int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
+int DGifGetImageDesc(GifFileType *GifFile);
+int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
+int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel);
+int DGifGetComment(GifFileType *GifFile, char *GifComment);
+int DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
+ GifByteType **GifExtension);
+int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension);
+int DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
+ GifByteType **GifCodeBlock);
+int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
+int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
+
/******************************************************************************
- * O.K., here are the routines from GIF_LIB file GIF_ERR.C.
+ Color table quantization (deprecated)
******************************************************************************/
-extern void PrintGifError(void);
-extern int GifLastError(void);
+int GifQuantizeBuffer(unsigned int Width, unsigned int Height,
+ int *ColorMapSize, GifByteType * RedInput,
+ GifByteType * GreenInput, GifByteType * BlueInput,
+ GifByteType * OutputBuffer,
+ GifColorType * OutputColorMap);
/******************************************************************************
- * O.K., here are the routines from GIF_LIB file DEV2GIF.C.
+ Error handling and reporting.
******************************************************************************/
-extern int DumpScreen2Gif(const char *FileName,
- int ReqGraphDriver,
- long ReqGraphMode1,
- long ReqGraphMode2,
- long ReqGraphMode3);
+extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */
/*****************************************************************************
- *
- * Everything below this point is new after version 1.2, supporting `slurp
- * mode' for doing I/O in two big belts with all the image-bashing in core.
- *
- *****************************************************************************/
+ Everything below this point is new after version 1.2, supporting `slurp
+ mode' for doing I/O in two big belts with all the image-bashing in core.
+******************************************************************************/
/******************************************************************************
- * Color Map handling from ALLOCGIF.C
- *****************************************************************************/
+ Color map handling from gif_alloc.c
+******************************************************************************/
-extern ColorMapObject *MakeMapObject(int ColorCount,
- const GifColorType * ColorMap);
-extern void FreeMapObject(ColorMapObject * Object);
-extern int BitSize(int n);
+extern ColorMapObject *GifMakeMapObject(int ColorCount,
+ const GifColorType *ColorMap);
+extern void GifFreeMapObject(ColorMapObject *Object);
+extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
+ const ColorMapObject *ColorIn2,
+ GifPixelType ColorTransIn2[]);
+extern int GifBitSize(int n);
/******************************************************************************
- * Support for the in-core structures allocation (slurp mode).
- *****************************************************************************/
+ Support for the in-core structures allocation (slurp mode).
+******************************************************************************/
-/* This is the in-core version of an extension record */
-typedef struct {
- int ByteCount;
- char *Bytes; /* on malloc(3) heap */
- int Function; /* Holds the type of the Extension block. */
-} ExtensionBlock;
+extern void GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]);
+extern int GifAddExtensionBlock(int *ExtensionBlock_Count,
+ ExtensionBlock **ExtensionBlocks,
+ int Function,
+ unsigned int Len, unsigned char ExtData[]);
+extern void GifFreeExtensions(int *ExtensionBlock_Count,
+ ExtensionBlock **ExtensionBlocks);
+extern SavedImage *GifMakeSavedImage(GifFileType *GifFile,
+ const SavedImage *CopyFrom);
+extern void GifFreeSavedImages(GifFileType *GifFile);
-/* This holds an image header, its unpacked raster bits, and extensions */
-typedef struct SavedImage {
- GifImageDesc ImageDesc;
- unsigned char *RasterBits; /* on malloc(3) heap */
- int Function; /* DEPRECATED: Use ExtensionBlocks[x].Function instead */
- int ExtensionBlockCount;
- ExtensionBlock *ExtensionBlocks; /* on malloc(3) heap */
-} SavedImage;
+/******************************************************************************
+ 5.x functions for GIF89 graphics control blocks
+******************************************************************************/
-extern void MakeExtension(SavedImage * New, int Function);
-extern int AddExtensionBlock(SavedImage * New, int Len,
- unsigned char ExtData[]);
-extern void FreeExtension(SavedImage * Image);
-extern SavedImage *MakeSavedImage(GifFileType * GifFile,
- const SavedImage * CopyFrom);
-extern void FreeSavedImages(GifFileType * GifFile);
+int DGifExtensionToGCB(const size_t GifExtensionLength,
+ const GifByteType *GifExtension,
+ GraphicsControlBlock *GCB);
+size_t EGifGCBToExtension(const GraphicsControlBlock *GCB,
+ GifByteType *GifExtension);
+int DGifSavedExtensionToGCB(GifFileType *GifFile,
+ int ImageIndex,
+ GraphicsControlBlock *GCB);
+int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB,
+ GifFileType *GifFile,
+ int ImageIndex);
+
+/******************************************************************************
+ The library's internal utility font
+******************************************************************************/
+
+#define GIF_FONT_WIDTH 8
+#define GIF_FONT_HEIGHT 8
+extern const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH];
+
+extern void GifDrawText8x8(SavedImage *Image,
+ const int x, const int y,
+ const char *legend, const int color);
+
+extern void GifDrawBox(SavedImage *Image,
+ const int x, const int y,
+ const int w, const int d, const int color);
+
+extern void GifDrawRectangle(SavedImage *Image,
+ const int x, const int y,
+ const int w, const int d, const int color);
+
+extern void GifDrawBoxedText8x8(SavedImage *Image,
+ const int x, const int y,
+ const char *legend,
+ const int border, const int bg, const int fg);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _GIF_LIB_H */
+
+/* end */
diff --git a/src/share/native/sun/awt/giflib/gif_lib_private.h b/src/share/native/sun/awt/giflib/gif_lib_private.h
index 422d255..67c4746 100644
--- a/src/share/native/sun/awt/giflib/gif_lib_private.h
+++ b/src/share/native/sun/awt/giflib/gif_lib_private.h
@@ -22,21 +22,21 @@
* questions.
*/
+/****************************************************************************
+
+gif_lib_private.h - internal giflib routines and structures
+
+****************************************************************************/
+
#ifndef _GIF_LIB_PRIVATE_H
#define _GIF_LIB_PRIVATE_H
#include "gif_lib.h"
+#include "gif_hash.h"
-#define PROGRAM_NAME "LIBUNGIF"
-
-#ifdef SYSV
-#define VersionStr "Gif library module,\t\tEric S. Raymond\n\
- (C) Copyright 1997 Eric S. Raymond\n"
-#else
-#define VersionStr PROGRAM_NAME " IBMPC " GIF_LIB_VERSION \
- " Eric S. Raymond, " __DATE__ ", " \
- __TIME__ "\n" "(C) Copyright 1997 Eric S. Raymond\n"
-#endif /* SYSV */
+#define EXTENSION_INTRODUCER 0x21
+#define DESCRIPTOR_INTRODUCER 0x2c
+#define TERMINATOR_INTRODUCER 0x3b
#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
#define LZ_BITS 12
@@ -54,7 +54,7 @@
#define IS_WRITEABLE(Private) (Private->FileState & FILE_STATE_WRITE)
typedef struct GifFilePrivateType {
- int FileState, FileHandle, /* Where all this data goes to! */
+ GifWord FileState, FileHandle, /* Where all this data goes to! */
BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */
ClearCode, /* The CLEAR LZ code. */
EOFCode, /* The EOF LZ code. */
@@ -73,9 +73,11 @@
GifByteType Buf[256]; /* Compressed input is buffered here. */
GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
- unsigned int Prefix[LZ_MAX_CODE + 1];
+ GifPrefixType Prefix[LZ_MAX_CODE + 1];
+ GifHashTableType *HashTable;
+ bool gif89;
} GifFilePrivateType;
-extern int _GifError;
-
#endif /* _GIF_LIB_PRIVATE_H */
+
+/* end */
diff --git a/src/share/native/sun/awt/giflib/gifalloc.c b/src/share/native/sun/awt/giflib/gifalloc.c
index 96f342a..f7a6a3d 100644
--- a/src/share/native/sun/awt/giflib/gifalloc.c
+++ b/src/share/native/sun/awt/giflib/gifalloc.c
@@ -23,36 +23,27 @@
*/
/*****************************************************************************
- * "Gif-Lib" - Yet another gif library.
- *
- * Written by: Gershon Elber Ver 0.1, Jun. 1989
- * Extensively hacked by: Eric S. Raymond Ver 1.?, Sep 1992
- *****************************************************************************
- * GIF construction tools
- *****************************************************************************
- * History:
- * 15 Sep 92 - Version 1.0 by Eric Raymond.
- ****************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+ GIF construction tools
+
+****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+
#include "gif_lib.h"
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
/******************************************************************************
- * Miscellaneous utility functions
- *****************************************************************************/
+ Miscellaneous utility functions
+******************************************************************************/
/* return smallest bitfield size n will fit in */
int
-BitSize(int n) {
-
+GifBitSize(int n)
+{
register int i;
for (i = 1; i <= 8; i++)
@@ -62,22 +53,21 @@
}
/******************************************************************************
- * Color map object functions
- *****************************************************************************/
+ Color map object functions
+******************************************************************************/
/*
* Allocate a color map of given size; initialize with contents of
* ColorMap if that pointer is non-NULL.
*/
ColorMapObject *
-MakeMapObject(int ColorCount,
- const GifColorType * ColorMap) {
-
+GifMakeMapObject(int ColorCount, const GifColorType *ColorMap)
+{
ColorMapObject *Object;
/*** FIXME: Our ColorCount has to be a power of two. Is it necessary to
* make the user know that or should we automatically round up instead? */
- if (ColorCount != (1 << BitSize(ColorCount))) {
+ if (ColorCount != (1 << GifBitSize(ColorCount))) {
return ((ColorMapObject *) NULL);
}
@@ -93,9 +83,10 @@
}
Object->ColorCount = ColorCount;
- Object->BitsPerPixel = BitSize(ColorCount);
+ Object->BitsPerPixel = GifBitSize(ColorCount);
+ Object->SortFlag = false;
- if (ColorMap) {
+ if (ColorMap != NULL) {
memcpy((char *)Object->Colors,
(char *)ColorMap, ColorCount * sizeof(GifColorType));
}
@@ -103,118 +94,222 @@
return (Object);
}
-/*
- * Free a color map object
- */
+/*******************************************************************************
+Free a color map object
+*******************************************************************************/
void
-FreeMapObject(ColorMapObject * Object) {
-
+GifFreeMapObject(ColorMapObject *Object)
+{
if (Object != NULL) {
- free(Object->Colors);
- free(Object);
- Object = NULL;
+ (void)free(Object->Colors);
+ (void)free(Object);
}
}
#ifdef DEBUG
void
-DumpColorMap(ColorMapObject * Object,
- FILE * fp) {
-
- if (Object) {
+DumpColorMap(ColorMapObject *Object,
+ FILE * fp)
+{
+ if (Object != NULL) {
int i, j, Len = Object->ColorCount;
for (i = 0; i < Len; i += 4) {
for (j = 0; j < 4 && j < Len; j++) {
- fprintf(fp, "%3d: %02x %02x %02x ", i + j,
- Object->Colors[i + j].Red,
- Object->Colors[i + j].Green,
- Object->Colors[i + j].Blue);
+ (void)fprintf(fp, "%3d: %02x %02x %02x ", i + j,
+ Object->Colors[i + j].Red,
+ Object->Colors[i + j].Green,
+ Object->Colors[i + j].Blue);
}
- fprintf(fp, "\n");
+ (void)fprintf(fp, "\n");
}
}
}
#endif /* DEBUG */
-/******************************************************************************
- * Extension record functions
- *****************************************************************************/
+/*******************************************************************************
+ Compute the union of two given color maps and return it. If result can't
+ fit into 256 colors, NULL is returned, the allocated union otherwise.
+ ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are
+ copied iff they didn't exist before. ColorTransIn2 maps the old
+ ColorIn2 into the ColorUnion color map table./
+*******************************************************************************/
+ColorMapObject *
+GifUnionColorMap(const ColorMapObject *ColorIn1,
+ const ColorMapObject *ColorIn2,
+ GifPixelType ColorTransIn2[])
+{
+ int i, j, CrntSlot, RoundUpTo, NewGifBitSize;
+ ColorMapObject *ColorUnion;
-void
-MakeExtension(SavedImage * New,
- int Function) {
-
- New->Function = Function;
- /*** FIXME:
- * Someday we might have to deal with multiple extensions.
- * ??? Was this a note from Gershon or from me? Does the multiple
- * extension blocks solve this or do we need multiple Functions? Or is
- * this an obsolete function? (People should use AddExtensionBlock
- * instead?)
- * Looks like AddExtensionBlock needs to take the int Function argument
- * then it can take the place of this function. Right now people have to
- * use both. Fix AddExtensionBlock and add this to the deprecation list.
+ /*
+ * We don't worry about duplicates within either color map; if
+ * the caller wants to resolve those, he can perform unions
+ * with an empty color map.
*/
+
+ /* Allocate table which will hold the result for sure. */
+ ColorUnion = GifMakeMapObject(MAX(ColorIn1->ColorCount,
+ ColorIn2->ColorCount) * 2, NULL);
+
+ if (ColorUnion == NULL)
+ return (NULL);
+
+ /*
+ * Copy ColorIn1 to ColorUnion.
+ */
+ for (i = 0; i < ColorIn1->ColorCount; i++)
+ ColorUnion->Colors[i] = ColorIn1->Colors[i];
+ CrntSlot = ColorIn1->ColorCount;
+
+ /*
+ * Potentially obnoxious hack:
+ *
+ * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end
+ * of table 1. This is very useful if your display is limited to
+ * 16 colors.
+ */
+ while (ColorIn1->Colors[CrntSlot - 1].Red == 0
+ && ColorIn1->Colors[CrntSlot - 1].Green == 0
+ && ColorIn1->Colors[CrntSlot - 1].Blue == 0)
+ CrntSlot--;
+
+ /* Copy ColorIn2 to ColorUnion (use old colors if they exist): */
+ for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) {
+ /* Let's see if this color already exists: */
+ for (j = 0; j < ColorIn1->ColorCount; j++)
+ if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i],
+ sizeof(GifColorType)) == 0)
+ break;
+
+ if (j < ColorIn1->ColorCount)
+ ColorTransIn2[i] = j; /* color exists in Color1 */
+ else {
+ /* Color is new - copy it to a new slot: */
+ ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
+ ColorTransIn2[i] = CrntSlot++;
+ }
+ }
+
+ if (CrntSlot > 256) {
+ GifFreeMapObject(ColorUnion);
+ return ((ColorMapObject *) NULL);
+ }
+
+ NewGifBitSize = GifBitSize(CrntSlot);
+ RoundUpTo = (1 << NewGifBitSize);
+
+ if (RoundUpTo != ColorUnion->ColorCount) {
+ register GifColorType *Map = ColorUnion->Colors;
+
+ /*
+ * Zero out slots up to next power of 2.
+ * We know these slots exist because of the way ColorUnion's
+ * start dimension was computed.
+ */
+ for (j = CrntSlot; j < RoundUpTo; j++)
+ Map[j].Red = Map[j].Green = Map[j].Blue = 0;
+
+ /* perhaps we can shrink the map? */
+ if (RoundUpTo < ColorUnion->ColorCount) {
+ GifColorType *new_map = (GifColorType *)realloc(Map,
+ sizeof(GifColorType) * RoundUpTo);
+ if( new_map == NULL ) {
+ GifFreeMapObject(ColorUnion);
+ return ((ColorMapObject *) NULL);
+ }
+ ColorUnion->Colors = new_map;
+ }
+ }
+
+ ColorUnion->ColorCount = RoundUpTo;
+ ColorUnion->BitsPerPixel = NewGifBitSize;
+
+ return (ColorUnion);
}
-int
-AddExtensionBlock(SavedImage * New,
- int Len,
- unsigned char ExtData[]) {
+/*******************************************************************************
+ Apply a given color translation to the raster bits of an image
+*******************************************************************************/
+void
+GifApplyTranslation(SavedImage *Image, GifPixelType Translation[])
+{
+ register int i;
+ register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width;
+ for (i = 0; i < RasterSize; i++)
+ Image->RasterBits[i] = Translation[Image->RasterBits[i]];
+}
+
+/******************************************************************************
+ Extension record functions
+******************************************************************************/
+int
+GifAddExtensionBlock(int *ExtensionBlockCount,
+ ExtensionBlock **ExtensionBlocks,
+ int Function,
+ unsigned int Len,
+ unsigned char ExtData[])
+{
ExtensionBlock *ep;
- if (New->ExtensionBlocks == NULL)
- New->ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
- else
- New->ExtensionBlocks = (ExtensionBlock *)realloc(New->ExtensionBlocks,
+ if (*ExtensionBlocks == NULL)
+ *ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
+ else {
+ ExtensionBlock* ep_new = (ExtensionBlock *)realloc(*ExtensionBlocks,
sizeof(ExtensionBlock) *
- (New->ExtensionBlockCount + 1));
+ (*ExtensionBlockCount + 1));
+ if( ep_new == NULL )
+ return (GIF_ERROR);
+ *ExtensionBlocks = ep_new;
+ }
- if (New->ExtensionBlocks == NULL)
+ if (*ExtensionBlocks == NULL)
return (GIF_ERROR);
- ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
+ ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++];
+ ep->Function = Function;
ep->ByteCount=Len;
- ep->Bytes = (char *)malloc(ep->ByteCount);
+ ep->Bytes = (GifByteType *)malloc(ep->ByteCount);
if (ep->Bytes == NULL)
return (GIF_ERROR);
- if (ExtData) {
+ if (ExtData != NULL) {
memcpy(ep->Bytes, ExtData, Len);
- ep->Function = New->Function;
}
return (GIF_OK);
}
void
-FreeExtension(SavedImage * Image)
+GifFreeExtensions(int *ExtensionBlockCount,
+ ExtensionBlock **ExtensionBlocks)
{
ExtensionBlock *ep;
- if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) {
+ if (*ExtensionBlocks == NULL)
return;
- }
- for (ep = Image->ExtensionBlocks;
- ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++)
+
+ for (ep = *ExtensionBlocks;
+ ep < (*ExtensionBlocks + *ExtensionBlockCount);
+ ep++)
(void)free((char *)ep->Bytes);
- free((char *)Image->ExtensionBlocks);
- Image->ExtensionBlocks = NULL;
+ (void)free((char *)*ExtensionBlocks);
+ *ExtensionBlocks = NULL;
+ *ExtensionBlockCount = 0;
}
/******************************************************************************
- * Image block allocation functions
+ Image block allocation functions
******************************************************************************/
/* Private Function:
* Frees the last image in the GifFile->SavedImages array
*/
void
-FreeLastSavedImage(GifFileType *GifFile) {
-
+FreeLastSavedImage(GifFileType *GifFile)
+{
SavedImage *sp;
if ((GifFile == NULL) || (GifFile->SavedImages == NULL))
@@ -225,20 +320,21 @@
sp = &GifFile->SavedImages[GifFile->ImageCount];
/* Deallocate its Colormap */
- if (sp->ImageDesc.ColorMap)
- FreeMapObject(sp->ImageDesc.ColorMap);
+ if (sp->ImageDesc.ColorMap != NULL) {
+ GifFreeMapObject(sp->ImageDesc.ColorMap);
+ sp->ImageDesc.ColorMap = NULL;
+ }
/* Deallocate the image data */
- if (sp->RasterBits)
+ if (sp->RasterBits != NULL)
free((char *)sp->RasterBits);
/* Deallocate any extensions */
- if (sp->ExtensionBlocks)
- FreeExtension(sp);
+ GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);
/*** FIXME: We could realloc the GifFile->SavedImages structure but is
* there a point to it? Saves some memory but we'd have to do it every
- * time. If this is used in FreeSavedImages then it would be inefficient
+ * time. If this is used in GifFreeSavedImages then it would be inefficient
* (The whole array is going to be deallocated.) If we just use it when
* we want to free the last Image it's convenient to do it here.
*/
@@ -248,11 +344,8 @@
* Append an image block to the SavedImages array
*/
SavedImage *
-MakeSavedImage(GifFileType * GifFile,
- const SavedImage * CopyFrom) {
-
- SavedImage *sp;
-
+GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
+{
if (GifFile->SavedImages == NULL)
GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
else
@@ -262,10 +355,10 @@
if (GifFile->SavedImages == NULL)
return ((SavedImage *)NULL);
else {
- sp = &GifFile->SavedImages[GifFile->ImageCount++];
+ SavedImage *sp = &GifFile->SavedImages[GifFile->ImageCount++];
memset((char *)sp, '\0', sizeof(SavedImage));
- if (CopyFrom) {
+ if (CopyFrom != NULL) {
memcpy((char *)sp, CopyFrom, sizeof(SavedImage));
/*
@@ -275,8 +368,8 @@
*/
/* first, the local color map */
- if (sp->ImageDesc.ColorMap) {
- sp->ImageDesc.ColorMap = MakeMapObject(
+ if (sp->ImageDesc.ColorMap != NULL) {
+ sp->ImageDesc.ColorMap = GifMakeMapObject(
CopyFrom->ImageDesc.ColorMap->ColorCount,
CopyFrom->ImageDesc.ColorMap->Colors);
if (sp->ImageDesc.ColorMap == NULL) {
@@ -298,7 +391,7 @@
CopyFrom->ImageDesc.Width);
/* finally, the extension blocks */
- if (sp->ExtensionBlocks) {
+ if (sp->ExtensionBlocks != NULL) {
sp->ExtensionBlocks = (ExtensionBlock *)malloc(
sizeof(ExtensionBlock) *
CopyFrom->ExtensionBlockCount);
@@ -308,17 +401,6 @@
}
memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks,
sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount);
-
- /*
- * For the moment, the actual blocks can take their
- * chances with free(). We'll fix this later.
- *** FIXME: [Better check this out... Toshio]
- * 2004 May 27: Looks like this was an ESR note.
- * It means the blocks are shallow copied from InFile to
- * OutFile. However, I don't see that in this code....
- * Did ESR fix it but never remove this note (And other notes
- * in gifspnge?)
- */
}
}
@@ -327,8 +409,8 @@
}
void
-FreeSavedImages(GifFileType * GifFile) {
-
+GifFreeSavedImages(GifFileType *GifFile)
+{
SavedImage *sp;
if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
@@ -336,15 +418,18 @@
}
for (sp = GifFile->SavedImages;
sp < GifFile->SavedImages + GifFile->ImageCount; sp++) {
- if (sp->ImageDesc.ColorMap)
- FreeMapObject(sp->ImageDesc.ColorMap);
+ if (sp->ImageDesc.ColorMap != NULL) {
+ GifFreeMapObject(sp->ImageDesc.ColorMap);
+ sp->ImageDesc.ColorMap = NULL;
+ }
- if (sp->RasterBits)
+ if (sp->RasterBits != NULL)
free((char *)sp->RasterBits);
- if (sp->ExtensionBlocks)
- FreeExtension(sp);
+ GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);
}
free((char *)GifFile->SavedImages);
- GifFile->SavedImages=NULL;
+ GifFile->SavedImages = NULL;
}
+
+/* end */
diff --git a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
index 5f7a036..e7330ab 100644
--- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
+++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
@@ -2778,6 +2778,14 @@
pb = &data->pixelBuf;
if (setPixelBuffer(env, pb, buffer) == NOT_OK) {
+ if (scale != NULL) {
+ for (i = 0; i < numBands; i++) {
+ if (scale[i] != NULL) {
+ free(scale[i]);
+ }
+ }
+ free(scale);
+ }
return data->abortFlag; // We already threw an out of memory exception
}
diff --git a/src/share/native/sun/awt/splashscreen/splashscreen_gif.c b/src/share/native/sun/awt/splashscreen/splashscreen_gif.c
index bdc88ae..f1954b5 100644
--- a/src/share/native/sun/awt/splashscreen/splashscreen_gif.c
+++ b/src/share/native/sun/awt/splashscreen/splashscreen_gif.c
@@ -82,8 +82,8 @@
int i, j;
int imageIndex;
int cx, cy, cw, ch; /* clamped coordinates */
- const int interlacedOffset[] = { 0, 4, 2, 1, 0 }; /* The way Interlaced image should. */
- const int interlacedJumps[] = { 8, 8, 4, 2, 1 }; /* be read - offsets and jumps... */
+ int numLines;
+ int numPassLines;
if (DGifSlurp(gif) == GIF_ERROR) {
return 0;
@@ -213,16 +213,6 @@
byte_t *pSrc = image->RasterBits;
ImageFormat srcFormat;
ImageRect srcRect, dstRect;
- int pass, npass;
-
- if (desc->Interlace) {
- pass = 0;
- npass = 4;
- }
- else {
- pass = 4;
- npass = 5;
- }
srcFormat.colorMap = colorMapBuf;
srcFormat.depthBytes = 1;
@@ -231,26 +221,22 @@
srcFormat.fixedBits = QUAD_ALPHA_MASK; // fixed 100% alpha
srcFormat.premultiplied = 0;
- for (; pass < npass; ++pass) {
- int jump = interlacedJumps[pass];
- int ofs = interlacedOffset[pass];
- /* Number of source lines for current pass */
- int numPassLines = (desc->Height + jump - ofs - 1) / jump;
- /* Number of lines that fits to dest buffer */
- int numLines = (ch + jump - ofs - 1) / jump;
+ /* Number of source lines for current pass */
+ numPassLines = desc->Height;
+ /* Number of lines that fits to dest buffer */
+ numLines = ch;
- initRect(&srcRect, 0, 0, desc->Width, numLines, 1,
- desc->Width, pSrc, &srcFormat);
+ initRect(&srcRect, 0, 0, desc->Width, numLines, 1,
+ desc->Width, pSrc, &srcFormat);
- if (numLines > 0) {
- initRect(&dstRect, cx, cy + ofs, cw,
- numLines , jump, stride, pBitmapBits, &splash->imageFormat);
+ if (numLines > 0) {
+ initRect(&dstRect, cx, cy, cw,
+ numLines , 1, stride, pBitmapBits, &splash->imageFormat);
- pSrc += convertRect(&srcRect, &dstRect, CVT_ALPHATEST);
- }
- // skip extra source data
- pSrc += (numPassLines - numLines) * srcRect.stride;
+ pSrc += convertRect(&srcRect, &dstRect, CVT_ALPHATEST);
}
+ // skip extra source data
+ pSrc += (numPassLines - numLines) * srcRect.stride;
}
// now dispose of the previous frame correctly
@@ -310,7 +296,7 @@
free(pBitmapBits);
free(pOldBitmapBits);
- DGifCloseFile(gif);
+ DGifCloseFile(gif, NULL);
return 1;
}
@@ -318,7 +304,7 @@
int
SplashDecodeGifStream(Splash * splash, SplashStream * stream)
{
- GifFileType *gif = DGifOpen((void *) stream, SplashStreamGifInputFunc);
+ GifFileType *gif = DGifOpen((void *) stream, SplashStreamGifInputFunc, NULL);
if (!gif)
return 0;
diff --git a/src/share/native/sun/font/freetypeScaler.c b/src/share/native/sun/font/freetypeScaler.c
index 55ca4eb..c1a52fe 100644
--- a/src/share/native/sun/font/freetypeScaler.c
+++ b/src/share/native/sun/font/freetypeScaler.c
@@ -147,20 +147,6 @@
#define FILEDATACACHESIZE 1024
-/* NB: is it ever called? */
-static void CloseTTFontFileFunc(FT_Stream stream) {
- FTScalerInfo *scalerInfo = (FTScalerInfo *) stream->pathname.pointer;
- JNIEnv* env = scalerInfo->env;
- jclass tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont");
- jfieldID platNameField =
- (*env)->GetFieldID(env, tmpClass, "platName", "Ljava/lang/String;");
- jstring platName = (*env)->GetObjectField(env,
- scalerInfo->font2D,
- platNameField);
- const char *name = JNU_GetStringPlatformChars(env, platName, NULL);
- JNU_ReleaseStringPlatformChars(env, platName, name);
-}
-
static unsigned long ReadTTFontFileFunc(FT_Stream stream,
unsigned long offset,
unsigned char* destBuffer,
@@ -305,7 +291,7 @@
ftstream->size = filesize;
ftstream->pos = 0;
ftstream->read = (FT_Stream_IoFunc) ReadTTFontFileFunc;
- ftstream->close = (FT_Stream_CloseFunc) CloseTTFontFileFunc;
+ ftstream->close = NULL;
ftstream->pathname.pointer = (void *) scalerInfo;
memset(&ft_open_args, 0, sizeof(FT_Open_Args));
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmscgats.c b/src/share/native/sun/java2d/cmm/lcms/cmscgats.c
index e3079d1..0dedc27 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmscgats.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmscgats.c
@@ -353,7 +353,7 @@
"XYZ_X", // X component of tristimulus data
"XYZ_Y", // Y component of tristimulus data
"XYZ_Z", // Z component of tristimulus data
- "XYY_X" // x component of chromaticity data
+ "XYY_X", // x component of chromaticity data
"XYY_Y", // y component of chromaticity data
"XYY_CAPY", // Y component of tristimulus data
"LAB_L", // L* component of Lab data
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c b/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c
index bc2b0da..f6ef06c 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c
@@ -298,6 +298,8 @@
{
cmsMAT3 Scale, m1, m2, m3, m4;
+ // TODO: Follow Marc Mahy's recommendation to check if CHAD is same by using M1*M2 == M2*M1. If so, do nothing.
+
// Adaptation state
if (AdaptationState == 1.0) {
@@ -559,7 +561,7 @@
cmsHPROFILE hProfile;
cmsMAT3 m;
cmsVEC3 off;
- cmsColorSpaceSignature ColorSpaceIn, ColorSpaceOut, CurrentColorSpace;
+ cmsColorSpaceSignature ColorSpaceIn, ColorSpaceOut = cmsSigLabData, CurrentColorSpace;
cmsProfileClassSignature ClassSig;
cmsUInt32Number i, Intent;
@@ -661,6 +663,22 @@
CurrentColorSpace = ColorSpaceOut;
}
+ // Check for non-negatives clip
+ if (dwFlags & cmsFLAGS_NONEGATIVES) {
+
+ if (ColorSpaceOut == cmsSigGrayData ||
+ ColorSpaceOut == cmsSigRgbData ||
+ ColorSpaceOut == cmsSigCmykData) {
+
+ cmsStage* clip = _cmsStageClipNegatives(Result->ContextID, cmsChannelsOf(ColorSpaceOut));
+ if (clip == NULL) goto Error;
+
+ if (!cmsPipelineInsertStage(Result, cmsAT_END, clip))
+ goto Error;
+ }
+
+ }
+
return Result;
Error:
@@ -1074,7 +1092,7 @@
if (TheIntents[i] == INTENT_PERCEPTUAL || TheIntents[i] == INTENT_SATURATION) {
// Force BPC for V4 profiles in perceptual and saturation
- if (cmsGetProfileVersion(hProfiles[i]) >= 4.0)
+ if (cmsGetEncodedICCversion(hProfiles[i]) >= 0x4000000)
BPC[i] = TRUE;
}
}
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmserr.c b/src/share/native/sun/java2d/cmm/lcms/cmserr.c
index 306d036..a708997 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmserr.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmserr.c
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2015 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -54,6 +54,13 @@
#include "lcms2_internal.h"
+
+// This function is here to help applications to prevent mixing lcms versions on header and shared objects.
+int CMSEXPORT cmsGetEncodedCMMversion(void)
+{
+ return LCMS_VERSION;
+}
+
// I am so tired about incompatibilities on those functions that here are some replacements
// that hopefully would be fully portable.
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c b/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c
index e57e6ea..b40bc1d 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c
@@ -958,7 +958,7 @@
Rest = c1 * rx + c2 * ry + c3 * rz;
- Tmp1[OutChan] = (cmsUInt16Number) c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest));
+ Tmp1[OutChan] = (cmsUInt16Number) ( c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)));
}
@@ -1022,7 +1022,7 @@
Rest = c1 * rx + c2 * ry + c3 * rz;
- Tmp2[OutChan] = (cmsUInt16Number) c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest));
+ Tmp2[OutChan] = (cmsUInt16Number) (c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)));
}
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmsio0.c b/src/share/native/sun/java2d/cmm/lcms/cmsio0.c
index d4dc1b0..cbaffb8 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmsio0.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmsio0.c
@@ -482,6 +482,14 @@
// -------------------------------------------------------------------------------------------------------
+cmsIOHANDLER* CMSEXPORT cmsGetProfileIOhandler(cmsHPROFILE hProfile)
+{
+ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile;
+
+ if (Icc == NULL) return NULL;
+ return Icc->IOhandler;
+}
+
// Creates an empty structure holding all required parameters
cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID)
{
@@ -651,25 +659,26 @@
return _cmsSearchTag(Icc, sig, FALSE) >= 0;
}
-/*
- * Enforces that the profile version is per. spec.
- * Operates on the big endian bytes from the profile.
- * Called before converting to platform endianness.
- * Byte 0 is BCD major version, so max 9.
- * Byte 1 is 2 BCD digits, one per nibble.
- * Reserved bytes 2 & 3 must be 0.
- */
-static cmsUInt32Number _validatedVersion(cmsUInt32Number DWord)
+
+
+// Enforces that the profile version is per. spec.
+// Operates on the big endian bytes from the profile.
+// Called before converting to platform endianness.
+// Byte 0 is BCD major version, so max 9.
+// Byte 1 is 2 BCD digits, one per nibble.
+// Reserved bytes 2 & 3 must be 0.
+static
+cmsUInt32Number _validatedVersion(cmsUInt32Number DWord)
{
- cmsUInt8Number* pByte = (cmsUInt8Number*)&DWord;
+ cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord;
cmsUInt8Number temp1;
cmsUInt8Number temp2;
- if (*pByte > 0x09) *pByte = (cmsUInt8Number)9;
+ if (*pByte > 0x09) *pByte = (cmsUInt8Number) 0x09;
temp1 = *(pByte+1) & 0xf0;
temp2 = *(pByte+1) & 0x0f;
if (temp1 > 0x90) temp1 = 0x90;
- if (temp2 > 9) temp2 = 0x09;
+ if (temp2 > 0x09) temp2 = 0x09;
*(pByte+1) = (cmsUInt8Number)(temp1 | temp2);
*(pByte+2) = (cmsUInt8Number)0;
*(pByte+3) = (cmsUInt8Number)0;
@@ -1167,33 +1176,7 @@
return cmsOpenProfileFromMemTHR(NULL, MemPtr, dwSize);
}
-static
-cmsBool SanityCheck(_cmsICCPROFILE* profile)
-{
- cmsIOHANDLER* io;
- if (!profile) {
- return FALSE;
- }
-
- io = profile->IOhandler;
- if (!io) {
- return FALSE;
- }
-
- if (!io->Seek ||
- !(io->Seek==NULLSeek || io->Seek==MemorySeek || io->Seek==FileSeek))
- {
- return FALSE;
- }
- if (!io->Read ||
- !(io->Read==NULLRead || io->Read==MemoryRead || io->Read==FileRead))
- {
- return FALSE;
- }
-
- return TRUE;
-}
// Dump tag contents. If the profile is being modified, untouched tags are copied from FileOrig
static
@@ -1225,7 +1208,7 @@
// Reach here if we are copying a tag from a disk-based ICC profile which has not been modified by user.
// In this case a blind copy of the block data is performed
- if (SanityCheck(FileOrig) && Icc -> TagOffsets[i]) {
+ if (FileOrig != NULL && Icc -> TagOffsets[i]) {
cmsUInt32Number TagSize = FileOrig -> TagSizes[i];
cmsUInt32Number TagOffset = FileOrig -> TagOffsets[i];
@@ -1874,7 +1857,7 @@
// Similar to the anterior. This function allows to write directly to the ICC profile any data, without
// checking anything. As a rule, mixing Raw with cooked doesn't work, so writting a tag as raw and then reading
-// it as cooked without serializing does result into an error. If that is wha you want, you will need to dump
+// it as cooked without serializing does result into an error. If that is what you want, you will need to dump
// the profile to memry or disk and then reopen it.
cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size)
{
@@ -1898,6 +1881,11 @@
Icc ->TagSizes[i] = Size;
_cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+
+ if (Icc->TagPtrs[i] == NULL) {
+ Icc->TagNames[i] = 0;
+ return FALSE;
+ }
return TRUE;
}
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmsio1.c b/src/share/native/sun/java2d/cmm/lcms/cmsio1.c
index 61c2ca5..4c259f8 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmsio1.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmsio1.c
@@ -339,8 +339,8 @@
cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
{
cmsTagTypeSignature OriginalType;
- cmsTagSignature tag16 = Device2PCS16[Intent];
- cmsTagSignature tagFloat = Device2PCSFloat[Intent];
+ cmsTagSignature tag16;
+ cmsTagSignature tagFloat;
cmsContext ContextID = cmsGetProfileContextID(hProfile);
// On named color, take the appropiate tag
@@ -369,6 +369,9 @@
// matter other LUT are present and have precedence. Intent = -1 means just this.
if (Intent != -1) {
+ tag16 = Device2PCS16[Intent];
+ tagFloat = Device2PCSFloat[Intent];
+
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
// Floating point LUT are always V4, but the encoding range is no
@@ -611,13 +614,16 @@
cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
{
cmsTagTypeSignature OriginalType;
- cmsTagSignature tag16 = PCS2Device16[Intent];
- cmsTagSignature tagFloat = PCS2DeviceFloat[Intent];
- cmsContext ContextID = cmsGetProfileContextID(hProfile);
+ cmsTagSignature tag16;
+ cmsTagSignature tagFloat;
+ cmsContext ContextID = cmsGetProfileContextID(hProfile);
if (Intent != -1) {
+ tag16 = PCS2Device16[Intent];
+ tagFloat = PCS2DeviceFloat[Intent];
+
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
// Floating point LUT are always V4
@@ -935,7 +941,7 @@
{
if (!cmsWriteTag(hProfile, cmsSigProfileSequenceDescTag, seq)) return FALSE;
- if (cmsGetProfileVersion(hProfile) >= 4.0) {
+ if (cmsGetEncodedICCversion(hProfile) >= 0x4000000) {
if (!cmsWriteTag(hProfile, cmsSigProfileSequenceIdTag, seq)) return FALSE;
}
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmslut.c b/src/share/native/sun/java2d/cmm/lcms/cmslut.c
index 8aded52..4c04ee9 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmslut.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmslut.c
@@ -1154,7 +1154,23 @@
return mpe;
}
+// Clips values smaller than zero
+static
+void Clipper(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe)
+{
+ cmsUInt32Number i;
+ for (i = 0; i < mpe->InputChannels; i++) {
+ cmsFloat32Number n = In[i];
+ Out[i] = n < 0 ? 0 : n;
+ }
+}
+
+cmsStage* _cmsStageClipNegatives(cmsContext ContextID, int nChannels)
+{
+ return _cmsStageAllocPlaceholder(ContextID, cmsSigClipNegativesElemType,
+ nChannels, nChannels, Clipper, NULL, NULL, NULL);
+}
// ********************************************************************************
// Type cmsSigXYZ2LabElemType
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c b/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c
index 4da4153..fd4e565 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c
@@ -543,8 +543,9 @@
v ->nColors = 0;
v ->ContextID = ContextID;
- while (v -> Allocated < n)
- GrowNamedColorList(v);
+ while (v -> Allocated < n){
+ if (!GrowNamedColorList(v)) return NULL;
+ }
strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix)-1);
strncpy(v ->Suffix, Suffix, sizeof(v ->Suffix)-1);
@@ -573,8 +574,9 @@
if (NewNC == NULL) return NULL;
// For really large tables we need this
- while (NewNC ->Allocated < v ->Allocated)
- GrowNamedColorList(NewNC);
+ while (NewNC ->Allocated < v ->Allocated){
+ if (!GrowNamedColorList(NewNC)) return NULL;
+ }
memmove(NewNC ->Prefix, v ->Prefix, sizeof(v ->Prefix));
memmove(NewNC ->Suffix, v ->Suffix, sizeof(v ->Suffix));
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmsopt.c b/src/share/native/sun/java2d/cmm/lcms/cmsopt.c
index b9d6951..c3267ec 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmsopt.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmsopt.c
@@ -192,6 +192,88 @@
return AnyOpt;
}
+
+static
+cmsBool CloseEnoughFloat(cmsFloat64Number a, cmsFloat64Number b)
+{
+ return fabs(b - a) < 0.00001f;
+}
+
+static
+cmsBool isFloatMatrixIdentity(const cmsMAT3* a)
+{
+ cmsMAT3 Identity;
+ int i, j;
+
+ _cmsMAT3identity(&Identity);
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ if (!CloseEnoughFloat(a->v[i].n[j], Identity.v[i].n[j])) return FALSE;
+
+ return TRUE;
+}
+// if two adjacent matrices are found, multiply them.
+static
+cmsBool _MultiplyMatrix(cmsPipeline* Lut)
+{
+ cmsStage** pt1;
+ cmsStage** pt2;
+ cmsStage* chain;
+ cmsBool AnyOpt = FALSE;
+
+ pt1 = &Lut->Elements;
+ if (*pt1 == NULL) return AnyOpt;
+
+ while (*pt1 != NULL) {
+
+ pt2 = &((*pt1)->Next);
+ if (*pt2 == NULL) return AnyOpt;
+
+ if ((*pt1)->Implements == cmsSigMatrixElemType && (*pt2)->Implements == cmsSigMatrixElemType) {
+
+ // Get both matrices
+ _cmsStageMatrixData* m1 = (_cmsStageMatrixData*) cmsStageData(*pt1);
+ _cmsStageMatrixData* m2 = (_cmsStageMatrixData*) cmsStageData(*pt2);
+ cmsMAT3 res;
+
+ // Input offset and output offset should be zero to use this optimization
+ if (m1->Offset != NULL || m2 ->Offset != NULL ||
+ cmsStageInputChannels(*pt1) != 3 || cmsStageOutputChannels(*pt1) != 3 ||
+ cmsStageInputChannels(*pt2) != 3 || cmsStageOutputChannels(*pt2) != 3)
+ return FALSE;
+
+ // Multiply both matrices to get the result
+ _cmsMAT3per(&res, (cmsMAT3*)m2->Double, (cmsMAT3*)m1->Double);
+
+ // Get the next in chain afer the matrices
+ chain = (*pt2)->Next;
+
+ // Remove both matrices
+ _RemoveElement(pt2);
+ _RemoveElement(pt1);
+
+ // Now what if the result is a plain identity?
+ if (!isFloatMatrixIdentity(&res)) {
+
+ // We can not get rid of full matrix
+ cmsStage* Multmat = cmsStageAllocMatrix(Lut->ContextID, 3, 3, (const cmsFloat64Number*) &res, NULL);
+
+ // Recover the chain
+ Multmat->Next = chain;
+ *pt1 = Multmat;
+ }
+
+ AnyOpt = TRUE;
+ }
+ else
+ pt1 = &((*pt1)->Next);
+ }
+
+ return AnyOpt;
+}
+
+
// Preoptimize just gets rif of no-ops coming paired. Conversion from v2 to v4 followed
// by a v4 to v2 and vice-versa. The elements are then discarded.
static
@@ -224,6 +306,9 @@
// Remove float pcs Lab conversions
Opt |= _Remove2Op(Lut, cmsSigXYZ2FloatPCS, cmsSigFloatPCS2XYZ);
+ // Simplify matrix.
+ Opt |= _MultiplyMatrix(Lut);
+
if (Opt) AnyOpt = TRUE;
} while (Opt);
@@ -280,12 +365,12 @@
void* Prelin16dup(cmsContext ContextID, const void* ptr)
{
Prelin16Data* p16 = (Prelin16Data*) ptr;
- Prelin16Data* Duped = _cmsDupMem(ContextID, p16, sizeof(Prelin16Data));
+ Prelin16Data* Duped = (Prelin16Data*) _cmsDupMem(ContextID, p16, sizeof(Prelin16Data));
if (Duped == NULL) return NULL;
- Duped ->EvalCurveOut16 = _cmsDupMem(ContextID, p16 ->EvalCurveOut16, p16 ->nOutputs * sizeof(_cmsInterpFn16));
- Duped ->ParamsCurveOut16 = _cmsDupMem(ContextID, p16 ->ParamsCurveOut16, p16 ->nOutputs * sizeof(cmsInterpParams* ));
+ Duped->EvalCurveOut16 = (_cmsInterpFn16*) _cmsDupMem(ContextID, p16->EvalCurveOut16, p16->nOutputs * sizeof(_cmsInterpFn16));
+ Duped->ParamsCurveOut16 = (cmsInterpParams**)_cmsDupMem(ContextID, p16->ParamsCurveOut16, p16->nOutputs * sizeof(cmsInterpParams*));
return Duped;
}
@@ -298,7 +383,7 @@
int nOutputs, cmsToneCurve** Out )
{
int i;
- Prelin16Data* p16 = _cmsMallocZero(ContextID, sizeof(Prelin16Data));
+ Prelin16Data* p16 = (Prelin16Data*)_cmsMallocZero(ContextID, sizeof(Prelin16Data));
if (p16 == NULL) return NULL;
p16 ->nInputs = nInputs;
@@ -787,7 +872,7 @@
cmsS15Fixed16Number v1, v2, v3;
Prelin8Data* p8;
- p8 = _cmsMallocZero(ContextID, sizeof(Prelin8Data));
+ p8 = (Prelin8Data*)_cmsMallocZero(ContextID, sizeof(Prelin8Data));
if (p8 == NULL) return NULL;
// Since this only works for 8 bit input, values comes always as x * 257,
@@ -861,7 +946,7 @@
Prelin8Data* p8 = (Prelin8Data*) D;
register const cmsInterpParams* p = p8 ->p;
int TotalOut = p -> nOutputs;
- const cmsUInt16Number* LutTable = p -> Table;
+ const cmsUInt16Number* LutTable = (const cmsUInt16Number*) p->Table;
r = Input[0] >> 8;
g = Input[1] >> 8;
@@ -1180,15 +1265,15 @@
static
void* CurvesDup(cmsContext ContextID, const void* ptr)
{
- Curves16Data* Data = _cmsDupMem(ContextID, ptr, sizeof(Curves16Data));
+ Curves16Data* Data = (Curves16Data*)_cmsDupMem(ContextID, ptr, sizeof(Curves16Data));
int i;
if (Data == NULL) return NULL;
- Data ->Curves = _cmsDupMem(ContextID, Data ->Curves, Data ->nCurves * sizeof(cmsUInt16Number*));
+ Data->Curves = (cmsUInt16Number**) _cmsDupMem(ContextID, Data->Curves, Data->nCurves * sizeof(cmsUInt16Number*));
for (i=0; i < Data -> nCurves; i++) {
- Data ->Curves[i] = _cmsDupMem(ContextID, Data ->Curves[i], Data -> nElements * sizeof(cmsUInt16Number));
+ Data->Curves[i] = (cmsUInt16Number*) _cmsDupMem(ContextID, Data->Curves[i], Data->nElements * sizeof(cmsUInt16Number));
}
return (void*) Data;
@@ -1201,18 +1286,18 @@
int i, j;
Curves16Data* c16;
- c16 = _cmsMallocZero(ContextID, sizeof(Curves16Data));
+ c16 = (Curves16Data*)_cmsMallocZero(ContextID, sizeof(Curves16Data));
if (c16 == NULL) return NULL;
c16 ->nCurves = nCurves;
c16 ->nElements = nElements;
- c16 ->Curves = _cmsCalloc(ContextID, nCurves, sizeof(cmsUInt16Number*));
+ c16->Curves = (cmsUInt16Number**) _cmsCalloc(ContextID, nCurves, sizeof(cmsUInt16Number*));
if (c16 ->Curves == NULL) return NULL;
for (i=0; i < nCurves; i++) {
- c16->Curves[i] = _cmsCalloc(ContextID, nElements, sizeof(cmsUInt16Number));
+ c16->Curves[i] = (cmsUInt16Number*) _cmsCalloc(ContextID, nElements, sizeof(cmsUInt16Number));
if (c16->Curves[i] == NULL) {
@@ -1560,49 +1645,83 @@
}
// 8 bits on input allows matrix-shaper boot up to 25 Mpixels per second on RGB. That's fast!
-// TODO: Allow a third matrix for abs. colorimetric
static
cmsBool OptimizeMatrixShaper(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags)
{
- cmsStage* Curve1, *Curve2;
- cmsStage* Matrix1, *Matrix2;
- _cmsStageMatrixData* Data1;
- _cmsStageMatrixData* Data2;
- cmsMAT3 res;
- cmsBool IdentityMat;
- cmsPipeline* Dest, *Src;
+ cmsStage* Curve1, *Curve2;
+ cmsStage* Matrix1, *Matrix2;
+ cmsMAT3 res;
+ cmsBool IdentityMat;
+ cmsPipeline* Dest, *Src;
+ cmsFloat64Number* Offset;
- // Only works on RGB to RGB
- if (T_CHANNELS(*InputFormat) != 3 || T_CHANNELS(*OutputFormat) != 3) return FALSE;
+ // Only works on RGB to RGB
+ if (T_CHANNELS(*InputFormat) != 3 || T_CHANNELS(*OutputFormat) != 3) return FALSE;
- // Only works on 8 bit input
- if (!_cmsFormatterIs8bit(*InputFormat)) return FALSE;
+ // Only works on 8 bit input
+ if (!_cmsFormatterIs8bit(*InputFormat)) return FALSE;
- // Seems suitable, proceed
- Src = *Lut;
+ // Seems suitable, proceed
+ Src = *Lut;
- // Check for shaper-matrix-matrix-shaper structure, that is what this optimizer stands for
- if (!cmsPipelineCheckAndRetreiveStages(Src, 4,
- cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType,
- &Curve1, &Matrix1, &Matrix2, &Curve2)) return FALSE;
+ // Check for:
+ //
+ // shaper-matrix-matrix-shaper
+ // shaper-matrix-shaper
+ //
+ // Both of those constructs are possible (first because abs. colorimetric).
+ // additionally, In the first case, the input matrix offset should be zero.
- // Get both matrices
- Data1 = (_cmsStageMatrixData*) cmsStageData(Matrix1);
- Data2 = (_cmsStageMatrixData*) cmsStageData(Matrix2);
+ IdentityMat = FALSE;
+ if (cmsPipelineCheckAndRetreiveStages(Src, 4,
+ cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType,
+ &Curve1, &Matrix1, &Matrix2, &Curve2)) {
- // Input offset should be zero
- if (Data1 ->Offset != NULL) return FALSE;
+ // Get both matrices
+ _cmsStageMatrixData* Data1 = (_cmsStageMatrixData*)cmsStageData(Matrix1);
+ _cmsStageMatrixData* Data2 = (_cmsStageMatrixData*)cmsStageData(Matrix2);
- // Multiply both matrices to get the result
- _cmsMAT3per(&res, (cmsMAT3*) Data2 ->Double, (cmsMAT3*) Data1 ->Double);
+ // Input offset should be zero
+ if (Data1->Offset != NULL) return FALSE;
- // Now the result is in res + Data2 -> Offset. Maybe is a plain identity?
- IdentityMat = FALSE;
- if (_cmsMAT3isIdentity(&res) && Data2 ->Offset == NULL) {
+ // Multiply both matrices to get the result
+ _cmsMAT3per(&res, (cmsMAT3*)Data2->Double, (cmsMAT3*)Data1->Double);
- // We can get rid of full matrix
- IdentityMat = TRUE;
- }
+ // Only 2nd matrix has offset, or it is zero
+ Offset = Data2->Offset;
+
+ // Now the result is in res + Data2 -> Offset. Maybe is a plain identity?
+ if (_cmsMAT3isIdentity(&res) && Offset == NULL) {
+
+ // We can get rid of full matrix
+ IdentityMat = TRUE;
+ }
+
+ }
+ else {
+
+ if (cmsPipelineCheckAndRetreiveStages(Src, 3,
+ cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType,
+ &Curve1, &Matrix1, &Curve2)) {
+
+ _cmsStageMatrixData* Data = (_cmsStageMatrixData*)cmsStageData(Matrix1);
+
+ // Copy the matrix to our result
+ memcpy(&res, Data->Double, sizeof(res));
+
+ // Preserve the Odffset (may be NULL as a zero offset)
+ Offset = Data->Offset;
+
+ if (_cmsMAT3isIdentity(&res) && Offset == NULL) {
+
+ // We can get rid of full matrix
+ IdentityMat = TRUE;
+ }
+ }
+ else
+ return FALSE; // Not optimizeable this time
+
+ }
// Allocate an empty LUT
Dest = cmsPipelineAlloc(Src ->ContextID, Src ->InputChannels, Src ->OutputChannels);
@@ -1612,9 +1731,12 @@
if (!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, cmsStageDup(Curve1)))
goto Error;
- if (!IdentityMat)
- if (!cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageAllocMatrix(Dest ->ContextID, 3, 3, (const cmsFloat64Number*) &res, Data2 ->Offset)))
- goto Error;
+ if (!IdentityMat) {
+
+ if (!cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageAllocMatrix(Dest->ContextID, 3, 3, (const cmsFloat64Number*)&res, Offset)))
+ goto Error;
+ }
+
if (!cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageDup(Curve2)))
goto Error;
@@ -1632,7 +1754,7 @@
*dwFlags |= cmsFLAGS_NOCACHE;
// Setup the optimizarion routines
- SetMatShaper(Dest, mpeC1 ->TheCurves, &res, (cmsVEC3*) Data2 ->Offset, mpeC2->TheCurves, OutputFormat);
+ SetMatShaper(Dest, mpeC1 ->TheCurves, &res, (cmsVEC3*) Offset, mpeC2->TheCurves, OutputFormat);
}
cmsPipelineFree(Src);
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmspack.c b/src/share/native/sun/java2d/cmm/lcms/cmspack.c
index 6659774..e389c4e 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmspack.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmspack.c
@@ -2438,9 +2438,6 @@
((cmsFloat64Number*) output)[i + start] = v;
}
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsFloat64Number);
- }
if (Extra == 0 && SwapFirst) {
@@ -2451,7 +2448,7 @@
if (T_PLANAR(info -> OutputFormat))
return output + sizeof(cmsFloat64Number);
else
- return output + nChan * sizeof(cmsFloat64Number);
+ return output + (nChan + Extra) * sizeof(cmsFloat64Number);
}
@@ -2462,50 +2459,47 @@
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse = T_FLAVOR(info ->OutputFormat);
- int Extra = T_EXTRA(info -> OutputFormat);
- int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int Planar = T_PLANAR(info -> OutputFormat);
- int ExtraFirst = DoSwap ^ SwapFirst;
- cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
- cmsFloat64Number v = 0;
- cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
- int i, start = 0;
+ int nChan = T_CHANNELS(info->OutputFormat);
+ int DoSwap = T_DOSWAP(info->OutputFormat);
+ int Reverse = T_FLAVOR(info->OutputFormat);
+ int Extra = T_EXTRA(info->OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info->OutputFormat);
+ int Planar = T_PLANAR(info->OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 655.35 : 65535.0;
+ cmsFloat64Number v = 0;
+ cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
+ int i, start = 0;
- if (ExtraFirst)
- start = Extra;
+ if (ExtraFirst)
+ start = Extra;
- for (i=0; i < nChan; i++) {
+ for (i = 0; i < nChan; i++) {
- int index = DoSwap ? (nChan - i - 1) : i;
+ int index = DoSwap ? (nChan - i - 1) : i;
- v = (cmsFloat64Number) wOut[index] / maximum;
+ v = (cmsFloat64Number)wOut[index] / maximum;
- if (Reverse)
- v = maximum - v;
+ if (Reverse)
+ v = maximum - v;
- if (Planar)
- ((cmsFloat32Number*) output)[(i + start ) * Stride]= (cmsFloat32Number) v;
- else
- ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
- }
+ if (Planar)
+ ((cmsFloat32Number*)output)[(i + start) * Stride] = (cmsFloat32Number)v;
+ else
+ ((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v;
+ }
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsFloat32Number);
- }
- if (Extra == 0 && SwapFirst) {
+ if (Extra == 0 && SwapFirst) {
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
- *swap1 = (cmsFloat32Number) v;
- }
+ memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number));
+ *swap1 = (cmsFloat32Number)v;
+ }
- if (T_PLANAR(info -> OutputFormat))
- return output + sizeof(cmsFloat32Number);
- else
- return output + nChan * sizeof(cmsFloat32Number);
+ if (T_PLANAR(info->OutputFormat))
+ return output + sizeof(cmsFloat32Number);
+ else
+ return output + (nChan + Extra) * sizeof(cmsFloat32Number);
}
@@ -2518,50 +2512,47 @@
cmsUInt8Number* output,
cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse = T_FLAVOR(info ->OutputFormat);
- int Extra = T_EXTRA(info -> OutputFormat);
- int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int Planar = T_PLANAR(info -> OutputFormat);
- int ExtraFirst = DoSwap ^ SwapFirst;
- cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
- cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
- cmsFloat64Number v = 0;
- int i, start = 0;
+ int nChan = T_CHANNELS(info->OutputFormat);
+ int DoSwap = T_DOSWAP(info->OutputFormat);
+ int Reverse = T_FLAVOR(info->OutputFormat);
+ int Extra = T_EXTRA(info->OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info->OutputFormat);
+ int Planar = T_PLANAR(info->OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0;
+ cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
+ cmsFloat64Number v = 0;
+ int i, start = 0;
- if (ExtraFirst)
- start = Extra;
+ if (ExtraFirst)
+ start = Extra;
- for (i=0; i < nChan; i++) {
+ for (i = 0; i < nChan; i++) {
- int index = DoSwap ? (nChan - i - 1) : i;
+ int index = DoSwap ? (nChan - i - 1) : i;
- v = wOut[index] * maximum;
+ v = wOut[index] * maximum;
- if (Reverse)
- v = maximum - v;
+ if (Reverse)
+ v = maximum - v;
- if (Planar)
- ((cmsFloat32Number*) output)[(i + start)* Stride]= (cmsFloat32Number) v;
- else
- ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
- }
+ if (Planar)
+ ((cmsFloat32Number*)output)[(i + start)* Stride] = (cmsFloat32Number)v;
+ else
+ ((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v;
+ }
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsFloat32Number);
- }
- if (Extra == 0 && SwapFirst) {
+ if (Extra == 0 && SwapFirst) {
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
- *swap1 = (cmsFloat32Number) v;
- }
+ memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number));
+ *swap1 = (cmsFloat32Number)v;
+ }
- if (T_PLANAR(info -> OutputFormat))
- return output + sizeof(cmsFloat32Number);
- else
- return output + nChan * sizeof(cmsFloat32Number);
+ if (T_PLANAR(info->OutputFormat))
+ return output + sizeof(cmsFloat32Number);
+ else
+ return output + (nChan + Extra) * sizeof(cmsFloat32Number);
}
static
@@ -2570,51 +2561,47 @@
cmsUInt8Number* output,
cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse = T_FLAVOR(info ->OutputFormat);
- int Extra = T_EXTRA(info -> OutputFormat);
- int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int Planar = T_PLANAR(info -> OutputFormat);
- int ExtraFirst = DoSwap ^ SwapFirst;
- cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
- cmsFloat64Number v = 0;
- cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
- int i, start = 0;
+ int nChan = T_CHANNELS(info->OutputFormat);
+ int DoSwap = T_DOSWAP(info->OutputFormat);
+ int Reverse = T_FLAVOR(info->OutputFormat);
+ int Extra = T_EXTRA(info->OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info->OutputFormat);
+ int Planar = T_PLANAR(info->OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0;
+ cmsFloat64Number v = 0;
+ cmsFloat64Number* swap1 = (cmsFloat64Number*)output;
+ int i, start = 0;
- if (ExtraFirst)
- start = Extra;
+ if (ExtraFirst)
+ start = Extra;
- for (i=0; i < nChan; i++) {
+ for (i = 0; i < nChan; i++) {
- int index = DoSwap ? (nChan - i - 1) : i;
+ int index = DoSwap ? (nChan - i - 1) : i;
- v = wOut[index] * maximum;
+ v = wOut[index] * maximum;
- if (Reverse)
- v = maximum - v;
+ if (Reverse)
+ v = maximum - v;
- if (Planar)
- ((cmsFloat64Number*) output)[(i + start) * Stride] = v;
- else
- ((cmsFloat64Number*) output)[i + start] = v;
- }
+ if (Planar)
+ ((cmsFloat64Number*)output)[(i + start) * Stride] = v;
+ else
+ ((cmsFloat64Number*)output)[i + start] = v;
+ }
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsFloat64Number);
- }
+ if (Extra == 0 && SwapFirst) {
- if (Extra == 0 && SwapFirst) {
-
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
- *swap1 = v;
- }
+ memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat64Number));
+ *swap1 = v;
+ }
- if (T_PLANAR(info -> OutputFormat))
- return output + sizeof(cmsFloat64Number);
- else
- return output + nChan * sizeof(cmsFloat64Number);
+ if (T_PLANAR(info->OutputFormat))
+ return output + sizeof(cmsFloat64Number);
+ else
+ return output + (nChan + Extra) * sizeof(cmsFloat64Number);
}
@@ -2850,50 +2837,47 @@
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse = T_FLAVOR(info ->OutputFormat);
- int Extra = T_EXTRA(info -> OutputFormat);
- int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int Planar = T_PLANAR(info -> OutputFormat);
- int ExtraFirst = DoSwap ^ SwapFirst;
- cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35F : 65535.0F;
- cmsFloat32Number v = 0;
- cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
- int i, start = 0;
+ int nChan = T_CHANNELS(info->OutputFormat);
+ int DoSwap = T_DOSWAP(info->OutputFormat);
+ int Reverse = T_FLAVOR(info->OutputFormat);
+ int Extra = T_EXTRA(info->OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info->OutputFormat);
+ int Planar = T_PLANAR(info->OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 655.35F : 65535.0F;
+ cmsFloat32Number v = 0;
+ cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
+ int i, start = 0;
- if (ExtraFirst)
- start = Extra;
+ if (ExtraFirst)
+ start = Extra;
- for (i=0; i < nChan; i++) {
+ for (i = 0; i < nChan; i++) {
- int index = DoSwap ? (nChan - i - 1) : i;
+ int index = DoSwap ? (nChan - i - 1) : i;
- v = (cmsFloat32Number) wOut[index] / maximum;
+ v = (cmsFloat32Number)wOut[index] / maximum;
- if (Reverse)
- v = maximum - v;
+ if (Reverse)
+ v = maximum - v;
- if (Planar)
- ((cmsUInt16Number*) output)[(i + start ) * Stride]= _cmsFloat2Half(v);
- else
- ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half(v);
- }
+ if (Planar)
+ ((cmsUInt16Number*)output)[(i + start) * Stride] = _cmsFloat2Half(v);
+ else
+ ((cmsUInt16Number*)output)[i + start] = _cmsFloat2Half(v);
+ }
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsUInt16Number);
- }
- if (Extra == 0 && SwapFirst) {
+ if (Extra == 0 && SwapFirst) {
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
- *swap1 = _cmsFloat2Half(v);
- }
+ memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsUInt16Number));
+ *swap1 = _cmsFloat2Half(v);
+ }
- if (T_PLANAR(info -> OutputFormat))
- return output + sizeof(cmsUInt16Number);
- else
- return output + nChan * sizeof(cmsUInt16Number);
+ if (T_PLANAR(info->OutputFormat))
+ return output + sizeof(cmsUInt16Number);
+ else
+ return output + (nChan + Extra) * sizeof(cmsUInt16Number);
}
@@ -2904,50 +2888,47 @@
cmsUInt8Number* output,
cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse = T_FLAVOR(info ->OutputFormat);
- int Extra = T_EXTRA(info -> OutputFormat);
- int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int Planar = T_PLANAR(info -> OutputFormat);
- int ExtraFirst = DoSwap ^ SwapFirst;
- cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0F : 1.0F;
- cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
- cmsFloat32Number v = 0;
- int i, start = 0;
+ int nChan = T_CHANNELS(info->OutputFormat);
+ int DoSwap = T_DOSWAP(info->OutputFormat);
+ int Reverse = T_FLAVOR(info->OutputFormat);
+ int Extra = T_EXTRA(info->OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info->OutputFormat);
+ int Planar = T_PLANAR(info->OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 100.0F : 1.0F;
+ cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
+ cmsFloat32Number v = 0;
+ int i, start = 0;
- if (ExtraFirst)
- start = Extra;
+ if (ExtraFirst)
+ start = Extra;
- for (i=0; i < nChan; i++) {
+ for (i = 0; i < nChan; i++) {
- int index = DoSwap ? (nChan - i - 1) : i;
+ int index = DoSwap ? (nChan - i - 1) : i;
- v = wOut[index] * maximum;
+ v = wOut[index] * maximum;
- if (Reverse)
- v = maximum - v;
+ if (Reverse)
+ v = maximum - v;
- if (Planar)
- ((cmsUInt16Number*) output)[(i + start)* Stride]= _cmsFloat2Half( v );
- else
- ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half( v );
- }
+ if (Planar)
+ ((cmsUInt16Number*)output)[(i + start)* Stride] = _cmsFloat2Half(v);
+ else
+ ((cmsUInt16Number*)output)[i + start] = _cmsFloat2Half(v);
+ }
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsUInt16Number);
- }
- if (Extra == 0 && SwapFirst) {
+ if (Extra == 0 && SwapFirst) {
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
- *swap1 = (cmsUInt16Number) _cmsFloat2Half( v );
- }
+ memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsUInt16Number));
+ *swap1 = (cmsUInt16Number)_cmsFloat2Half(v);
+ }
- if (T_PLANAR(info -> OutputFormat))
- return output + sizeof(cmsUInt16Number);
- else
- return output + nChan * sizeof(cmsUInt16Number);
+ if (T_PLANAR(info->OutputFormat))
+ return output + sizeof(cmsUInt16Number);
+ else
+ return output + (nChan + Extra)* sizeof(cmsUInt16Number);
}
#endif
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmspcs.c b/src/share/native/sun/java2d/cmm/lcms/cmspcs.c
index 7d39aaa..d4ef694 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmspcs.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmspcs.c
@@ -135,6 +135,15 @@
Dest -> Z = ((1 - Source -> x - Source -> y) / Source -> y) * Source -> Y;
}
+/*
+ The break point (24/116)^3 = (6/29)^3 is a very small amount of tristimulus
+ primary (0.008856). Generally, this only happens for
+ nearly ideal blacks and for some orange / amber colors in transmission mode.
+ For example, the Z value of the orange turn indicator lamp lens on an
+ automobile will often be below this value. But the Z does not
+ contribute to the perceived color directly.
+*/
+
static
cmsFloat64Number f(cmsFloat64Number t)
{
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c b/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c
index ef75e13..4443820 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c
@@ -712,15 +712,21 @@
// Internal: get the memory area associanted with each context client
-// Returns the block assigned to the specific zone.
+// Returns the block assigned to the specific zone. Never return NULL.
void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc)
{
struct _cmsContext_struct* ctx;
void *ptr;
- if (mc < 0 || mc >= MemoryClientMax) {
- cmsSignalError(ContextID, cmsERROR_RANGE, "Bad context client");
- return NULL;
+ if ((int) mc < 0 || mc >= MemoryClientMax) {
+
+ cmsSignalError(ContextID, cmsERROR_INTERNAL, "Bad context client -- possible corruption");
+
+ // This is catastrophic. Should never reach here
+ _cmsAssert(0);
+
+ // Reverts to global context
+ return globalContext.chunks[UserPtr];
}
ctx = _cmsGetContext(ContextID);
@@ -909,7 +915,7 @@
}
-
+/*
static
struct _cmsContext_struct* FindPrev(struct _cmsContext_struct* id)
{
@@ -926,6 +932,7 @@
return NULL; // List is empty or only one element!
}
+*/
// Frees any resources associated with the given context,
// and destroys the context placeholder.
@@ -961,8 +968,8 @@
// Search for previous
for (prev = _cmsContextPoolHead;
- prev != NULL;
- prev = prev ->Next)
+ prev != NULL;
+ prev = prev ->Next)
{
if (prev -> Next == ctx) {
prev -> Next = ctx ->Next;
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmssamp.c b/src/share/native/sun/java2d/cmm/lcms/cmssamp.c
index 42a5bbf..bcd9d50 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmssamp.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmssamp.c
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2014 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -369,28 +369,7 @@
}
-/*
-static
-cmsBool IsMonotonic(int n, const cmsFloat64Number Table[])
-{
- int i;
- cmsFloat64Number last;
- last = Table[n-1];
-
- for (i = n-2; i >= 0; --i) {
-
- if (Table[i] > last)
-
- return FALSE;
- else
- last = Table[i];
-
- }
-
- return TRUE;
-}
-*/
// Calculates the black point of a destination profile.
// This algorithm comes from the Adobe paper disclosing its black point compensation method.
@@ -515,7 +494,6 @@
// Test for mid range straight (only on relative colorimetric)
-
NearlyStraightMidrange = TRUE;
MinL = outRamp[0]; MaxL = outRamp[255];
if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
@@ -531,7 +509,6 @@
// DestinationBlackPoint shall be the same as initialLab.
// Otherwise, the DestinationBlackPoint shall be determined
// using curve fitting.
-
if (NearlyStraightMidrange) {
cmsLab2XYZ(NULL, BlackPoint, &InitialLab);
@@ -543,14 +520,12 @@
// curve fitting: The round-trip curve normally looks like a nearly constant section at the black point,
// with a corner and a nearly straight line to the white point.
-
for (l=0; l < 256; l++) {
yRamp[l] = (outRamp[l] - MinL) / (MaxL - MinL);
}
// find the black point using the least squares error quadratic curve fitting
-
if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
lo = 0.1;
hi = 0.5;
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmstypes.c b/src/share/native/sun/java2d/cmm/lcms/cmstypes.c
index 08cad5e..684a205 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmstypes.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmstypes.c
@@ -1718,10 +1718,7 @@
else
for (j=0; j < 256; j++) {
- if (Tables != NULL)
- val = (cmsUInt8Number) FROM_16_TO_8(Tables->TheCurves[i]->Table16[j]);
- else
- val = (cmsUInt8Number) j;
+ val = (cmsUInt8Number) FROM_16_TO_8(Tables->TheCurves[i]->Table16[j]);
if (!_cmsWriteUInt8Number(io, val)) return FALSE;
}
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c b/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c
index 3598751..6c84f13 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c
@@ -671,7 +671,7 @@
// Create the ICC virtual profile for sRGB space
cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID)
{
- cmsCIExyY D65;
+ cmsCIExyY D65 = { 0.3127, 0.3290, 1.0 };
cmsCIExyYTRIPLE Rec709Primaries = {
{0.6400, 0.3300, 1.0},
{0.3000, 0.6000, 1.0},
@@ -680,7 +680,7 @@
cmsToneCurve* Gamma22[3];
cmsHPROFILE hsRGB;
- cmsWhitePointFromTemp(&D65, 6504);
+ // cmsWhitePointFromTemp(&D65, 6504);
Gamma22[0] = Gamma22[1] = Gamma22[2] = Build_sRGBGamma(ContextID);
if (Gamma22[0] == NULL) return NULL;
@@ -708,6 +708,7 @@
cmsFloat64Number Contrast;
cmsFloat64Number Hue;
cmsFloat64Number Saturation;
+ cmsBool lAdjustWP;
cmsCIEXYZ WPsrc, WPdest;
} BCHSWADJUSTS, *LPBCHSWADJUSTS;
@@ -737,9 +738,10 @@
cmsLCh2Lab(&LabOut, &LChOut);
// Move white point in Lab
-
- cmsLab2XYZ(&bchsw ->WPsrc, &XYZ, &LabOut);
- cmsXYZ2Lab(&bchsw ->WPdest, &LabOut, &XYZ);
+ if (bchsw->lAdjustWP) {
+ cmsLab2XYZ(&bchsw->WPsrc, &XYZ, &LabOut);
+ cmsXYZ2Lab(&bchsw->WPdest, &LabOut, &XYZ);
+ }
// Back to encoded
@@ -773,18 +775,23 @@
bchsw.Contrast = Contrast;
bchsw.Hue = Hue;
bchsw.Saturation = Saturation;
+ if (TempSrc == TempDest) {
- cmsWhitePointFromTemp(&WhitePnt, TempSrc );
- cmsxyY2XYZ(&bchsw.WPsrc, &WhitePnt);
+ bchsw.lAdjustWP = FALSE;
+ }
+ else {
+ bchsw.lAdjustWP = TRUE;
+ cmsWhitePointFromTemp(&WhitePnt, TempSrc);
+ cmsxyY2XYZ(&bchsw.WPsrc, &WhitePnt);
+ cmsWhitePointFromTemp(&WhitePnt, TempDest);
+ cmsxyY2XYZ(&bchsw.WPdest, &WhitePnt);
- cmsWhitePointFromTemp(&WhitePnt, TempDest);
- cmsxyY2XYZ(&bchsw.WPdest, &WhitePnt);
+ }
hICC = cmsCreateProfilePlaceholder(ContextID);
if (!hICC) // can't allocate
return NULL;
-
cmsSetDeviceClass(hICC, cmsSigAbstractClass);
cmsSetColorSpace(hICC, cmsSigLabData);
cmsSetPCS(hICC, cmsSigLabData);
@@ -1017,12 +1024,14 @@
} cmsAllowedLUT;
+#define cmsSig0 ((cmsTagSignature) 0)
+
static const cmsAllowedLUT AllowedLUTTypes[] = {
- { FALSE, 0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
- { FALSE, 0, cmsSigLut16Type, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
- { FALSE, 0, cmsSigLut16Type, 2, { cmsSigCurveSetElemType, cmsSigCLutElemType}},
- { TRUE , 0, cmsSigLutAtoBType, 1, { cmsSigCurveSetElemType }},
+ { FALSE, cmsSig0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } },
+ { FALSE, cmsSig0, cmsSigLut16Type, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } },
+ { FALSE, cmsSig0, cmsSigLut16Type, 2, { cmsSigCurveSetElemType, cmsSigCLutElemType } },
+ { TRUE, cmsSig0, cmsSigLutAtoBType, 1, { cmsSigCurveSetElemType } },
{ TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType } },
{ TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } },
{ TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 5, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType }},
diff --git a/src/share/native/sun/java2d/cmm/lcms/cmsxform.c b/src/share/native/sun/java2d/cmm/lcms/cmsxform.c
index 3e244c3..c0a0693 100644
--- a/src/share/native/sun/java2d/cmm/lcms/cmsxform.c
+++ b/src/share/native/sun/java2d/cmm/lcms/cmsxform.c
@@ -621,46 +621,48 @@
_cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID, TransformPlugin);
_cmsTransformCollection* Plugin;
- // Allocate needed memory
- _cmsTRANSFORM* p = (_cmsTRANSFORM*) _cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM));
- if (!p) return NULL;
+ // Allocate needed memory
+ _cmsTRANSFORM* p = (_cmsTRANSFORM*)_cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM));
+ if (!p) return NULL;
- // Store the proposed pipeline
- p ->Lut = lut;
+ // Store the proposed pipeline
+ p->Lut = lut;
- // Let's see if any plug-in want to do the transform by itself
- for (Plugin = ctx ->TransformCollection;
- Plugin != NULL;
- Plugin = Plugin ->Next) {
+ // Let's see if any plug-in want to do the transform by itself
+ if (p->Lut != NULL) {
- if (Plugin ->Factory(&p->xform, &p->UserData, &p ->FreeUserData, &p ->Lut, InputFormat, OutputFormat, dwFlags)) {
+ for (Plugin = ctx->TransformCollection;
+ Plugin != NULL;
+ Plugin = Plugin->Next) {
- // Last plugin in the declaration order takes control. We just keep
- // the original parameters as a logging.
- // Note that cmsFLAGS_CAN_CHANGE_FORMATTER is not set, so by default
- // an optimized transform is not reusable. The plug-in can, however, change
- // the flags and make it suitable.
+ if (Plugin->Factory(&p->xform, &p->UserData, &p->FreeUserData, &p->Lut, InputFormat, OutputFormat, dwFlags)) {
- p ->ContextID = ContextID;
- p ->InputFormat = *InputFormat;
- p ->OutputFormat = *OutputFormat;
- p ->dwOriginalFlags = *dwFlags;
+ // Last plugin in the declaration order takes control. We just keep
+ // the original parameters as a logging.
+ // Note that cmsFLAGS_CAN_CHANGE_FORMATTER is not set, so by default
+ // an optimized transform is not reusable. The plug-in can, however, change
+ // the flags and make it suitable.
- // Fill the formatters just in case the optimized routine is interested.
- // No error is thrown if the formatter doesn't exist. It is up to the optimization
- // factory to decide what to do in those cases.
- p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
- p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
- p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
- p ->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+ p->ContextID = ContextID;
+ p->InputFormat = *InputFormat;
+ p->OutputFormat = *OutputFormat;
+ p->dwOriginalFlags = *dwFlags;
- return p;
- }
- }
+ // Fill the formatters just in case the optimized routine is interested.
+ // No error is thrown if the formatter doesn't exist. It is up to the optimization
+ // factory to decide what to do in those cases.
+ p->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+ p->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+ p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+ p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
- // Not suitable for the transform plug-in, let's check the pipeline plug-in
- if (p ->Lut != NULL)
- _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags);
+ return p;
+ }
+ }
+
+ // Not suitable for the transform plug-in, let's check the pipeline plug-in
+ _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags);
+ }
// Check whatever this is a true floating point transform
if (_cmsFormatterIsFloat(*InputFormat) && _cmsFormatterIsFloat(*OutputFormat)) {
diff --git a/src/share/native/sun/java2d/cmm/lcms/lcms2.h b/src/share/native/sun/java2d/cmm/lcms/lcms2.h
index 2fd2b56..0d66b26 100644
--- a/src/share/native/sun/java2d/cmm/lcms/lcms2.h
+++ b/src/share/native/sun/java2d/cmm/lcms/lcms2.h
@@ -52,7 +52,7 @@
//
//---------------------------------------------------------------------------------
//
-// Version 2.6
+// Version 2.7
//
#ifndef _lcms2_H
@@ -104,7 +104,7 @@
#endif
// Version/release
-#define LCMS_VERSION 2060
+#define LCMS_VERSION 2070
// I will give the chance of redefining basic types for compilers that are not fully C99 compliant
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
@@ -213,27 +213,19 @@
# define CMS_USE_BIG_ENDIAN 1
#endif
-# ifdef TARGET_CPU_PPC
-# if TARGET_CPU_PPC
-# define CMS_USE_BIG_ENDIAN 1
-# endif
-# endif
#if defined(__powerpc__) || defined(__ppc__) || defined(TARGET_CPU_PPC)
+# if __powerpc__ || __ppc__ || TARGET_CPU_PPC
# define CMS_USE_BIG_ENDIAN 1
-# if defined (__GNUC__) && defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN)
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-// // Don't use big endian for PowerPC little endian mode
+# if defined (__GNUC__) && defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
+# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ // Don't use big endian for PowerPC little endian mode
# undef CMS_USE_BIG_ENDIAN
# endif
+# endif
# endif
#endif
-// WORDS_BIGENDIAN takes precedence
-#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN)
-# define CMS_USE_BIG_ENDIAN 1
-#endif
-
#ifdef macintosh
# ifdef __BIG_ENDIAN__
# define CMS_USE_BIG_ENDIAN 1
@@ -243,6 +235,12 @@
# endif
#endif
+// WORDS_BIGENDIAN takes precedence
+#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN)
+# define CMS_USE_BIG_ENDIAN 1
+#endif
+
+
// Calling convention -- this is hardly platform and compiler dependent
#ifdef CMS_IS_WINDOWS_
# if defined(CMS_DLL) || defined(CMS_DLL_BUILD)
@@ -553,7 +551,8 @@
cmsSigLab2FloatPCS = 0x64326C20, // 'd2l '
cmsSigFloatPCS2Lab = 0x6C326420, // 'l2d '
cmsSigXYZ2FloatPCS = 0x64327820, // 'd2x '
- cmsSigFloatPCS2XYZ = 0x78326420 // 'x2d '
+ cmsSigFloatPCS2XYZ = 0x78326420, // 'x2d '
+ cmsSigClipNegativesElemType = 0x636c7020 // 'clp '
} cmsStageSignature;
@@ -1031,6 +1030,10 @@
} cmsICCViewingConditions;
+// Get LittleCMS version (for shared objects) -----------------------------------------------------------------------------
+
+CMSAPI int CMSEXPORT cmsGetEncodedCMMversion(void);
+
// Support of non-standard functions --------------------------------------------------------------------------------------
CMSAPI int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2);
@@ -1509,7 +1512,7 @@
CMSAPI cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace);
-// Build a suitable formatter for the colorspace of this profile
+// Build a suitable formatter for the colorspace of this profile. nBytes=1 means 8 bits, nBytes=2 means 16 bits.
CMSAPI cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat);
CMSAPI cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat);
@@ -1538,6 +1541,7 @@
CMSAPI cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* Stream);
CMSAPI cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromMem(cmsContext ContextID, void *Buffer, cmsUInt32Number size, const char* AccessMode);
CMSAPI cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromNULL(cmsContext ContextID);
+CMSAPI cmsIOHANDLER* CMSEXPORT cmsGetProfileIOhandler(cmsHPROFILE hProfile);
CMSAPI cmsBool CMSEXPORT cmsCloseIOhandler(cmsIOHANDLER* io);
// MD5 message digest --------------------------------------------------------------------------------------------------
@@ -1672,6 +1676,10 @@
#define cmsFLAGS_CLUT_POST_LINEARIZATION 0x0001 // create postlinearization tables if possible
#define cmsFLAGS_CLUT_PRE_LINEARIZATION 0x0010 // create prelinearization tables if possible
+// Specific to unbounded mode
+#define cmsFLAGS_NONEGATIVES 0x8000 // Prevent negative numbers in floating point transforms
+
+
// Fine-tune control over number of gridpoints
#define cmsFLAGS_GRIDPOINTS(n) (((n) & 0xFF) << 16)
diff --git a/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h b/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h
index 7f28f3d..c6cfbd6 100644
--- a/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h
+++ b/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h
@@ -223,11 +223,17 @@
// Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical
// section, even when they changed the underlying algorithm to be more scalable.
// The final parts of the critical section object are unimportant, and can be set
-// to zero for their defaults. This yields an initialization macro:
+// to zero for their defaults. This yields to an initialization macro:
typedef CRITICAL_SECTION _cmsMutex;
-#define CMS_MUTEX_INITIALIZER {(void*) -1,-1,0,0,0,0}
+#define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}
+
+#ifdef _MSC_VER
+# if (_MSC_VER >= 1800)
+# pragma warning(disable : 26135)
+# endif
+#endif
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
{
@@ -313,38 +319,38 @@
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
#endif
@@ -852,6 +858,8 @@
cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);
cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
+cmsStage* _cmsStageClipNegatives(cmsContext ContextID, int nChannels);
+
// For curve set only
cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
diff --git a/src/share/native/sun/tracing/dtrace/JVM.c b/src/share/native/sun/tracing/dtrace/JVM.c
index d17f8a8..ba54d8e 100644
--- a/src/share/native/sun/tracing/dtrace/JVM.c
+++ b/src/share/native/sun/tracing/dtrace/JVM.c
@@ -144,32 +144,34 @@
env, provider, &(jvm_provider->argsAttributes));
}
-static void readProviderData(
+static int readProviderData(
JNIEnv* env, jobject provider, JVM_DTraceProvider* jvm_provider) {
jmethodID mid;
jobjectArray probes;
jsize i;
- jclass clazz = (*env)->GetObjectClass(env, provider); CHECK
+ jclass clazz = (*env)->GetObjectClass(env, provider); CHECK_(0)
mid = (*env)->GetMethodID(
- env, clazz, "getProbes", "()[Lsun/tracing/dtrace/DTraceProbe;"); CHECK
+ env, clazz, "getProbes", "()[Lsun/tracing/dtrace/DTraceProbe;"); CHECK_(0)
probes = (jobjectArray)(*env)->CallObjectMethod(
- env, provider, mid); CHECK
+ env, provider, mid); CHECK_(0)
// Fill JVM structure, describing provider
- jvm_provider->probe_count = (*env)->GetArrayLength(env, probes); CHECK
+ jvm_provider->probe_count = (*env)->GetArrayLength(env, probes); CHECK_(0)
jvm_provider->probes = (JVM_DTraceProbe*)calloc(
jvm_provider->probe_count, sizeof(*jvm_provider->probes));
mid = (*env)->GetMethodID(
- env, clazz, "getProviderName", "()Ljava/lang/String;"); CHECK
+ env, clazz, "getProviderName", "()Ljava/lang/String;"); CHECK_(0)
jvm_provider->name = (jstring)(*env)->CallObjectMethod(
- env, provider, mid); CHECK
+ env, provider, mid); CHECK_(0)
- readInterfaceAttributes(env, provider, jvm_provider); CHECK
+ readInterfaceAttributes(env, provider, jvm_provider); CHECK_(0)
for (i = 0; i < jvm_provider->probe_count; ++i) {
- jobject probe = (*env)->GetObjectArrayElement(env, probes, i); CHECK
- readProbeData(env, probe, &jvm_provider->probes[i]); CHECK
+ jobject probe = (*env)->GetObjectArrayElement(env, probes, i); CHECK_(0)
+ readProbeData(env, probe, &jvm_provider->probes[i]); CHECK_(0)
}
+
+ return 1;
}
/*
@@ -182,6 +184,7 @@
jlong handle = 0;
jsize num_providers;
jsize i;
+ jsize count = 0;
JVM_DTraceProvider* jvm_providers;
initialize();
@@ -195,16 +198,23 @@
jvm_providers = (JVM_DTraceProvider*)calloc(
num_providers, sizeof(*jvm_providers));
- for (i = 0; i < num_providers; ++i) {
- JVM_DTraceProvider* p = &(jvm_providers[i]);
+ for (; count < num_providers; ++count) {
+ JVM_DTraceProvider* p = &(jvm_providers[count]);
jobject provider = (*env)->GetObjectArrayElement(
- env, providers, i);
- readProviderData(env, provider, p);
+ env, providers, count);
+ if ((*env)->ExceptionOccurred(env) ||
+ ! readProviderData(env, provider, p)) {
+ // got an error, bail out!
+ break;
+ }
}
- handle = jvm_symbols->Activate(
- env, JVM_TRACING_DTRACE_VERSION, moduleName,
- num_providers, jvm_providers);
+ if (count == num_providers) {
+ // all providers successfully loaded - get the handle
+ handle = jvm_symbols->Activate(
+ env, JVM_TRACING_DTRACE_VERSION, moduleName,
+ num_providers, jvm_providers);
+ }
for (i = 0; i < num_providers; ++i) {
JVM_DTraceProvider* p = &(jvm_providers[i]);
diff --git a/src/solaris/bin/arm/jvm.cfg b/src/solaris/bin/arm/jvm.cfg
deleted file mode 100644
index c462113..0000000
--- a/src/solaris/bin/arm/jvm.cfg
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (c) 2011, 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.
-#
-# List of JVMs that can be used as an option to java, javac, etc.
-# Order is important -- first in this list is the default JVM.
-# NOTE that this both this file and its format are UNSUPPORTED and
-# WILL GO AWAY in a future release.
-#
-# You may also select a JVM in an arbitrary location with the
-# "-XXaltjvm=<jvm_dir>" option, but that too is unsupported
-# and may not be available in a future release.
-#
--client IF_SERVER_CLASS -server
--server KNOWN
--minimal KNOWN
diff --git a/src/solaris/bin/ppc/jvm.cfg b/src/solaris/bin/ppc/jvm.cfg
deleted file mode 100644
index e930341..0000000
--- a/src/solaris/bin/ppc/jvm.cfg
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (c) 2011, 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.
-#
-# List of JVMs that can be used as an option to java, javac, etc.
-# Order is important -- first in this list is the default JVM.
-# NOTE that this both this file and its format are UNSUPPORTED and
-# WILL GO AWAY in a future release.
-#
-# You may also select a JVM in an arbitrary location with the
-# "-XXaltjvm=<jvm_dir>" option, but that too is unsupported
-# and may not be available in a future release.
-#
--client KNOWN
--server KNOWN
--minimal KNOWN
diff --git a/src/solaris/classes/java/lang/UNIXProcess.java b/src/solaris/classes/java/lang/UNIXProcess.java
index 35d37e6..cc3b596 100644
--- a/src/solaris/classes/java/lang/UNIXProcess.java
+++ b/src/solaris/classes/java/lang/UNIXProcess.java
@@ -405,14 +405,17 @@
if (hasExited) return true;
if (timeout <= 0) return false;
- long timeoutAsNanos = unit.toNanos(timeout);
- long startTime = System.nanoTime();
- long rem = timeoutAsNanos;
+ long remainingNanos = unit.toNanos(timeout);
+ long deadline = System.nanoTime() + remainingNanos;
- while (!hasExited && (rem > 0)) {
- wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
- rem = timeoutAsNanos - (System.nanoTime() - startTime);
- }
+ do {
+ // Round up to next millisecond
+ wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L));
+ if (hasExited) {
+ return true;
+ }
+ remainingNanos = deadline - System.nanoTime();
+ } while (remainingNanos > 0);
return hasExited;
}
diff --git a/src/solaris/classes/sun/awt/UNIXToolkit.java b/src/solaris/classes/sun/awt/UNIXToolkit.java
index 50a913c..d385dc1 100644
--- a/src/solaris/classes/sun/awt/UNIXToolkit.java
+++ b/src/solaris/classes/sun/awt/UNIXToolkit.java
@@ -29,11 +29,9 @@
import java.awt.color.ColorSpace;
import java.awt.image.*;
import java.security.AccessController;
-import java.security.PrivilegedAction;
import sun.security.action.GetIntegerAction;
import com.sun.java.swing.plaf.gtk.GTKConstants.TextDirection;
import sun.java2d.opengl.OGLRenderQueue;
-import java.lang.reflect.InvocationTargetException;
public abstract class UNIXToolkit extends SunToolkit
{
@@ -73,16 +71,16 @@
if (nativeGTKLoaded != null) {
// We've already attempted to load GTK, so just return the
// status of that attempt.
- return nativeGTKLoaded.booleanValue();
+ return nativeGTKLoaded;
} else if (nativeGTKAvailable != null) {
// We've already checked the availability of the native GTK
// libraries, so just return the status of that attempt.
- return nativeGTKAvailable.booleanValue();
+ return nativeGTKAvailable;
} else {
boolean success = check_gtk();
- nativeGTKAvailable = Boolean.valueOf(success);
+ nativeGTKAvailable = success;
return success;
}
}
@@ -99,11 +97,10 @@
public boolean loadGTK() {
synchronized (GTK_LOCK) {
if (nativeGTKLoaded == null) {
- boolean success = load_gtk();
- nativeGTKLoaded = Boolean.valueOf(success);
+ nativeGTKLoaded = load_gtk();
}
}
- return nativeGTKLoaded.booleanValue();
+ return nativeGTKLoaded;
}
/**
@@ -252,6 +249,7 @@
private native void nativeSync();
+ @Override
public void sync() {
// flush the X11 buffer
nativeSync();
@@ -266,6 +264,8 @@
* This requires that the Gnome properties have already been gathered.
*/
public static final String FONTCONFIGAAHINT = "fontconfig/Antialias";
+
+ @Override
protected RenderingHints getDesktopAAHints() {
Object aaValue = getDesktopProperty("gnome.Xft/Antialias");
@@ -288,8 +288,8 @@
* us to default to "OFF". I don't think that's the best guess.
* So if its !=0 then lets assume AA.
*/
- boolean aa = Boolean.valueOf(((aaValue instanceof Number) &&
- ((Number)aaValue).intValue() != 0));
+ boolean aa = ((aaValue instanceof Number)
+ && ((Number) aaValue).intValue() != 0);
Object aaHint;
if (aa) {
String subpixOrder =
diff --git a/src/solaris/classes/sun/awt/X11/XClipboard.java b/src/solaris/classes/sun/awt/X11/XClipboard.java
index 7068b66..0bad274 100644
--- a/src/solaris/classes/sun/awt/X11/XClipboard.java
+++ b/src/solaris/classes/sun/awt/X11/XClipboard.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -281,6 +281,11 @@
}
}
- checkChange(formats);
+ XToolkit.awtUnlock();
+ try {
+ checkChange(formats);
+ } finally {
+ XToolkit.awtLock();
+ }
}
}
diff --git a/src/solaris/classes/sun/awt/X11/XToolkit.java b/src/solaris/classes/sun/awt/X11/XToolkit.java
index 8a264d2..f8673f8 100644
--- a/src/solaris/classes/sun/awt/X11/XToolkit.java
+++ b/src/solaris/classes/sun/awt/X11/XToolkit.java
@@ -814,10 +814,32 @@
// managers don't set this hint correctly, so we just get intersection with windowBounds
if (windowBounds != null && windowBounds.intersects(screenBounds))
{
- insets.left = Math.max((int)Native.getLong(native_ptr, 0), insets.left);
- insets.right = Math.max((int)Native.getLong(native_ptr, 1), insets.right);
- insets.top = Math.max((int)Native.getLong(native_ptr, 2), insets.top);
- insets.bottom = Math.max((int)Native.getLong(native_ptr, 3), insets.bottom);
+ int left = (int)Native.getLong(native_ptr, 0);
+ int right = (int)Native.getLong(native_ptr, 1);
+ int top = (int)Native.getLong(native_ptr, 2);
+ int bottom = (int)Native.getLong(native_ptr, 3);
+
+ /*
+ * struts could be relative to root window bounds, so
+ * make them relative to the screen bounds in this case
+ */
+ left = rootBounds.x + left > screenBounds.x ?
+ rootBounds.x + left - screenBounds.x : 0;
+ right = rootBounds.x + rootBounds.width - right <
+ screenBounds.x + screenBounds.width ?
+ screenBounds.x + screenBounds.width -
+ (rootBounds.x + rootBounds.width - right) : 0;
+ top = rootBounds.y + top > screenBounds.y ?
+ rootBounds.y + top - screenBounds.y : 0;
+ bottom = rootBounds.y + rootBounds.height - bottom <
+ screenBounds.y + screenBounds.height ?
+ screenBounds.y + screenBounds.height -
+ (rootBounds.y + rootBounds.height - bottom) : 0;
+
+ insets.left = Math.max(left, insets.left);
+ insets.right = Math.max(right, insets.right);
+ insets.top = Math.max(top, insets.top);
+ insets.bottom = Math.max(bottom, insets.bottom);
}
}
}
diff --git a/src/solaris/classes/sun/awt/X11ComponentPeer.java b/src/solaris/classes/sun/awt/X11ComponentPeer.java
index 6883972..35623a6 100644
--- a/src/solaris/classes/sun/awt/X11ComponentPeer.java
+++ b/src/solaris/classes/sun/awt/X11ComponentPeer.java
@@ -32,6 +32,7 @@
import java.awt.Graphics;
public interface X11ComponentPeer {
+ long getWindow();
long getContentWindow();
SurfaceData getSurfaceData();
GraphicsConfiguration getGraphicsConfiguration();
diff --git a/src/solaris/classes/sun/awt/X11GraphicsDevice.java b/src/solaris/classes/sun/awt/X11GraphicsDevice.java
index c885427..7ffa132 100644
--- a/src/solaris/classes/sun/awt/X11GraphicsDevice.java
+++ b/src/solaris/classes/sun/awt/X11GraphicsDevice.java
@@ -298,11 +298,7 @@
@Override
public boolean isFullScreenSupported() {
- // REMIND: for now we will only allow fullscreen exclusive mode
- // on the primary screen; we could change this behavior slightly
- // in the future by allowing only one screen to be in fullscreen
- // exclusive mode at any given time...
- boolean fsAvailable = (screen == 0) && isXrandrExtensionSupported();
+ boolean fsAvailable = isXrandrExtensionSupported();
if (fsAvailable) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
@@ -328,7 +324,7 @@
private static void enterFullScreenExclusive(Window w) {
X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
if (peer != null) {
- enterFullScreenExclusive(peer.getContentWindow());
+ enterFullScreenExclusive(peer.getWindow());
peer.setFullScreenExclusiveModeState(true);
}
}
@@ -337,7 +333,7 @@
X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
if (peer != null) {
peer.setFullScreenExclusiveModeState(false);
- exitFullScreenExclusive(peer.getContentWindow());
+ exitFullScreenExclusive(peer.getWindow());
}
}
@@ -379,7 +375,11 @@
@Override
public synchronized DisplayMode getDisplayMode() {
if (isFullScreenSupported()) {
- return getCurrentDisplayMode(screen);
+ DisplayMode mode = getCurrentDisplayMode(screen);
+ if (mode == null) {
+ mode = getDefaultDisplayMode();
+ }
+ return mode;
} else {
if (origDisplayMode == null) {
origDisplayMode = getDefaultDisplayMode();
diff --git a/src/solaris/classes/sun/font/FcFontConfiguration.java b/src/solaris/classes/sun/font/FcFontConfiguration.java
index 1aff478..34d8b7c 100644
--- a/src/solaris/classes/sun/font/FcFontConfiguration.java
+++ b/src/solaris/classes/sun/font/FcFontConfiguration.java
@@ -180,7 +180,7 @@
String[] componentFaceNames = cfi[idx].getComponentFaceNames();
FontDescriptor[] ret = new FontDescriptor[componentFaceNames.length];
for (int i = 0; i < componentFaceNames.length; i++) {
- ret[i] = new FontDescriptor(componentFaceNames[i], StandardCharsets.UTF_8.newEncoder(), new int[0]);
+ ret[i] = new FontDescriptor(componentFaceNames[i], StandardCharsets.ISO_8859_1.newEncoder(), new int[0]);
}
return ret;
diff --git a/src/solaris/classes/sun/java2d/xr/XRSolidSrcPict.java b/src/solaris/classes/sun/java2d/xr/XRSolidSrcPict.java
index f999748..03e3bdb 100644
--- a/src/solaris/classes/sun/java2d/xr/XRSolidSrcPict.java
+++ b/src/solaris/classes/sun/java2d/xr/XRSolidSrcPict.java
@@ -1,6 +1,5 @@
/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
-
+ * Copyright (c) 2013, 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
diff --git a/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java b/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java
index 5af3d44..8075953 100644
--- a/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java
+++ b/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java
@@ -85,6 +85,15 @@
if (val.charAt(0) == '#' || val.charAt(0) == ';') {
break;
}
+ if ("nameserver".equals(keyword)) {
+ if (val.indexOf(':') >= 0 &&
+ val.indexOf('.') < 0 && // skip for IPv4 literals with port
+ val.indexOf('[') < 0 &&
+ val.indexOf(']') < 0 ) {
+ // IPv6 literal, in non-BSD-style.
+ val = "[" + val + "]";
+ }
+ }
ll.add(val);
if (--maxvalues == 0) {
break;
diff --git a/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java b/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
index 2c7504c..3b88948 100644
--- a/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
+++ b/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
@@ -25,10 +25,10 @@
package sun.nio.ch;
-import java.io.*;
+import java.io.FileDescriptor;
+import java.io.IOException;
-class FileDispatcherImpl extends FileDispatcher
-{
+class FileDispatcherImpl extends FileDispatcher {
static {
IOUtil.load();
@@ -108,6 +108,14 @@
return new FileDescriptor();
}
+ boolean canTransferToDirectly(java.nio.channels.SelectableChannel sc) {
+ return true;
+ }
+
+ boolean transferToDirectlyNeedsPositionLock() {
+ return false;
+ }
+
// -- Native methods --
static native int read0(FileDescriptor fd, long address, int len)
diff --git a/src/solaris/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java b/src/solaris/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java
index d549b87..a959661 100644
--- a/src/solaris/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java
+++ b/src/solaris/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
diff --git a/src/solaris/native/java/io/UnixFileSystem_md.c b/src/solaris/native/java/io/UnixFileSystem_md.c
index 5f95cd9..487e8a2 100644
--- a/src/solaris/native/java/io/UnixFileSystem_md.c
+++ b/src/solaris/native/java/io/UnixFileSystem_md.c
@@ -283,6 +283,10 @@
struct dirent64 *result;
int len, maxlen;
jobjectArray rv, old;
+ jclass str_class;
+
+ str_class = JNU_ClassString(env);
+ CHECK_NULL_RETURN(str_class, NULL);
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
dir = opendir(path);
@@ -299,7 +303,7 @@
/* Allocate an initial String array */
len = 0;
maxlen = 16;
- rv = (*env)->NewObjectArray(env, maxlen, JNU_ClassString(env), NULL);
+ rv = (*env)->NewObjectArray(env, maxlen, str_class, NULL);
if (rv == NULL) goto error;
/* Scan the directory */
@@ -309,8 +313,7 @@
continue;
if (len == maxlen) {
old = rv;
- rv = (*env)->NewObjectArray(env, maxlen <<= 1,
- JNU_ClassString(env), NULL);
+ rv = (*env)->NewObjectArray(env, maxlen <<= 1, str_class, NULL);
if (rv == NULL) goto error;
if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;
(*env)->DeleteLocalRef(env, old);
@@ -329,7 +332,7 @@
/* Copy the final results into an appropriately-sized array */
old = rv;
- rv = (*env)->NewObjectArray(env, len, JNU_ClassString(env), NULL);
+ rv = (*env)->NewObjectArray(env, len, str_class, NULL);
if (rv == NULL) {
return NULL;
}
diff --git a/src/solaris/native/java/net/Inet6AddressImpl.c b/src/solaris/native/java/net/Inet6AddressImpl.c
index 7ac26c0..eab898d 100644
--- a/src/solaris/native/java/net/Inet6AddressImpl.c
+++ b/src/solaris/native/java/net/Inet6AddressImpl.c
@@ -196,6 +196,10 @@
}
name = (*env)->NewStringUTF(env, hostname);
+ if (name == NULL) {
+ freeifaddrs(ifa);
+ return NULL;
+ }
/* Iterate over the interfaces, and total up the number of IPv4 and IPv6
* addresses we have. Also keep a count of loopback addresses. We need to
diff --git a/src/solaris/native/java/net/NetworkInterface.c b/src/solaris/native/java/net/NetworkInterface.c
index 09ab89c..1788944 100644
--- a/src/solaris/native/java/net/NetworkInterface.c
+++ b/src/solaris/native/java/net/NetworkInterface.c
@@ -253,6 +253,7 @@
if (name_utf == NULL) {
if (!(*env)->ExceptionCheck(env))
JNU_ThrowOutOfMemoryError(env, NULL);
+ freeif(ifs);
return NULL;
}
/*
@@ -527,9 +528,9 @@
JNU_ThrowOutOfMemoryError(env, NULL);
return NULL;
}
- if ((sock =openSocketWithFallback(env, name_utf)) < 0) {
+ if ((sock = openSocketWithFallback(env, name_utf)) < 0) {
(*env)->ReleaseStringUTFChars(env, name, name_utf);
- return JNI_FALSE;
+ return NULL;
}
diff --git a/src/solaris/native/java/net/net_util_md.c b/src/solaris/native/java/net/net_util_md.c
index f32b089..9dec516 100644
--- a/src/solaris/native/java/net/net_util_md.c
+++ b/src/solaris/native/java/net/net_util_md.c
@@ -97,6 +97,7 @@
CHECK_NULL(c);
ni_defaultIndexID = (*env)->GetStaticFieldID(
env, c, "defaultIndex", "I");
+ CHECK_NULL(ni_defaultIndexID);
ni_class = c;
}
int defaultIndex;
@@ -119,6 +120,7 @@
CHECK_NULL_RETURN(c, 0);
ni_defaultIndexID = (*env)->GetStaticFieldID(env, c,
"defaultIndex", "I");
+ CHECK_NULL_RETURN(ni_defaultIndexID, 0);
ni_class = c;
}
int defaultIndex = 0;
@@ -777,6 +779,11 @@
#endif
}
+JNIEXPORT jint JNICALL
+NET_EnableFastTcpLoopback(int fd) {
+ return 0;
+}
+
/* In the case of an IPv4 Inetaddress this method will return an
* IPv4 mapped address where IPv6 is available and v4MappedAddress is TRUE.
* Otherwise it will return a sockaddr_in structure for an IPv4 InetAddress.
diff --git a/src/solaris/native/sun/awt/awt_Event.c b/src/solaris/native/sun/awt/awt_Event.c
index e1b48d5..6442469 100644
--- a/src/solaris/native/sun/awt/awt_Event.c
+++ b/src/solaris/native/sun/awt/awt_Event.c
@@ -42,7 +42,7 @@
JNIEXPORT void JNICALL
Java_java_awt_Event_initIDs(JNIEnv *env, jclass cls)
{
- eventIDs.data = (*env)->GetFieldID(env, cls, "data", "J");
- eventIDs.consumed = (*env)->GetFieldID(env, cls, "consumed", "Z");
- eventIDs.id = (*env)->GetFieldID(env, cls, "id", "I");
+ CHECK_NULL(eventIDs.data = (*env)->GetFieldID(env, cls, "data", "J"));
+ CHECK_NULL(eventIDs.consumed = (*env)->GetFieldID(env, cls, "consumed", "Z"));
+ CHECK_NULL(eventIDs.id = (*env)->GetFieldID(env, cls, "id", "I"));
}
diff --git a/src/solaris/native/sun/awt/awt_Font.c b/src/solaris/native/sun/awt/awt_Font.c
index 14870b5..3b16c6e 100644
--- a/src/solaris/native/sun/awt/awt_Font.c
+++ b/src/solaris/native/sun/awt/awt_Font.c
@@ -579,6 +579,7 @@
Disposer_AddRecord(env, font, pDataDisposeMethod, ptr_to_jlong(fdata));
return fdata;
} else {
+ JNU_CHECK_EXCEPTION_RETURN(env, NULL);
Display *display = NULL;
struct FontData *fdata = NULL;
char fontSpec[1024];
diff --git a/src/solaris/native/sun/awt/awt_GraphicsEnv.c b/src/solaris/native/sun/awt/awt_GraphicsEnv.c
index f142c86..1a20b40 100644
--- a/src/solaris/native/sun/awt/awt_GraphicsEnv.c
+++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.c
@@ -23,6 +23,7 @@
* questions.
*/
+#include "jni_util.h"
#include "awt_p.h"
#include "awt.h"
#include "color.h"
@@ -763,6 +764,7 @@
XSetIOErrorHandler(xioerror_handler);
JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XErrorHandlerUtil", "init", "(J)V",
ptr_to_jlong(awt_display));
+ JNU_CHECK_EXCEPTION_RETURN(env, NULL);
/* set awt_numScreens, and whether or not we're using Xinerama */
xineramaInit();
@@ -789,6 +791,7 @@
x11Screens[i].root = RootWindow(awt_display, i);
}
x11Screens[i].defaultConfig = makeDefaultConfig(env, i);
+ JNU_CHECK_EXCEPTION_RETURN(env, NULL);
}
return dpy;
@@ -1495,7 +1498,7 @@
if (aData == NULL) {
return JNI_FALSE;
}
- return (jboolean)aData->isTranslucencySupported;
+ return aData->isTranslucencySupported ? JNI_TRUE : JNI_FALSE;
#endif
}
@@ -1575,9 +1578,9 @@
jobject this)
{
#ifdef HEADLESS
- return false;
+ return JNI_FALSE;
#else
- return usingXinerama;
+ return usingXinerama ? JNI_TRUE : JNI_FALSE;
#endif /* HEADLESS */
}
@@ -1713,9 +1716,9 @@
/*
* REMIND: Fullscreen mode doesn't work quite right with multi-monitor
- * setups and RANDR 1.2. So for now we also require a single screen.
+ * setups and RANDR 1.2.
*/
- if (awt_numScreens > 1 ) {
+ if ((rr_maj_ver == 1 && rr_min_ver <= 2) && awt_numScreens > 1) {
J2dRlsTraceLn(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. "
"Multiple screens in use");
dlclose(pLibRandR);
@@ -1803,40 +1806,14 @@
Atom wmState = XInternAtom(awt_display, "_NET_WM_STATE", False);
Atom wmStateFs = XInternAtom(awt_display,
"_NET_WM_STATE_FULLSCREEN", False);
- Window root, parent, *children = NULL;
- unsigned int numchildren;
+ XWindowAttributes attr;
XEvent event;
- Status status;
- if (wmState == None || wmStateFs == None) {
+ if (wmState == None || wmStateFs == None
+ || !XGetWindowAttributes(awt_display, win, &attr)) {
return;
}
- /*
- * Note: the Window passed to this method is typically the "content
- * window" of the top-level, but we need the actual shell window for
- * the purposes of constructing the XEvent. Therefore, we walk up the
- * window hierarchy here to find the true top-level.
- */
- do {
- if (!XQueryTree(awt_display, win,
- &root, &parent,
- &children, &numchildren))
- {
- return;
- }
-
- if (children != NULL) {
- XFree(children);
- }
-
- if (parent == root) {
- break;
- }
-
- win = parent;
- } while (root != parent);
-
memset(&event, 0, sizeof(event));
event.xclient.type = ClientMessage;
event.xclient.message_type = wmState;
@@ -1846,7 +1823,7 @@
event.xclient.data.l[0] = enabled ? 1 : 0; // 1==add, 0==remove
event.xclient.data.l[1] = wmStateFs;
- XSendEvent(awt_display, root, False,
+ XSendEvent(awt_display, attr.root, False,
SubstructureRedirectMask | SubstructureNotifyMask,
&event);
XSync(awt_display, False);
diff --git a/src/solaris/native/sun/awt/gtk2_interface.c b/src/solaris/native/sun/awt/gtk2_interface.c
index f61fee0..1ba9beb 100644
--- a/src/solaris/native/sun/awt/gtk2_interface.c
+++ b/src/solaris/native/sun/awt/gtk2_interface.c
@@ -33,6 +33,7 @@
#include "jvm_md.h"
#include "sizecalc.h"
#include <jni_util.h>
+#include "awt.h"
#define GTK2_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0")
#define GTK2_LIB JNI_LIB_NAME("gtk-x11-2.0")
@@ -433,7 +434,8 @@
result = TRUE;
}
- dlclose(lib);
+ // 8048289: workaround for https://bugzilla.gnome.org/show_bug.cgi?id=733065
+ // dlclose(lib);
return result;
}
@@ -889,6 +891,7 @@
* BadMatch errors which we would normally ignore. The IO error handler
* is preserved here, too, just for consistency.
*/
+ AWT_LOCK();
handler = XSetErrorHandler(NULL);
io_handler = XSetIOErrorHandler(NULL);
@@ -925,6 +928,7 @@
XSetErrorHandler(handler);
XSetIOErrorHandler(io_handler);
+ AWT_UNLOCK();
/* Initialize widget array. */
for (i = 0; i < _GTK_WIDGET_TYPE_SIZE; i++)
diff --git a/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c b/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c
index 1c040e0..6801926 100644
--- a/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c
+++ b/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c
@@ -72,6 +72,11 @@
static void quit(JNIEnv * env, jobject jpeer, gboolean isSignalHandler)
{
+ jthrowable pendingException;
+ if (pendingException = (*env)->ExceptionOccurred(env)) {
+ (*env)->ExceptionClear(env);
+ }
+
GtkWidget * dialog = (GtkWidget*)jlong_to_ptr(
(*env)->GetLongField(env, jpeer, widgetFieldID));
@@ -95,6 +100,10 @@
fp_gdk_threads_leave();
}
}
+
+ if (pendingException) {
+ (*env)->Throw(env, pendingException);
+ }
}
/*
diff --git a/src/solaris/native/sun/font/X11FontScaler.c b/src/solaris/native/sun/font/X11FontScaler.c
index dc83f4c..c8a3cf8 100644
--- a/src/solaris/native/sun/font/X11FontScaler.c
+++ b/src/solaris/native/sun/font/X11FontScaler.c
@@ -234,7 +234,7 @@
NativeScalerContext *context = (NativeScalerContext*)pScalerContext;
AWTFont xFont = (AWTFont)context->xFont;
- AWTChar xcs;
+ AWTChar xcs = NULL;
jfloat advance = 0.0f;
if (xFont == NULL || context->ptSize == NO_POINTSIZE) {
diff --git a/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c b/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
index 816270c..f5dd361 100644
--- a/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
+++ b/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
@@ -56,18 +56,28 @@
Java_sun_nio_ch_DatagramChannelImpl_initIDs(JNIEnv *env, jclass clazz)
{
clazz = (*env)->FindClass(env, "java/net/InetSocketAddress");
+ CHECK_NULL(clazz);
isa_class = (*env)->NewGlobalRef(env, clazz);
+ if (isa_class == NULL) {
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return;
+ }
isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
"(Ljava/net/InetAddress;I)V");
+ CHECK_NULL(isa_ctorID);
clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
+ CHECK_NULL(clazz);
dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
"Ljava/net/SocketAddress;");
+ CHECK_NULL(dci_senderID);
dci_senderAddrID = (*env)->GetFieldID(env, clazz,
"cachedSenderInetAddress",
"Ljava/net/InetAddress;");
+ CHECK_NULL(dci_senderAddrID);
dci_senderPortID = (*env)->GetFieldID(env, clazz,
"cachedSenderPort", "I");
+ CHECK_NULL(dci_senderPortID);
}
JNIEXPORT void JNICALL
@@ -121,7 +131,7 @@
* but that is acceptable.
*/
if (rv < 0 && errno == EAFNOSUPPORT)
- rv = errno = 0;
+ rv = errno = 0;
#endif
}
#endif
@@ -192,17 +202,11 @@
if (senderAddr == NULL) {
jobject isa = NULL;
int port;
- jobject ia = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa,
- &port);
-
+ jobject ia = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
if (ia != NULL) {
isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
}
-
- if (isa == NULL) {
- JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
- return IOS_THROWN;
- }
+ CHECK_NULL_RETURN(isa, IOS_THROWN);
(*env)->SetObjectField(env, this, dci_senderAddrID, ia);
(*env)->SetIntField(env, this, dci_senderPortID,
diff --git a/src/solaris/native/sun/nio/ch/FileChannelImpl.c b/src/solaris/native/sun/nio/ch/FileChannelImpl.c
index 8952890..d8face7 100644
--- a/src/solaris/native/sun/nio/ch/FileChannelImpl.c
+++ b/src/solaris/native/sun/nio/ch/FileChannelImpl.c
@@ -154,10 +154,13 @@
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
- jint srcFD,
+ jobject srcFDO,
jlong position, jlong count,
- jint dstFD)
+ jobject dstFDO)
{
+ jint srcFD = fdval(env, srcFDO);
+ jint dstFD = fdval(env, dstFDO);
+
#if defined(__linux__)
off64_t offset = (off64_t)position;
jlong n = sendfile64(dstFD, srcFD, &offset, (size_t)count);
diff --git a/src/solaris/native/sun/nio/ch/FileKey.c b/src/solaris/native/sun/nio/ch/FileKey.c
index ddb8832..bdb42a6 100644
--- a/src/solaris/native/sun/nio/ch/FileKey.c
+++ b/src/solaris/native/sun/nio/ch/FileKey.c
@@ -43,8 +43,8 @@
JNIEXPORT void JNICALL
Java_sun_nio_ch_FileKey_initIDs(JNIEnv *env, jclass clazz)
{
- key_st_dev = (*env)->GetFieldID(env, clazz, "st_dev", "J");
- key_st_ino = (*env)->GetFieldID(env, clazz, "st_ino", "J");
+ CHECK_NULL(key_st_dev = (*env)->GetFieldID(env, clazz, "st_dev", "J"));
+ CHECK_NULL(key_st_ino = (*env)->GetFieldID(env, clazz, "st_ino", "J"));
}
diff --git a/src/solaris/native/sun/nio/ch/IOUtil.c b/src/solaris/native/sun/nio/ch/IOUtil.c
index 7dbf010..438bf41 100644
--- a/src/solaris/native/sun/nio/ch/IOUtil.c
+++ b/src/solaris/native/sun/nio/ch/IOUtil.c
@@ -42,8 +42,8 @@
JNIEXPORT void JNICALL
Java_sun_nio_ch_IOUtil_initIDs(JNIEnv *env, jclass clazz)
{
- clazz = (*env)->FindClass(env, "java/io/FileDescriptor");
- fd_fdID = (*env)->GetFieldID(env, clazz, "fd", "I");
+ CHECK_NULL(clazz = (*env)->FindClass(env, "java/io/FileDescriptor"));
+ CHECK_NULL(fd_fdID = (*env)->GetFieldID(env, clazz, "fd", "I"));
}
JNIEXPORT jboolean JNICALL
diff --git a/src/solaris/native/sun/nio/ch/Net.c b/src/solaris/native/sun/nio/ch/Net.c
index ae7f579..73560ad 100644
--- a/src/solaris/native/sun/nio/ch/Net.c
+++ b/src/solaris/native/sun/nio/ch/Net.c
@@ -231,7 +231,7 @@
JNIEXPORT int JNICALL
Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
- jboolean stream, jboolean reuse)
+ jboolean stream, jboolean reuse, jboolean ignored)
{
int fd;
int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
diff --git a/src/solaris/native/sun/nio/ch/ServerSocketChannelImpl.c b/src/solaris/native/sun/nio/ch/ServerSocketChannelImpl.c
index 7a730cc..e96c9b0 100644
--- a/src/solaris/native/sun/nio/ch/ServerSocketChannelImpl.c
+++ b/src/solaris/native/sun/nio/ch/ServerSocketChannelImpl.c
@@ -57,12 +57,20 @@
jclass cls;
cls = (*env)->FindClass(env, "java/io/FileDescriptor");
+ CHECK_NULL(cls);
fd_fdID = (*env)->GetFieldID(env, cls, "fd", "I");
+ CHECK_NULL(fd_fdID);
cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
+ CHECK_NULL(cls);
isa_class = (*env)->NewGlobalRef(env, cls);
+ if (isa_class == NULL) {
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return;
+ }
isa_ctorID = (*env)->GetMethodID(env, cls, "<init>",
"(Ljava/net/InetAddress;I)V");
+ CHECK_NULL(isa_ctorID);
}
JNIEXPORT jint JNICALL
@@ -79,6 +87,10 @@
jint remote_port;
NET_AllocSockaddr(&sa, &alloc_len);
+ if (sa == NULL) {
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return IOS_THROWN;
+ }
/*
* accept connection but ignore ECONNABORTED indicating that
@@ -110,8 +122,9 @@
(*env)->SetIntField(env, newfdo, fd_fdID, newfd);
remote_ia = NET_SockaddrToInetAddress(env, sa, (int *)&remote_port);
free((void *)sa);
- isa = (*env)->NewObject(env, isa_class, isa_ctorID,
- remote_ia, remote_port);
+ CHECK_NULL_RETURN(remote_ia, IOS_THROWN);
+ isa = (*env)->NewObject(env, isa_class, isa_ctorID, remote_ia, remote_port);
+ CHECK_NULL_RETURN(isa, IOS_THROWN);
(*env)->SetObjectArrayElement(env, isaa, 0, isa);
return 1;
}
diff --git a/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c b/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c
index 2ccf0f8..63000d8 100644
--- a/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c
+++ b/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -213,6 +213,7 @@
/* retrieved address from sockaddr */
isaObj = SockAddrToInetSocketAddress(env, sap);
+ CHECK_NULL(isaObj);
/* data retrieved from sff_data */
if (dataLength > 0) {
@@ -337,6 +338,7 @@
}
addressObj = SockAddrToInetSocketAddress(env, (struct sockaddr*)&spc->spc_aaddr);
+ CHECK_NULL(addressObj);
/* create PeerAddressChanged */
resultObj = (*env)->NewObject(env, spc_class, spc_ctrID, spc->spc_assoc_id,
@@ -393,6 +395,7 @@
}
isa = SockAddrToInetSocketAddress(env, sap);
+ CHECK_NULL(isa);
getControlData(msg, cdata);
/* create MessageInfoImpl */
@@ -461,11 +464,6 @@
union sctp_notification *snp;
jboolean allocated = JNI_FALSE;
- if (rv > SCTP_NOTIFICATION_SIZE) {
- JNU_ThrowInternalError(env, "should not reach here");
- return -1;
- }
-
if (!(msg->msg_flags & MSG_EOR) && length < SCTP_NOTIFICATION_SIZE) {
char* newBuf;
int rvSAVE = rv;
@@ -613,4 +611,3 @@
return Java_sun_nio_ch_SocketChannelImpl_checkConnect(env, this,
fdo, block, ready);
}
-
diff --git a/src/solaris/native/sun/nio/ch/sctp/SctpNet.c b/src/solaris/native/sun/nio/ch/sctp/SctpNet.c
index 57c4fae..1b700bb 100644
--- a/src/solaris/native/sun/nio/ch/sctp/SctpNet.c
+++ b/src/solaris/native/sun/nio/ch/sctp/SctpNet.c
@@ -315,11 +315,12 @@
if (isaCls == 0) {
jclass c = (*env)->FindClass(env, "java/net/InetSocketAddress");
CHECK_NULL(c);
+ isaCtrID = (*env)->GetMethodID(env, c, "<init>",
+ "(Ljava/net/InetAddress;I)V");
+ CHECK_NULL(isaCtrID);
isaCls = (*env)->NewGlobalRef(env, c);
CHECK_NULL(isaCls);
(*env)->DeleteLocalRef(env, c);
- isaCtrID = (*env)->GetMethodID(env, isaCls, "<init>",
- "(Ljava/net/InetAddress;I)V");
}
}
@@ -382,8 +383,9 @@
ia = NET_SockaddrToInetAddress(env, sap, &port);
if (ia != NULL)
isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
- if (isa != NULL)
- (*env)->SetObjectArrayElement(env, isaa, i, isa);
+ if (isa == NULL)
+ break;
+ (*env)->SetObjectArrayElement(env, isaa, i, isa);
if (sap->sa_family == AF_INET)
addr_buf = ((struct sockaddr_in*)addr_buf) + 1;
@@ -433,8 +435,9 @@
ia = NET_SockaddrToInetAddress(env, sap, &port);
if (ia != NULL)
isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
- if (isa != NULL)
- (*env)->SetObjectArrayElement(env, isaa, i, isa);
+ if (isa == NULL)
+ break;
+ (*env)->SetObjectArrayElement(env, isaa, i, isa);
if (sap->sa_family == AF_INET)
addr_buf = ((struct sockaddr_in*)addr_buf) + 1;
diff --git a/src/solaris/native/sun/nio/fs/BsdNativeDispatcher.c b/src/solaris/native/sun/nio/fs/BsdNativeDispatcher.c
index 0b4f2a7..9453f75 100644
--- a/src/solaris/native/sun/nio/fs/BsdNativeDispatcher.c
+++ b/src/solaris/native/sun/nio/fs/BsdNativeDispatcher.c
@@ -72,13 +72,15 @@
jclass clazz;
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
- if (clazz == NULL) {
- return;
- }
+ CHECK_NULL(clazz);
entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
+ CHECK_NULL(entry_name);
entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
+ CHECK_NULL(entry_dir);
entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
+ CHECK_NULL(entry_fstype);
entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
+ CHECK_NULL(entry_options);
}
JNIEXPORT jlong JNICALL
@@ -201,4 +203,3 @@
free(iter);
}
}
-
diff --git a/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c b/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c
index 1de7d5b..c8500db 100644
--- a/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c
+++ b/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c
@@ -68,13 +68,15 @@
my_flistxattr_func = (flistxattr_func*)dlsym(RTLD_DEFAULT, "flistxattr");
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
- if (clazz == NULL)
- return;
-
+ CHECK_NULL(clazz);
entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
+ CHECK_NULL(entry_name);
entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
+ CHECK_NULL(entry_dir);
entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
+ CHECK_NULL(entry_fstype);
entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
+ CHECK_NULL(entry_options);
}
JNIEXPORT jint JNICALL
diff --git a/src/solaris/native/sun/nio/fs/SolarisNativeDispatcher.c b/src/solaris/native/sun/nio/fs/SolarisNativeDispatcher.c
index 1480ea9..de04bbd 100644
--- a/src/solaris/native/sun/nio/fs/SolarisNativeDispatcher.c
+++ b/src/solaris/native/sun/nio/fs/SolarisNativeDispatcher.c
@@ -55,14 +55,17 @@
JNIEXPORT void JNICALL
Java_sun_nio_fs_SolarisNativeDispatcher_init(JNIEnv *env, jclass clazz) {
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
- if (clazz == NULL)
- return;
-
+ CHECK_NULL(clazz);
entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
+ CHECK_NULL(entry_name);
entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
+ CHECK_NULL(entry_dir);
entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
+ CHECK_NULL(entry_fstype);
entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
+ CHECK_NULL(entry_options);
entry_dev = (*env)->GetFieldID(env, clazz, "dev", "J");
+ CHECK_NULL(entry_dev);
}
JNIEXPORT jint JNICALL
diff --git a/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c b/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c
index c06efaf..e8a1623 100644
--- a/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c
+++ b/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c
@@ -179,46 +179,64 @@
jclass clazz;
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileAttributes");
- if (clazz == NULL) {
- return 0;
- }
+ CHECK_NULL_RETURN(clazz, 0);
attrs_st_mode = (*env)->GetFieldID(env, clazz, "st_mode", "I");
+ CHECK_NULL_RETURN(attrs_st_mode, 0);
attrs_st_ino = (*env)->GetFieldID(env, clazz, "st_ino", "J");
+ CHECK_NULL_RETURN(attrs_st_ino, 0);
attrs_st_dev = (*env)->GetFieldID(env, clazz, "st_dev", "J");
+ CHECK_NULL_RETURN(attrs_st_dev, 0);
attrs_st_rdev = (*env)->GetFieldID(env, clazz, "st_rdev", "J");
+ CHECK_NULL_RETURN(attrs_st_rdev, 0);
attrs_st_nlink = (*env)->GetFieldID(env, clazz, "st_nlink", "I");
+ CHECK_NULL_RETURN(attrs_st_nlink, 0);
attrs_st_uid = (*env)->GetFieldID(env, clazz, "st_uid", "I");
+ CHECK_NULL_RETURN(attrs_st_uid, 0);
attrs_st_gid = (*env)->GetFieldID(env, clazz, "st_gid", "I");
+ CHECK_NULL_RETURN(attrs_st_gid, 0);
attrs_st_size = (*env)->GetFieldID(env, clazz, "st_size", "J");
+ CHECK_NULL_RETURN(attrs_st_size, 0);
attrs_st_atime_sec = (*env)->GetFieldID(env, clazz, "st_atime_sec", "J");
+ CHECK_NULL_RETURN(attrs_st_atime_sec, 0);
attrs_st_atime_nsec = (*env)->GetFieldID(env, clazz, "st_atime_nsec", "J");
+ CHECK_NULL_RETURN(attrs_st_atime_nsec, 0);
attrs_st_mtime_sec = (*env)->GetFieldID(env, clazz, "st_mtime_sec", "J");
+ CHECK_NULL_RETURN(attrs_st_mtime_sec, 0);
attrs_st_mtime_nsec = (*env)->GetFieldID(env, clazz, "st_mtime_nsec", "J");
+ CHECK_NULL_RETURN(attrs_st_mtime_nsec, 0);
attrs_st_ctime_sec = (*env)->GetFieldID(env, clazz, "st_ctime_sec", "J");
+ CHECK_NULL_RETURN(attrs_st_ctime_sec, 0);
attrs_st_ctime_nsec = (*env)->GetFieldID(env, clazz, "st_ctime_nsec", "J");
+ CHECK_NULL_RETURN(attrs_st_ctime_nsec, 0);
#ifdef _DARWIN_FEATURE_64_BIT_INODE
attrs_st_birthtime_sec = (*env)->GetFieldID(env, clazz, "st_birthtime_sec", "J");
+ CHECK_NULL_RETURN(attrs_st_birthtime_sec, 0);
#endif
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileStoreAttributes");
- if (clazz == NULL) {
- return 0;
- }
+ CHECK_NULL_RETURN(clazz, 0);
attrs_f_frsize = (*env)->GetFieldID(env, clazz, "f_frsize", "J");
+ CHECK_NULL_RETURN(attrs_f_frsize, 0);
attrs_f_blocks = (*env)->GetFieldID(env, clazz, "f_blocks", "J");
+ CHECK_NULL_RETURN(attrs_f_blocks, 0);
attrs_f_bfree = (*env)->GetFieldID(env, clazz, "f_bfree", "J");
+ CHECK_NULL_RETURN(attrs_f_bfree, 0);
attrs_f_bavail = (*env)->GetFieldID(env, clazz, "f_bavail", "J");
+ CHECK_NULL_RETURN(attrs_f_bavail, 0);
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
- if (clazz == NULL) {
- return 0;
- }
+ CHECK_NULL_RETURN(clazz, 0);
entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
+ CHECK_NULL_RETURN(entry_name, 0);
entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
+ CHECK_NULL_RETURN(entry_dir, 0);
entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
+ CHECK_NULL_RETURN(entry_fstype, 0);
entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
+ CHECK_NULL_RETURN(entry_options, 0);
entry_dev = (*env)->GetFieldID(env, clazz, "dev", "J");
+ CHECK_NULL_RETURN(entry_dev, 0);
/* system calls that might not be available at run time */
diff --git a/src/solaris/native/sun/xawt/XToolkit.c b/src/solaris/native/sun/xawt/XToolkit.c
index 77a6af8..099c167 100644
--- a/src/solaris/native/sun/xawt/XToolkit.c
+++ b/src/solaris/native/sun/xawt/XToolkit.c
@@ -77,7 +77,7 @@
#ifndef HEADLESS
extern Display* awt_init_Display(JNIEnv *env, jobject this);
-extern void freeNativeStringArray(char **array, long length);
+extern void freeNativeStringArray(char **array, jsize length);
extern char** stringArrayToNative(JNIEnv *env, jobjectArray array, jsize * ret_length);
struct XFontPeerIDs xFontPeerIDs;
diff --git a/src/windows/classes/com/sun/java/accessibility/32bit/AccessBridgeLoader.java b/src/windows/classes/com/sun/java/accessibility/32bit/AccessBridgeLoader.java
new file mode 100644
index 0000000..1e04c4d
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/32bit/AccessBridgeLoader.java
@@ -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<Object>() {
+ 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<Object>() {
+ public Object run() {
+ System.loadLibrary("JAWT");
+ System.loadLibrary("JAWTAccessBridge-32");
+ return null;
+ }
+ }, null, new RuntimePermission("loadLibrary.JAWT"),
+ new RuntimePermission("loadLibrary.JAWTAccessBridge-32")
+ );
+ }
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/64bit/AccessBridgeLoader.java b/src/windows/classes/com/sun/java/accessibility/64bit/AccessBridgeLoader.java
new file mode 100644
index 0000000..45f30c8
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/64bit/AccessBridgeLoader.java
@@ -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<Object>() {
+ 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<Object>() {
+ public Object run() {
+ System.loadLibrary("JAWT");
+ System.loadLibrary("JAWTAccessBridge-64");
+ return null;
+ }
+ }, null, new RuntimePermission("loadLibrary.JAWT"),
+ new RuntimePermission("loadLibrary.JAWTAccessBridge-64")
+ );
+ }
+ }
+
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/AccessBridge.java b/src/windows/classes/com/sun/java/accessibility/AccessBridge.java
new file mode 100644
index 0000000..e21429e
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/AccessBridge.java
@@ -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<String,AccessibleRole> accessibleRoleMap = new ConcurrentHashMap<>();
+
+ /**
+ If the object's role is in the following array getVirtualAccessibleName
+ will use the extended search algorithm.
+ */
+ private ArrayList<AccessibleRole> 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<AccessibleRole> 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<Integer,AccessibleContext> windowHandleToContextMap = new ConcurrentHashMap<>();
+
+ // hash table of AccessibleContext to native window handle mappings
+ static private ConcurrentHashMap<AccessibleContext,Integer> 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<AccessibleContext>() {
+ @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<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return a.getAccessibleContext();
+ }
+ }, a);
+ windowHandleToContextMap.remove(nativeWindowHandle);
+ contextToWindowHandleMap.remove(ac);
+ }
+
+ // vector of native window handlers
+ private static Vector<NativeWindowHandler> 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<AccessibleContext>() {
+ @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<AccessibleContext>() {
+ @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<AccessibleContext>() {
+ @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<AccessibleContext>() {
+ @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<AccessibleContext>() {
+ @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<AccessibleComponent>() {
+ @Override
+ public AccessibleComponent call() throws Exception {
+ return parent.getAccessibleComponent();
+ }
+ }, parent);
+ if (acmp!=null) {
+ final Point loc = InvocationUtils.invokeAndWait(new Callable<Point>() {
+ @Override
+ public Point call() throws Exception {
+ return acmp.getLocation();
+ }
+ }, parent);
+ final Accessible a = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
+ @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<AccessibleContext>() {
+ @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<AccessibleContext>() {
+ @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<AccessibleContext>() {
+ @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<String>() {
+ @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<String>() {
+ @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<String>() {
+ @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<AccessibleRole>() {
+ @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<AccessibleRole>() {
+ @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<AccessibleText>() {
+ @Override
+ public AccessibleText call() throws Exception {
+ return ac.getAccessibleText();
+ }
+ }, ac);
+ if (null != at) {
+ int charCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @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<AccessibleIcon[]>() {
+ @Override
+ public AccessibleIcon[] call() throws Exception {
+ return ac.getAccessibleIcon();
+ }
+ }, ac);
+ if ( (null != ai) && (ai.length > 0) ) {
+ String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @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<AccessibleRole>() {
+ @Override
+ public AccessibleRole call() throws Exception {
+ return parentContextInnerTemp.getAccessibleRole();
+ }
+ }, ac);
+ if ( AccessibleRole.TABLE == parentRole ) {
+ int indexInParent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @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<AccessibleIcon[]>() {
+ @Override
+ public AccessibleIcon[] call() throws Exception {
+ return acTableCell.getAccessibleIcon();
+ }
+ }, ac);
+ if ( (null != aiRet) && (aiRet.length > 0) ) {
+ String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
+ 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<AccessibleIcon []>() {
+ public AccessibleIcon [] call() {
+ return ac.getAccessibleIcon ();
+ }
+ }, ac);
+ if ( (null != ai) && (ai.length > 0) ) {
+ String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
+ 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<AccessibleValue>() {
+ @Override
+ public AccessibleValue call() throws Exception {
+ return ac.getAccessibleValue();
+ }
+ }, ac);
+ if ( null != av ) {
+ nameString = null;
+ Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
+ @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<String>() {
+ @Override
+ public String call() throws Exception {
+ return parentContextOuterTemp.getAccessibleName();
+ }
+ }, ac);
+ String parentDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @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<AccessibleRole>() {
+ @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<AccessibleRelationSet>() {
+ @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<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return tempContext.getAccessibleIndexInParent();
+ }
+ }, ac);
+ if ( null != parentContext ) {
+ final AccessibleContext parentContextInnerTemp = parentContext;
+ testIndexMax = InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @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<Accessible>() {
+ @Override
+ public Accessible call() throws Exception {
+ return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
+ }
+ }, ac);
+ if ( null != child ) {
+ final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return child.getAccessibleContext();
+ }
+ }, ac);
+ if ( null != childContext ) {
+ AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
+ @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<String>() {
+ 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<String>() {
+ 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<String>() {
+ 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<String>() {
+ 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<Accessible>() {
+ @Override
+ public Accessible call() throws Exception {
+ return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
+ }
+ }, ac);
+ if ( null != child ) {
+ final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return child.getAccessibleContext();
+ }
+ }, ac);
+ if ( null != childContext ) {
+ AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
+ @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<String>() {
+ 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<String>() {
+ 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<String>() {
+ 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<String>() {
+ 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<Accessible>() {
+ @Override
+ public Accessible call() throws Exception {
+ return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
+ }
+ }, ac);
+ if ( null != child ) {
+ final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return child.getAccessibleContext();
+ }
+ }, ac);
+ if ( null != childContext ) {
+ AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
+ @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<String>() {
+ 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<String>() {
+ 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<Accessible>() {
+ @Override
+ public Accessible call() throws Exception {
+ return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
+ }
+ }, ac);
+ if ( null != child ) {
+ final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return child.getAccessibleContext();
+ }
+ }, ac);
+ if ( null != childContext ) {
+ AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
+ @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<String>() {
+ 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<String>() {
+ 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<String>() {
+ @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<AccessibleRole>() {
+ @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<AccessibleStateSet>() {
+ @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<AccessibleStateSet>() {
+ @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<AccessibleContext>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<JTable>() {
+ @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<AccessibleContext>() {
+ @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<AccessibleContext>() {
+ @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<Rectangle>() {
+ @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<AccessibleAction>() {
+ @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<AccessibleSelection>() {
+ @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<AccessibleText>() {
+ @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<AccessibleValue>() {
+ @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<Rectangle>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<String>() {
+ @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<String>() {
+ @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<String>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<String>() {
+ @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<AttributeSet>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<String>() {
+ @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<AttributeSet>() {
+ @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<Rectangle>() {
+ @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<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return comp.getAccessibleContext();
+ }
+ }, comp);
+ if (ac != null) {
+ attrString += "; Accessible Component = " + InvocationUtils.invokeAndWait(new Callable<String>() {
+ @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<Number>() {
+ @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<Number>() {
+ @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<Number>() {
+ @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<Object>() {
+ @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<Object>() {
+ @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<AccessibleContext>() {
+ @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<Integer>() {
+ @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<Boolean>() {
+ @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<Object>() {
+ @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<Object>() {
+ @Override
+ public Object call() throws Exception {
+ if (ac != null) {
+ AccessibleSelection as = ac.getAccessibleSelection();
+ if (as != null) {
+ as.selectAllAccessibleSelection();
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ // ======== AccessibleTable ========
+
+ ConcurrentHashMap<AccessibleTable,AccessibleContext> 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<AccessibleTable>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<AccessibleContext>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Boolean>() {
+ @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<AccessibleTable>() {
+ @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<AccessibleTable>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<AccessibleContext>() {
+ @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<AccessibleContext>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Boolean>() {
+ @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<Boolean>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<AccessibleRelationSet>() {
+ @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<String>() {
+ @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<Integer>() {
+ @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<AccessibleContext>() {
+ @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<AccessibleHypertext, AccessibleContext> hyperTextContextMap = new WeakHashMap<>();
+ private Map<AccessibleHyperlink, AccessibleContext> 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<AccessibleHypertext>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return hypertext.getLinkCount();
+ }
+ }, ac) ) {
+ return null;
+ }
+ AccessibleHyperlink acLink = InvocationUtils.invokeAndWait(new Callable<AccessibleHyperlink>() {
+ @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<String>() {
+ @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<String>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Boolean>() {
+ @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<KeyStroke>() {
+ @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<KeyStroke>() {
+ @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<Integer>() {
+ @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<String>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<Integer>() {
+ @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<String>() {
+ @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<Boolean>() {
+ @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<Boolean>() {
+ @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<AccessibleContext>() {
+ @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<AccessibleContext>() {
+ @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<Integer>() {
+ @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<Accessible>() {
+ @Override
+ public Accessible call() throws Exception {
+ return ac.getAccessibleParent();
+ }
+ }, ac);
+
+ if (parent != null) {
+ Accessible child = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
+ @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<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return new AccessibleJTreeNode(tree,
+ tree.getSelectionPath(),
+ null);
+ }
+ }, child);
+ }
+ }
+
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @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<String>() {
+ @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<Boolean>() {
+ @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<Boolean>() {
+ @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<Boolean>() {
+ @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<Integer>() {
+ @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<AccessibleContext>() {
+ @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<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING);
+ }
+ }, ac))
+ ) {
+ continue;
+ }
+ _visibleChildrenCount++;
+
+ if (InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @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<String>() {
+ @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<Integer>() {
+ @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<AccessibleContext>() {
+ @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<Boolean>() {
+ @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<Integer>() {
+ @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<Object,Reference> 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
+ * <code>JTree</code> 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 <code>Accessible</code> child, if one exists,
+ * contained at the local coordinate <code>Point</code>.
+ * Otherwise returns <code>null</code>.
+ *
+ * @param p point in local coordinates of this
+ * <code>Accessible</code>
+ * @return the <code>Accessible</code>, if it exists,
+ * at the specified location; else <code>null</code>
+ */
+ 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 <T> type parameter for the result value
+ *
+ * @return the result of the {@code Callable} execution
+ */
+ public static <T> T invokeAndWait(final Callable<T> 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 <T> type parameter for the result value
+ *
+ * @return the result of the {@code Callable} execution
+ */
+ public static <T> T invokeAndWait(final Callable<T> 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 <T> type parameter for the result value
+ *
+ * @return the result of the {@code Callable} execution
+ */
+ public static <T> T invokeAndWait(final Callable<T> 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> T invokeAndWait(final Callable<T> callable,
+ final AppContext targetAppContext) {
+ final CallableWrapper<T> wrapper = new CallableWrapper<T>(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 <T> void updateAppContextMap(final T accessibleContext,
+ final AppContext targetContext) {
+ if (accessibleContext instanceof AccessibleContext) {
+ registerAccessibleContext((AccessibleContext)accessibleContext, targetContext);
+ }
+ }
+
+ private static class CallableWrapper<T> implements Runnable {
+ private final Callable<T> callable;
+ private volatile T object;
+ private Exception e;
+
+ CallableWrapper(final Callable<T> 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;
+ }
+ }
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRelation.java b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRelation.java
new file mode 100644
index 0000000..93a5e31
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRelation.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+package com.sun.java.accessibility.extensions;
+
+import javax.accessibility.*;
+
+/**
+ * <P>Class AccessibleExtendedRelation contains extensions to the class
+ * AccessibleRelation that are currently not in a public API.
+ *
+ * <P>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.
+ * <p>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.
+ * <p>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);
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRelationConstants.java b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRelationConstants.java
new file mode 100644
index 0000000..28dd52c
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRelationConstants.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+package com.sun.java.accessibility.extensions;
+
+import javax.accessibility.*;
+
+/**
+ * <P>Class AccessibleExtendedRelation contains extensions to the class
+ * AccessibleRelation that are currently not in a public API.
+ *
+ * <P>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.
+ * <p>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.
+ * <p>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). <p> 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);
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRole.java b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRole.java
new file mode 100644
index 0000000..207eefb
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRole.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+package com.sun.java.accessibility.extensions;
+
+import javax.accessibility.*;
+
+/**
+ * <P>Class AccessibleExtendedRole contains extensions to the class
+ * AccessibleRole that are currently not in a public API.
+ *
+ * <P>Class AccessibleRole determines the role of a component. The role
+ * of a component describes its generic function. (E.G.,
+ * "push button," "table," or "list.")
+ * <p>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);
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRoleConstants.java b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRoleConstants.java
new file mode 100644
index 0000000..708c013
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedRoleConstants.java
@@ -0,0 +1,75 @@
+/*
+ * 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.extensions;
+
+import javax.accessibility.*;
+
+/**
+ * <P>Class AccessibleExtendedRole contains extensions to the class
+ * AccessibleRole that are currently not in a public API.
+ *
+ * <P>Class AccessibleRole determines the role of a component. The role
+ * of a component describes its generic function. (E.G.,
+ * "push button," "table," or "list.")
+ * <p>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);
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedState.java b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedState.java
new file mode 100644
index 0000000..96838f2
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedState.java
@@ -0,0 +1,51 @@
+/*
+ * 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.extensions;
+
+import javax.accessibility.*;
+
+/**
+ * <P>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.
+ * <p>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.
+ * <p>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);
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedStateConstants.java b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedStateConstants.java
new file mode 100644
index 0000000..6737cc4
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/extensions/AccessibleExtendedStateConstants.java
@@ -0,0 +1,57 @@
+/*
+ * 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.extensions;
+
+import javax.accessibility.*;
+
+/**
+ * <P>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.
+ * <p>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.
+ * <p>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);
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/legacy/AccessBridgeLoader.java b/src/windows/classes/com/sun/java/accessibility/legacy/AccessBridgeLoader.java
new file mode 100644
index 0000000..273c046
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/legacy/AccessBridgeLoader.java
@@ -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<Object>() {
+ 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<Object>() {
+ public Object run() {
+ System.loadLibrary("JAWT");
+ System.loadLibrary("JAWTAccessBridge");
+ return null;
+ }
+ }, null, new RuntimePermission("loadLibrary.JAWT"),
+ new RuntimePermission("loadLibrary.JAWTAccessBridge")
+ );
+ }
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/AWTEventMonitor.java b/src/windows/classes/com/sun/java/accessibility/util/AWTEventMonitor.java
new file mode 100644
index 0000000..b2a37e2
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/AWTEventMonitor.java
@@ -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;
+
+/**
+ * <P>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).
+ * <p>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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);
+ }
+ }
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/AccessibilityEventMonitor.java b/src/windows/classes/com/sun/java/accessibility/util/AccessibilityEventMonitor.java
new file mode 100644
index 0000000..4719e7c
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/AccessibilityEventMonitor.java
@@ -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.*;
+
+/**
+ * <P>{@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.
+ * <p>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.
+ * <P>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.
+ * <p>
+ * 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);
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/AccessibilityListenerList.java b/src/windows/classes/com/sun/java/accessibility/util/AccessibilityListenerList.java
new file mode 100644
index 0000000..c73424d
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/AccessibilityListenerList.java
@@ -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.*;
+
+/**
+ * <P>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.
+ * <p>
+ * 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;
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/EventID.java b/src/windows/classes/com/sun/java/accessibility/util/EventID.java
new file mode 100644
index 0000000..bbd08f5
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/EventID.java
@@ -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;
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/EventQueueMonitor.java b/src/windows/classes/com/sun/java/accessibility/util/EventQueueMonitor.java
new file mode 100644
index 0000000..3c2a163
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/EventQueueMonitor.java
@@ -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;
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/GUIInitializedListener.java b/src/windows/classes/com/sun/java/accessibility/util/GUIInitializedListener.java
new file mode 100644
index 0000000..9a4474d
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/GUIInitializedListener.java
@@ -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();
+
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/GUIInitializedMulticaster.java b/src/windows/classes/com/sun/java/accessibility/util/GUIInitializedMulticaster.java
new file mode 100644
index 0000000..2b9e4cc
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/GUIInitializedMulticaster.java
@@ -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
+ }
+ }
+
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/SwingEventMonitor.java b/src/windows/classes/com/sun/java/accessibility/util/SwingEventMonitor.java
new file mode 100644
index 0000000..133ef31
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/SwingEventMonitor.java
@@ -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.*;
+
+
+/**
+ * <P>{@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).
+ * <p>This class depends upon {@link EventQueueMonitor}, which provides the base
+ * level support for capturing the top-level containers as they are created.
+ * <p>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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.
+ * <P>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);
+ }
+ }
+ }
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/TopLevelWindowListener.java b/src/windows/classes/com/sun/java/accessibility/util/TopLevelWindowListener.java
new file mode 100644
index 0000000..94d0330
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/TopLevelWindowListener.java
@@ -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);
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/TopLevelWindowMulticaster.java b/src/windows/classes/com/sun/java/accessibility/util/TopLevelWindowMulticaster.java
new file mode 100644
index 0000000..eea259a
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/TopLevelWindowMulticaster.java
@@ -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
+ }
+ }
+
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/Translator.java b/src/windows/classes/com/sun/java/accessibility/util/Translator.java
new file mode 100644
index 0000000..935943e
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/Translator.java
@@ -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.*;
+
+/**
+ * <p>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.
+ *
+ * <p>An example of how an assistive technology might use the {@code Translator}
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>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);
+ }
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/java/awt/ButtonTranslator.java b/src/windows/classes/com/sun/java/accessibility/util/java/awt/ButtonTranslator.java
new file mode 100644
index 0000000..8abe467
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/java/awt/ButtonTranslator.java
@@ -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.*;
+
+/**
+ * <p>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.
+ *
+ * <p>An example of how an assistive technology might use the Translator
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>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;
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/java/awt/CheckboxTranslator.java b/src/windows/classes/com/sun/java/accessibility/util/java/awt/CheckboxTranslator.java
new file mode 100644
index 0000000..8cb6035
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/java/awt/CheckboxTranslator.java
@@ -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.*;
+
+/**
+ * <p>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.
+ *
+ * <p>An example of how an assistive technology might use the Translator
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>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;
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/java/awt/ChoiceTranslator.java b/src/windows/classes/com/sun/java/accessibility/util/java/awt/ChoiceTranslator.java
new file mode 100644
index 0000000..f56becb
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/java/awt/ChoiceTranslator.java
@@ -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.*;
+
+/**
+ * <p>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.
+ *
+ * <p>An example of how an assistive technology might use the Translator
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>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;
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/java/awt/LabelTranslator.java b/src/windows/classes/com/sun/java/accessibility/util/java/awt/LabelTranslator.java
new file mode 100644
index 0000000..acdc9b1
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/java/awt/LabelTranslator.java
@@ -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.*;
+
+/**
+ * <p>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.
+ *
+ * <p>An example of how an assistive technology might use the Translator
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>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;
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/java/awt/ListTranslator.java b/src/windows/classes/com/sun/java/accessibility/util/java/awt/ListTranslator.java
new file mode 100644
index 0000000..a129c33
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/java/awt/ListTranslator.java
@@ -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.*;
+
+/**
+ * <p>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.
+ *
+ * <p>An example of how an assistive technology might use the Translator
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>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;
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/java/awt/TextComponentTranslator.java b/src/windows/classes/com/sun/java/accessibility/util/java/awt/TextComponentTranslator.java
new file mode 100644
index 0000000..37d921d
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/java/awt/TextComponentTranslator.java
@@ -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.*;
+
+/**
+ * <p>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.
+ *
+ * <p>An example of how an assistive technology might use the Translator
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>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;
+ }
+}
diff --git a/src/windows/classes/com/sun/java/accessibility/util/package-info.java b/src/windows/classes/com/sun/java/accessibility/util/package-info.java
new file mode 100644
index 0000000..f3b0a62
--- /dev/null
+++ b/src/windows/classes/com/sun/java/accessibility/util/package-info.java
@@ -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.
+ *
+ * <p>The class {@code AccessibilityEventMonitor} implements a PropertyChange
+ * listener on every UI object that implements interface {@code Accessible} in the Java
+ * Virtual Machine.
+ *
+ * <p> The class {@code AWTEventMonitor} implements a suite of listeners that are
+ * conditionally installed on every AWT component instance in the Java Virtual Machine.
+ *
+ * <p>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).
+ *
+ * <p>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.
+ *
+ * <p>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.
+ *
+ * <p>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.
+ *
+ * <p>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;
diff --git a/src/windows/classes/java/lang/ProcessImpl.java b/src/windows/classes/java/lang/ProcessImpl.java
index b288dbd..21b4386 100644
--- a/src/windows/classes/java/lang/ProcessImpl.java
+++ b/src/windows/classes/java/lang/ProcessImpl.java
@@ -461,11 +461,21 @@
if (getExitCodeProcess(handle) != STILL_ACTIVE) return true;
if (timeout <= 0) return false;
- long msTimeout = unit.toMillis(timeout);
+ long remainingNanos = unit.toNanos(timeout);
+ long deadline = System.nanoTime() + remainingNanos ;
- waitForTimeoutInterruptibly(handle, msTimeout);
- if (Thread.interrupted())
- throw new InterruptedException();
+ do {
+ // Round up to next millisecond
+ long msTimeout = TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L);
+ waitForTimeoutInterruptibly(handle, msTimeout);
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ if (getExitCodeProcess(handle) != STILL_ACTIVE) {
+ return true;
+ }
+ remainingNanos = deadline - System.nanoTime();
+ } while (remainingNanos > 0);
+
return (getExitCodeProcess(handle) != STILL_ACTIVE);
}
diff --git a/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java b/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java
index 25d45dc..87bd76e 100644
--- a/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java
+++ b/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -51,6 +51,11 @@
private static int pScale = 0;
private static final int MAX_BAND_SIZE = (1024*30);
+ /**
+ * This flag is set to {@code true} if this embedded frame is hosted by Internet Explorer.
+ */
+ private boolean isEmbeddedInIE = false;
+
private static String printScale = AccessController.doPrivileged(
new GetPropertyAction("sun.java2d.print.pluginscalefactor"));
@@ -243,6 +248,14 @@
}
}
+ @SuppressWarnings("deprecation")
+ public boolean requestFocusToEmbedder() {
+ if (isEmbeddedInIE) {
+ return ((WEmbeddedFramePeer) getPeer()).requestFocusToEmbedder();
+ }
+ return false;
+ }
+
public void registerAccelerator(AWTKeyStroke stroke) {}
public void unregisterAccelerator(AWTKeyStroke stroke) {}
diff --git a/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java b/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java
index 930b447..4cc3a4d 100644
--- a/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java
+++ b/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -78,4 +78,11 @@
// false on other systems.
return !Win32GraphicsEnvironment.isDWMCompositionEnabled();
}
+
+ /**
+ * Sets the focus to plugin control window, the parent of embedded frame.
+ * Eventually, it will synthesizeWindowActivation to activate the embedded frame,
+ * if plugin control window gets the focus.
+ */
+ public native boolean requestFocusToEmbedder();
}
diff --git a/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java b/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
index ccab64d..f2b962e 100644
--- a/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
+++ b/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
@@ -25,15 +25,16 @@
package sun.nio.ch;
-import java.io.*;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.security.PrivilegedAction;
import sun.misc.SharedSecrets;
import sun.misc.JavaIOFileDescriptorAccess;
-class FileDispatcherImpl extends FileDispatcher
-{
- static {
- IOUtil.load();
- }
+class FileDispatcherImpl extends FileDispatcher {
+
+ // set to true if fast file transmission (TransmitFile) is enabled
+ private static final boolean fastFileTransfer;
/**
* Indicates if the dispatcher should first advance the file position
@@ -120,6 +121,36 @@
return result;
}
+ boolean canTransferToDirectly(java.nio.channels.SelectableChannel sc) {
+ return fastFileTransfer && sc.isBlocking();
+ }
+
+ boolean transferToDirectlyNeedsPositionLock() {
+ return true;
+ }
+
+ static boolean isFastFileTransferRequested() {
+ String fileTransferProp = java.security.AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ @Override
+ public String run() {
+ return System.getProperty("jdk.nio.enableFastFileTransfer");
+ }
+ });
+ boolean enable;
+ if ("".equals(fileTransferProp)) {
+ enable = true;
+ } else {
+ enable = Boolean.parseBoolean(fileTransferProp);
+ }
+ return enable;
+ }
+
+ static {
+ IOUtil.load();
+ fastFileTransfer = isFastFileTransferRequested();
+ }
+
//-- Native methods
static native int read0(FileDescriptor fd, long address, int len)
diff --git a/src/windows/native/java/io/FileDescriptor_md.c b/src/windows/native/java/io/FileDescriptor_md.c
index 221bf1d..db04cd4 100644
--- a/src/windows/native/java/io/FileDescriptor_md.c
+++ b/src/windows/native/java/io/FileDescriptor_md.c
@@ -48,8 +48,8 @@
JNIEXPORT void JNICALL
Java_java_io_FileDescriptor_initIDs(JNIEnv *env, jclass fdClass) {
- IO_fd_fdID = (*env)->GetFieldID(env, fdClass, "fd", "I");
- IO_handle_fdID = (*env)->GetFieldID(env, fdClass, "handle", "J");
+ CHECK_NULL(IO_fd_fdID = (*env)->GetFieldID(env, fdClass, "fd", "I"));
+ CHECK_NULL(IO_handle_fdID = (*env)->GetFieldID(env, fdClass, "handle", "J"));
}
JNIEXPORT jlong JNICALL
diff --git a/src/windows/native/java/io/WinNTFileSystem_md.c b/src/windows/native/java/io/WinNTFileSystem_md.c
index 2a0d477..d86183e 100644
--- a/src/windows/native/java/io/WinNTFileSystem_md.c
+++ b/src/windows/native/java/io/WinNTFileSystem_md.c
@@ -59,10 +59,12 @@
Java_java_io_WinNTFileSystem_initIDs(JNIEnv *env, jclass cls)
{
HMODULE handle;
- jclass fileClass = (*env)->FindClass(env, "java/io/File");
- if (!fileClass) return;
- ids.path =
- (*env)->GetFieldID(env, fileClass, "path", "Ljava/lang/String;");
+ jclass fileClass;
+
+ fileClass = (*env)->FindClass(env, "java/io/File");
+ CHECK_NULL(fileClass);
+ ids.path = (*env)->GetFieldID(env, fileClass, "path", "Ljava/lang/String;");
+ CHECK_NULL(ids.path);
// GetFinalPathNameByHandle requires Windows Vista or newer
if (GetModuleHandleExW((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
@@ -247,8 +249,8 @@
WCHAR canonicalPath[MAX_PATH_LENGTH];
WITH_UNICODE_STRING(env, pathname, path) {
- /*we estimate the max length of memory needed as
- "currentDir. length + pathname.length"
+ /* we estimate the max length of memory needed as
+ "currentDir. length + pathname.length"
*/
int len = (int)wcslen(path);
len += currentDirLength(path, len);
@@ -262,12 +264,11 @@
} else {
JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");
}
- } else
- if (wcanonicalize(path, canonicalPath, MAX_PATH_LENGTH) >= 0) {
+ } else if (wcanonicalize(path, canonicalPath, MAX_PATH_LENGTH) >= 0) {
rv = (*env)->NewString(env, canonicalPath, (jsize)wcslen(canonicalPath));
}
} END_UNICODE_STRING(env, path);
- if (rv == NULL) {
+ if (rv == NULL && !(*env)->ExceptionCheck(env)) {
JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
}
return rv;
@@ -296,15 +297,14 @@
} else {
JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");
}
- } else
- if (wcanonicalizeWithPrefix(canonicalPrefix,
- pathWithCanonicalPrefix,
- canonicalPath, MAX_PATH_LENGTH) >= 0) {
+ } else if (wcanonicalizeWithPrefix(canonicalPrefix,
+ pathWithCanonicalPrefix,
+ canonicalPath, MAX_PATH_LENGTH) >= 0) {
rv = (*env)->NewString(env, canonicalPath, (jsize)wcslen(canonicalPath));
}
} END_UNICODE_STRING(env, pathWithCanonicalPrefix);
} END_UNICODE_STRING(env, canonicalPrefix);
- if (rv == NULL) {
+ if (rv == NULL && !(*env)->ExceptionCheck(env)) {
JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
}
return rv;
@@ -624,8 +624,13 @@
jobjectArray rv, old;
DWORD fattr;
jstring name;
+ jclass str_class;
+ WCHAR *pathbuf;
- WCHAR *pathbuf = fileToNTPath(env, file, ids.path);
+ str_class = JNU_ClassString(env);
+ CHECK_NULL_RETURN(str_class, NULL);
+
+ pathbuf = fileToNTPath(env, file, ids.path);
if (pathbuf == NULL)
return NULL;
search_path = (WCHAR*)malloc(2*wcslen(pathbuf) + 6);
@@ -673,7 +678,7 @@
return NULL;
} else {
// No files found - return an empty array
- rv = (*env)->NewObjectArray(env, 0, JNU_ClassString(env), NULL);
+ rv = (*env)->NewObjectArray(env, 0, str_class, NULL);
return rv;
}
}
@@ -681,7 +686,7 @@
/* Allocate an initial String array */
len = 0;
maxlen = 16;
- rv = (*env)->NewObjectArray(env, maxlen, JNU_ClassString(env), NULL);
+ rv = (*env)->NewObjectArray(env, maxlen, str_class, NULL);
if (rv == NULL) // Couldn't allocate an array
return NULL;
/* Scan the directory */
@@ -695,10 +700,8 @@
return NULL; // error;
if (len == maxlen) {
old = rv;
- rv = (*env)->NewObjectArray(env, maxlen <<= 1,
- JNU_ClassString(env), NULL);
- if ( rv == NULL
- || JNU_CopyObjectArray(env, rv, old, len) < 0)
+ rv = (*env)->NewObjectArray(env, maxlen <<= 1, str_class, NULL);
+ if (rv == NULL || JNU_CopyObjectArray(env, rv, old, len) < 0)
return NULL; // error
(*env)->DeleteLocalRef(env, old);
}
@@ -713,7 +716,7 @@
/* Copy the final results into an appropriately-sized array */
old = rv;
- rv = (*env)->NewObjectArray(env, len, JNU_ClassString(env), NULL);
+ rv = (*env)->NewObjectArray(env, len, str_class, NULL);
if (rv == NULL)
return NULL; /* error */
if (JNU_CopyObjectArray(env, rv, old, len) < 0)
diff --git a/src/windows/native/java/lang/ProcessImpl_md.c b/src/windows/native/java/lang/ProcessImpl_md.c
index 922e5a5..3a013c1 100644
--- a/src/windows/native/java/lang/ProcessImpl_md.c
+++ b/src/windows/native/java/lang/ProcessImpl_md.c
@@ -272,14 +272,10 @@
FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE};
- {
- /* Extraction of current process standard IOE handles */
- DWORD idsIOE[3] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE};
- int i;
- for (i = 0; i < 3; ++i)
- /* Should not be closed by CloseHandle! */
- stdIOE[i] = GetStdHandle(idsIOE[i]);
- }
+ /* These three should not be closed by CloseHandle! */
+ stdIOE[0] = GetStdHandle(STD_INPUT_HANDLE);
+ stdIOE[1] = GetStdHandle(STD_OUTPUT_HANDLE);
+ stdIOE[2] = GetStdHandle(STD_ERROR_HANDLE);
prepareIOEHandleState(stdIOE, inherit);
{
@@ -308,11 +304,16 @@
if (success) {
PROCESS_INFORMATION pi;
- DWORD processFlag = CREATE_UNICODE_ENVIRONMENT;
+ DWORD processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
- /* Suppress popping-up of a console window for non-console applications */
- if (GetConsoleWindow() == NULL)
- processFlag |= CREATE_NO_WINDOW;
+ /* If the standard I/O is inherited, CREATE_NO_WINDOW must not be used. */
+ if (GetConsoleWindow() != NULL &&
+ (si.hStdInput == stdIOE[0] ||
+ si.hStdOutput == stdIOE[1] ||
+ si.hStdError == (redirectErrorStream ? stdIOE[1] : stdIOE[2])))
+ {
+ processFlag &= ~CREATE_NO_WINDOW;
+ }
si.dwFlags = STARTF_USESTDHANDLES;
if (!CreateProcessW(
diff --git a/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c b/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c
index 454e993..108f0de 100644
--- a/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c
+++ b/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c
@@ -462,7 +462,7 @@
*/
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketSetIntOption
(JNIEnv *env, jclass clazz, jint fd , jint cmd, jint value) {
- int level, opt;
+ int level = 0, opt = 0;
if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
@@ -482,7 +482,7 @@
*/
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketGetIntOption
(JNIEnv *env, jclass clazz, jint fd, jint cmd) {
- int level, opt, result=0;
+ int level = 0, opt = 0, result=0;
int result_len = sizeof(result);
if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
diff --git a/src/windows/native/java/net/DualStackPlainSocketImpl.c b/src/windows/native/java/net/DualStackPlainSocketImpl.c
index 1aef69d..604ea9f 100644
--- a/src/windows/native/java/net/DualStackPlainSocketImpl.c
+++ b/src/windows/native/java/net/DualStackPlainSocketImpl.c
@@ -294,6 +294,8 @@
return -1;
}
+ SetHandleInformation((HANDLE)(UINT_PTR)newfd, HANDLE_FLAG_INHERIT, 0);
+
ia = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
(*env)->SetObjectArrayElement(env, isaa, 0, isa);
@@ -367,8 +369,8 @@
JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_setIntOption
(JNIEnv *env, jclass clazz, jint fd, jint cmd, jint value) {
- int level, opt;
- struct linger linger;
+ int level = 0, opt = 0;
+ struct linger linger = {0, 0};
char *parg;
int arglen;
@@ -407,9 +409,9 @@
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_getIntOption
(JNIEnv *env, jclass clazz, jint fd, jint cmd) {
- int level, opt;
+ int level = 0, opt = 0;
int result=0;
- struct linger linger;
+ struct linger linger = {0, 0};
char *arg;
int arglen;
diff --git a/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c b/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c
index ed6efdf..6922d3d 100644
--- a/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c
+++ b/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c
@@ -335,6 +335,8 @@
struct sockaddr_in rmtaddr;
int addrlen = sizeof(rmtaddr);
+ memset((char *)&rmtaddr, 0, sizeof(rmtaddr));
+
/*
* A no-op if this OS doesn't support it.
*/
@@ -431,9 +433,11 @@
int ipv6_supported = ipv6_available();
SOCKETADDRESS lcladdr;
- int lcladdrlen;
+ int lcladdrlen = sizeof(lcladdr);
int address;
+ memset((char *)&lcladdr, 0, sizeof(lcladdr));
+
family = getInetAddress_family(env, addressObj);
if (family == IPv6 && !ipv6_supported) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
@@ -617,7 +621,7 @@
}
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- memset(&addr, 0, len);
+ memset((char *)&addr, 0, len);
connect(fd, (struct sockaddr *)&addr, len);
/*
@@ -625,7 +629,7 @@
* to disable ICMP port unreachable handling here.
*/
if (xp_or_later) {
- DWORD x1, x2; /* ignored result codes */
+ DWORD x1 = 0, x2 = 0; /* ignored result codes */
int t = FALSE;
WSAIoctl(fd,SIO_UDP_CONNRESET,&t,sizeof(t),&x1,sizeof(x1),&x2,0,0);
}
@@ -655,8 +659,9 @@
SOCKETADDRESS rmtaddr;
SOCKETADDRESS *addrp = &rmtaddr;
- int addrlen;
+ int addrlen = 0;
+ memset((char *)&rmtaddr, 0, sizeof(rmtaddr));
if (IS_NULL(packet)) {
JNU_ThrowNullPointerException(env, "null packet");
@@ -1444,7 +1449,7 @@
} else if (n < 0) {
NET_ThrowCurrent(env, "Datagram receive failed");
} else {
- int port;
+ int port = 0;
jobject packetAddress;
/*
@@ -1822,11 +1827,11 @@
jint opt,jobject value) {
int fd=-1, fd1=-1;
- int levelv4, levelv6, optnamev4, optnamev6, optlen;
+ int levelv4 = 0, levelv6 = 0, optnamev4 = 0, optnamev6 = 0, optlen = 0;
union {
int i;
char c;
- } optval;
+ } optval = { 0 };
int ipv6_supported = ipv6_available();
fd = getFD(env, this);
@@ -2193,7 +2198,7 @@
int level, optname, optlen;
union {
int i;
- } optval;
+ } optval = {0};
int ipv6_supported = ipv6_available();
fd = getFD(env, this);
@@ -2444,12 +2449,15 @@
struct ipv6_mreq mname6;
struct in_addr in;
- DWORD ifindex;
+ DWORD ifindex = 0;
int len, family;
int ipv6_supported = ipv6_available();
int cmd ;
+ memset((char *)&in, 0, sizeof(in));
+ memset((char *)&name, 0, sizeof(name));
+
if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
diff --git a/src/windows/native/java/net/TwoStacksPlainSocketImpl.c b/src/windows/native/java/net/TwoStacksPlainSocketImpl.c
index e7aa49b..899d5de 100644
--- a/src/windows/native/java/net/TwoStacksPlainSocketImpl.c
+++ b/src/windows/native/java/net/TwoStacksPlainSocketImpl.c
@@ -208,6 +208,7 @@
/* The result of the connection */
int connect_res;
+ memset((char *)&him, 0, sizeof(him));
if (!IS_NULL(fdObj)) {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
@@ -400,7 +401,7 @@
/* fdObj is the FileDescriptor field on this */
jobject fdObj, fd1Obj;
/* fd is an int field on fdObj */
- int fd, fd1, len;
+ int fd, fd1, len = 0;
int ipv6_supported = ipv6_available();
/* family is an int field of iaObj */
@@ -700,6 +701,7 @@
}
return;
}
+ SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, 0);
(*env)->SetIntField(env, socketFdObj, IO_fd_fdID, fd);
if (him.him.sa_family == AF_INET) {
@@ -843,12 +845,13 @@
jint cmd, jboolean on,
jobject value) {
int fd, fd1;
- int level, optname, optlen;
+ int level = 0, optname = 0, optlen = 0;
union {
int i;
struct linger ling;
} optval;
+ memset((char *)&optval, 0, sizeof(optval));
/*
* Get SOCKET and check that it hasn't been closed
*/
@@ -1009,17 +1012,17 @@
jint opt, jobject iaContainerObj) {
int fd, fd1;
- int level, optname, optlen;
+ int level = 0, optname = 0, optlen = 0;
union {
int i;
struct linger ling;
} optval;
-
/*
* Get SOCKET and check it hasn't been closed
*/
fd = getFD(env, this);
fd1 = getFD1(env, this);
+ memset((char *)&optval, 0, sizeof(optval));
if (fd < 0 && fd1 < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
@@ -1043,6 +1046,7 @@
jfieldID iaFieldID;
len = sizeof(him);
+ memset((char *)&him, 0, len);
if (fd == -1) {
/* must be an IPV6 only socket. Case where both sockets are != -1
diff --git a/src/windows/native/java/net/net_util_md.c b/src/windows/native/java/net/net_util_md.c
index 274d909..8a0f5c1 100644
--- a/src/windows/native/java/net/net_util_md.c
+++ b/src/windows/native/java/net/net_util_md.c
@@ -29,6 +29,9 @@
#include "net_util.h"
#include "jni.h"
+// Taken from mstcpip.h in Windows SDK 8.0 or newer.
+#define SIO_LOOPBACK_FAST_PATH _WSAIOW(IOC_VENDOR,16)
+
#ifndef IPTOS_TOS_MASK
#define IPTOS_TOS_MASK 0x1e
#endif
@@ -386,8 +389,8 @@
NET_SetSockOpt(int s, int level, int optname, const void *optval,
int optlen)
{
- int rv;
- int parg;
+ int rv = 0;
+ int parg = 0;
int plen = sizeof(parg);
if (level == IPPROTO_IP && optname == IP_TOS) {
@@ -478,7 +481,7 @@
* Sets SO_ECLUSIVEADDRUSE if SO_REUSEADDR is not already set.
*/
void setExclusiveBind(int fd) {
- int parg;
+ int parg = 0;
int plen = sizeof(parg);
int rv = 0;
rv = NET_GetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&parg, &plen);
@@ -499,7 +502,7 @@
JNIEXPORT int JNICALL
NET_Bind(int s, struct sockaddr *him, int len)
{
- int rv;
+ int rv = 0;
rv = bind(s, him, len);
if (rv == SOCKET_ERROR) {
@@ -529,8 +532,8 @@
JNIEXPORT int JNICALL
NET_SocketClose(int fd) {
- struct linger l;
- int ret;
+ struct linger l = {0, 0};
+ int ret = 0;
int len = sizeof (l);
if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) {
if (l.l_onoff == 0) {
@@ -844,6 +847,25 @@
}
}
+/**
+ * Enables SIO_LOOPBACK_FAST_PATH
+ */
+JNIEXPORT jint JNICALL
+NET_EnableFastTcpLoopback(int fd) {
+ int enabled = 1;
+ DWORD result_byte_count = -1;
+ int result = WSAIoctl(fd,
+ SIO_LOOPBACK_FAST_PATH,
+ &enabled,
+ sizeof(enabled),
+ NULL,
+ 0,
+ &result_byte_count,
+ NULL,
+ NULL);
+ return result == SOCKET_ERROR ? WSAGetLastError() : 0;
+}
+
/* If address types is IPv6, then IPv6 must be available. Otherwise
* no address can be generated. In the case of an IPv4 Inetaddress this
* method will return an IPv4 mapped address where IPv6 is available and
diff --git a/src/windows/native/java/util/TimeZone_md.c b/src/windows/native/java/util/TimeZone_md.c
index 7cb23e0..cb5f17c 100644
--- a/src/windows/native/java/util/TimeZone_md.c
+++ b/src/windows/native/java/util/TimeZone_md.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include "jvm.h"
#include "TimeZone_md.h"
+#include "jdk_util.h"
#define VALUE_UNKNOWN 0
#define VALUE_KEY 1
@@ -49,6 +50,20 @@
SYSTEMTIME dstDate;
} TziValue;
+#if _WIN32_WINNT < 0x0600 /* < _WIN32_WINNT_VISTA */
+typedef struct _TIME_DYNAMIC_ZONE_INFORMATION {
+ LONG Bias;
+ WCHAR StandardName[32];
+ SYSTEMTIME StandardDate;
+ LONG StandardBias;
+ WCHAR DaylightName[32];
+ SYSTEMTIME DaylightDate;
+ LONG DaylightBias;
+ WCHAR TimeZoneKeyName[128];
+ BOOLEAN DynamicDaylightTimeDisabled;
+} DYNAMIC_TIME_ZONE_INFORMATION, *PDYNAMIC_TIME_ZONE_INFORMATION;
+#endif
+
/*
* Registry key names
*/
@@ -143,6 +158,33 @@
}
/*
+ * Use NO_DYNAMIC_TIME_ZONE_INFO as the return value indicating that no
+ * dynamic time zone information is available.
+ */
+#define NO_DYNAMIC_TIME_ZONE_INFO (-128)
+
+static int getDynamicTimeZoneInfo(PDYNAMIC_TIME_ZONE_INFORMATION pdtzi) {
+ DWORD timeType = NO_DYNAMIC_TIME_ZONE_INFO;
+ HMODULE dllHandle;
+
+ /*
+ * Dynamically load the dll to call GetDynamicTimeZoneInformation.
+ */
+ dllHandle = JDK_LoadSystemLibrary("Kernel32.dll");
+ if (dllHandle != NULL) {
+ typedef DWORD (WINAPI *GetDynamicTimezoneInfoType)(PDYNAMIC_TIME_ZONE_INFORMATION);
+ GetDynamicTimezoneInfoType getDynamicTimeZoneInfoFunc =
+ (GetDynamicTimezoneInfoType) GetProcAddress(dllHandle,
+ "GetDynamicTimeZoneInformation");
+
+ if (getDynamicTimeZoneInfo != NULL) {
+ timeType = getDynamicTimeZoneInfoFunc(pdtzi);
+ }
+ }
+ return timeType;
+}
+
+/*
* Gets the current time zone entry in the "Time Zones" registry.
*/
static int getWinTimeZone(char *winZoneName, char *winMapID)
@@ -161,23 +203,96 @@
WCHAR *stdNamePtr = tzi.StandardName;
DWORD valueSize;
DWORD timeType;
- int isVista;
+ int isVistaOrLater;
/*
- * Get the current time zone setting of the platform.
+ * Determine if this is a Vista or later.
+ */
+ ver.dwOSVersionInfoSize = sizeof(ver);
+ GetVersionEx(&ver);
+ isVistaOrLater = (ver.dwMajorVersion >= 6);
+
+ if (isVistaOrLater) {
+ DYNAMIC_TIME_ZONE_INFORMATION dtzi;
+ DWORD bufSize;
+ DWORD val;
+
+ /*
+ * Get the dynamic time zone information, if available, so that time
+ * zone redirection can be supported. (see JDK-7044727)
+ */
+ timeType = getDynamicTimeZoneInfo(&dtzi);
+ if (timeType == TIME_ZONE_ID_INVALID) {
+ goto err;
+ }
+
+ if (timeType != NO_DYNAMIC_TIME_ZONE_INFO) {
+ /*
+ * Make sure TimeZoneKeyName is available from the API call. If
+ * DynamicDaylightTime is disabled, return a custom time zone name
+ * based on the GMT offset. Otherwise, return the TimeZoneKeyName
+ * value.
+ */
+ if (dtzi.TimeZoneKeyName[0] != 0) {
+ if (dtzi.DynamicDaylightTimeDisabled) {
+ customZoneName(dtzi.Bias, winZoneName);
+ return VALUE_GMTOFFSET;
+ }
+ wcstombs(winZoneName, dtzi.TimeZoneKeyName, MAX_ZONE_CHAR);
+ return VALUE_KEY;
+ }
+
+ /*
+ * If TimeZoneKeyName is not available, check whether StandardName
+ * is available to fall back to the older API GetTimeZoneInformation.
+ * If not, directly read the value from registry keys.
+ */
+ if (dtzi.StandardName[0] == 0) {
+ ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0,
+ KEY_READ, (PHKEY)&hKey);
+ if (ret != ERROR_SUCCESS) {
+ goto err;
+ }
+
+ /*
+ * Determine if auto-daylight time adjustment is turned off.
+ */
+ bufSize = sizeof(val);
+ ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled", NULL,
+ &valueType, (LPBYTE) &val, &bufSize);
+ if (ret != ERROR_SUCCESS) {
+ goto err;
+ }
+ /*
+ * Return a custom time zone name if auto-daylight time
+ * adjustment is disabled.
+ */
+ if (val == 1) {
+ customZoneName(dtzi.Bias, winZoneName);
+ (void) RegCloseKey(hKey);
+ return VALUE_GMTOFFSET;
+ }
+
+ bufSize = MAX_ZONE_CHAR;
+ ret = RegQueryValueExA(hKey, "TimeZoneKeyName",NULL,
+ &valueType, (LPBYTE)winZoneName, &bufSize);
+ if (ret != ERROR_SUCCESS) {
+ goto err;
+ }
+ (void) RegCloseKey(hKey);
+ return VALUE_KEY;
+ }
+ }
+ }
+
+ /*
+ * Fall back to GetTimeZoneInformation
*/
timeType = GetTimeZoneInformation(&tzi);
if (timeType == TIME_ZONE_ID_INVALID) {
goto err;
}
- /*
- * Determine if this is an NT system.
- */
- ver.dwOSVersionInfoSize = sizeof(ver);
- GetVersionEx(&ver);
- isVista = ver.dwMajorVersion >= 6;
-
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0,
KEY_READ, (PHKEY)&hKey);
if (ret == ERROR_SUCCESS) {
@@ -187,23 +302,23 @@
/*
* Determine if auto-daylight time adjustment is turned off.
*/
- valueType = 0;
bufSize = sizeof(val);
- ret = RegQueryValueExA(hKey, "DisableAutoDaylightTimeSet",
- NULL, &valueType, (LPBYTE) &val, &bufSize);
- /*
- * Vista uses the different key name.
- */
+ ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled", NULL,
+ &valueType, (LPBYTE) &val, &bufSize);
if (ret != ERROR_SUCCESS) {
- bufSize = sizeof(val);
- ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled",
- NULL, &valueType, (LPBYTE) &val, &bufSize);
+ /*
+ * Try the old key name.
+ */
+ bufSize = sizeof(val);
+ ret = RegQueryValueExA(hKey, "DisableAutoDaylightTimeSet", NULL,
+ &valueType, (LPBYTE) &val, &bufSize);
}
if (ret == ERROR_SUCCESS) {
- int daylightSavingsUpdateDisabledOther = val == 1 && tzi.DaylightDate.wMonth != 0;
- int daylightSavingsUpdateDisabledVista = val == 1;
- int daylightSavingsUpdateDisabled = isVista ? daylightSavingsUpdateDisabledVista : daylightSavingsUpdateDisabledOther;
+ int daylightSavingsUpdateDisabledOther = (val == 1 && tzi.DaylightDate.wMonth != 0);
+ int daylightSavingsUpdateDisabledVista = (val == 1);
+ int daylightSavingsUpdateDisabled
+ = (isVistaOrLater ? daylightSavingsUpdateDisabledVista : daylightSavingsUpdateDisabledOther);
if (daylightSavingsUpdateDisabled) {
(void) RegCloseKey(hKey);
@@ -213,28 +328,12 @@
}
/*
- * Vista has the key for the current "Time Zones" entry.
- */
- if (isVista) {
- valueType = 0;
- bufSize = MAX_ZONE_CHAR;
- ret = RegQueryValueExA(hKey, "TimeZoneKeyName", NULL,
- &valueType, (LPBYTE) winZoneName, &bufSize);
- if (ret != ERROR_SUCCESS) {
- goto err;
- }
- (void) RegCloseKey(hKey);
- return VALUE_KEY;
- }
-
- /*
* Win32 problem: If the length of the standard time name is equal
* to (or probably longer than) 32 in the registry,
* GetTimeZoneInformation() on NT returns a null string as its
* standard time name. We need to work around this problem by
* getting the same information from the TimeZoneInformation
- * registry. The function on Win98 seems to return its key name.
- * We can't do anything in that case.
+ * registry.
*/
if (tzi.StandardName[0] == 0) {
bufSize = sizeof(stdNameInReg);
@@ -510,18 +609,49 @@
} else {
std_timezone = matchJavaTZ(java_home_dir, result,
winZoneName, winMapID);
+ if (std_timezone == NULL) {
+ std_timezone = getGMTOffsetID();
+ }
}
}
-
return std_timezone;
}
/**
- * Returns a GMT-offset-based time zone ID. On Win32, it always return
- * NULL since the fall back is performed in getWinTimeZone().
+ * Returns a GMT-offset-based time zone ID.
*/
char *
getGMTOffsetID()
{
- return NULL;
+ LONG bias = 0;
+ LONG ret;
+ HANDLE hKey = NULL;
+ char zonename[32];
+
+ // Obtain the current GMT offset value of ActiveTimeBias.
+ ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0,
+ KEY_READ, (PHKEY)&hKey);
+ if (ret == ERROR_SUCCESS) {
+ DWORD val;
+ DWORD bufSize = sizeof(val);
+ ULONG valueType = 0;
+ ret = RegQueryValueExA(hKey, "ActiveTimeBias",
+ NULL, &valueType, (LPBYTE) &val, &bufSize);
+ if (ret == ERROR_SUCCESS) {
+ bias = (LONG) val;
+ }
+ (void) RegCloseKey(hKey);
+ }
+
+ // If we can't get the ActiveTimeBias value, use Bias of TimeZoneInformation.
+ // Note: Bias doesn't reflect current daylight saving.
+ if (ret != ERROR_SUCCESS) {
+ TIME_ZONE_INFORMATION tzi;
+ if (GetTimeZoneInformation(&tzi) != TIME_ZONE_ID_INVALID) {
+ bias = tzi.Bias;
+ }
+ }
+
+ customZoneName(bias, zonename);
+ return _strdup(zonename);
}
diff --git a/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp b/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp
new file mode 100644
index 0000000..1615a6e
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp
@@ -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 <windows.h>
+#include <winbase.h>
+
+
+/**
+ * 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 <process.h>
+#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;
+}
diff --git a/src/windows/native/sun/bridge/AccessBridgeATInstance.h b/src/windows/native/sun/bridge/AccessBridgeATInstance.h
new file mode 100644
index 0000000..1a29098
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeATInstance.h
@@ -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 <windows.h>
+#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
diff --git a/src/windows/native/sun/bridge/AccessBridgeCallbacks.h b/src/windows/native/sun/bridge/AccessBridgeCallbacks.h
new file mode 100644
index 0000000..d2428b8
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeCallbacks.h
@@ -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 <jni.h>
+#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
diff --git a/src/windows/native/sun/bridge/AccessBridgeCalls.c b/src/windows/native/sun/bridge/AccessBridgeCalls.c
new file mode 100644
index 0000000..70ab3ef
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeCalls.c
@@ -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 <windows.h>
+#include <jni.h>
+
+
+//#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
diff --git a/src/windows/native/sun/bridge/AccessBridgeCalls.h b/src/windows/native/sun/bridge/AccessBridgeCalls.h
new file mode 100644
index 0000000..7ee7c3a
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeCalls.h
@@ -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 <windows.h>
+#include <jni.h>
+#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
diff --git a/src/windows/native/sun/bridge/AccessBridgeDebug.cpp b/src/windows/native/sun/bridge/AccessBridgeDebug.cpp
new file mode 100644
index 0000000..2513595
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeDebug.cpp
@@ -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 <stdarg.h>
+#include <stdio.h>
+#include <windows.h>
+
+#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
diff --git a/src/windows/native/sun/bridge/AccessBridgeDebug.h b/src/windows/native/sun/bridge/AccessBridgeDebug.h
new file mode 100644
index 0000000..95fd047
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeDebug.h
@@ -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 <crtdbg.h>
+#include <windows.h>
+
+#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
diff --git a/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp b/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp
new file mode 100644
index 0000000..ee75bfe
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp
@@ -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)
diff --git a/src/windows/native/sun/bridge/AccessBridgeEventHandler.h b/src/windows/native/sun/bridge/AccessBridgeEventHandler.h
new file mode 100644
index 0000000..32fd2cf
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeEventHandler.h
@@ -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
diff --git a/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp b/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp
new file mode 100644
index 0000000..2d2eb88
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp
@@ -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;
+}
diff --git a/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.h b/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.h
new file mode 100644
index 0000000..e13daea
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.h
@@ -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 <windows.h>
+#include <jni.h>
+
+#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
diff --git a/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp b/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp
new file mode 100644
index 0000000..2647db6
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp
@@ -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 <winbase.h>
+#include <jni.h>
+
+// 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;
+}
diff --git a/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.h b/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.h
new file mode 100644
index 0000000..18a536a
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.h
@@ -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 <jni.h>
+#include <windows.h>
+
+/**
+ * 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
diff --git a/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp b/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp
new file mode 100644
index 0000000..6dca15b
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp
@@ -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 <windows.h>
+#include <malloc.h>
+
+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;
+}
diff --git a/src/windows/native/sun/bridge/AccessBridgeMessageQueue.h b/src/windows/native/sun/bridge/AccessBridgeMessageQueue.h
new file mode 100644
index 0000000..0009250
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeMessageQueue.h
@@ -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 <windows.h>
+
+#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
diff --git a/src/windows/native/sun/bridge/AccessBridgeMessages.cpp b/src/windows/native/sun/bridge/AccessBridgeMessages.cpp
new file mode 100644
index 0000000..bc5d291
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeMessages.cpp
@@ -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;
+}
diff --git a/src/windows/native/sun/bridge/AccessBridgeMessages.h b/src/windows/native/sun/bridge/AccessBridgeMessages.h
new file mode 100644
index 0000000..a61aabe
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeMessages.h
@@ -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 <windows.h>
+#include <winuser.h>
+
+#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
diff --git a/src/windows/native/sun/bridge/AccessBridgePackages.h b/src/windows/native/sun/bridge/AccessBridgePackages.h
new file mode 100644
index 0000000..564dd7f
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgePackages.h
@@ -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 <jni.h>
+#include <windows.h>
+
+#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
diff --git a/src/windows/native/sun/bridge/AccessBridgeStatusWindow.RC b/src/windows/native/sun/bridge/AccessBridgeStatusWindow.RC
new file mode 100644
index 0000000..34c9c4f
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeStatusWindow.RC
@@ -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
+
diff --git a/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp b/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp
new file mode 100644
index 0000000..2472bc7
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp
@@ -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 <windows.h>
+#include <jni.h>
+
+
+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
diff --git a/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.h b/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.h
new file mode 100644
index 0000000..a655592
--- /dev/null
+++ b/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.h
@@ -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 <windows.h>
+#include <jni.h>
+
+#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
diff --git a/src/windows/native/sun/bridge/JAWTAccessBridge.cpp b/src/windows/native/sun/bridge/JAWTAccessBridge.cpp
new file mode 100644
index 0000000..8273743
--- /dev/null
+++ b/src/windows/native/sun/bridge/JAWTAccessBridge.cpp
@@ -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 <windows.h>
+#include <stdio.h>
+
+#include <jawt.h>
+#include <win32/jawt_md.h>
+
+// ---------------------------------------------------------------------------
+
+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;
+ }
+}
diff --git a/src/windows/native/sun/bridge/JAWTAccessBridge.h b/src/windows/native/sun/bridge/JAWTAccessBridge.h
new file mode 100644
index 0000000..3c78610
--- /dev/null
+++ b/src/windows/native/sun/bridge/JAWTAccessBridge.h
@@ -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 <windows.h>
+#include <jni.h>
+
+#include "AccessBridgePackages.h"
+
+#ifndef __JAWTAccessBridge_H__
+#define __JAWTAccessBridge_H__
+
+
+extern "C" {
+ BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason,
+ LPVOID lpvReserved);
+}
+
+#endif
diff --git a/src/windows/native/sun/bridge/JavaAccessBridge.cpp b/src/windows/native/sun/bridge/JavaAccessBridge.cpp
new file mode 100644
index 0000000..3feb019
--- /dev/null
+++ b/src/windows/native/sun/bridge/JavaAccessBridge.cpp
@@ -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 <windows.h>
+#include <stdio.h>
+
+// #ifdef JAWT_SUPPORT
+#include <jawt.h>
+#include <win32/jawt_md.h>
+// #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)
+
+ }
diff --git a/src/windows/native/sun/bridge/JavaAccessBridge.h b/src/windows/native/sun/bridge/JavaAccessBridge.h
new file mode 100644
index 0000000..d03960f
--- /dev/null
+++ b/src/windows/native/sun/bridge/JavaAccessBridge.h
@@ -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 <windows.h>
+#include <jni.h>
+
+#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
diff --git a/src/windows/native/sun/bridge/WinAccessBridge.DEF b/src/windows/native/sun/bridge/WinAccessBridge.DEF
new file mode 100644
index 0000000..612374f
--- /dev/null
+++ b/src/windows/native/sun/bridge/WinAccessBridge.DEF
@@ -0,0 +1,154 @@
+;
+; 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.
+;
+;
+;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
diff --git a/src/windows/native/sun/bridge/WinAccessBridge.cpp b/src/windows/native/sun/bridge/WinAccessBridge.cpp
new file mode 100644
index 0000000..15e5928
--- /dev/null
+++ b/src/windows/native/sun/bridge/WinAccessBridge.cpp
@@ -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 <windows.h>
+#include <jni.h>
+#include <stdio.h>
+
+// 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)
diff --git a/src/windows/native/sun/bridge/WinAccessBridge.h b/src/windows/native/sun/bridge/WinAccessBridge.h
new file mode 100644
index 0000000..d3b1b85
--- /dev/null
+++ b/src/windows/native/sun/bridge/WinAccessBridge.h
@@ -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 <windows.h>
+#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
diff --git a/src/windows/native/sun/bridge/accessBridgeResource.h b/src/windows/native/sun/bridge/accessBridgeResource.h
new file mode 100644
index 0000000..cddd1ac
--- /dev/null
+++ b/src/windows/native/sun/bridge/accessBridgeResource.h
@@ -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
diff --git a/src/windows/native/sun/bridge/accessibility.properties b/src/windows/native/sun/bridge/accessibility.properties
new file mode 100644
index 0000000..d9f12e3
--- /dev/null
+++ b/src/windows/native/sun/bridge/accessibility.properties
@@ -0,0 +1,6 @@
+#
+# Load the Java Access Bridge class into the JVM
+#
+#assistive_technologies=com.sun.java.accessibility.AccessBridge
+#screen_magnifier_present=true
+
diff --git a/src/windows/native/sun/bridge/jabswitch.cpp b/src/windows/native/sun/bridge/jabswitch.cpp
new file mode 100644
index 0000000..e3257d7
--- /dev/null
+++ b/src/windows/native/sun/bridge/jabswitch.cpp
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <Windows.h>
+#include <tchar.h>
+
+// 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");
+ }
+ }
+}
diff --git a/src/windows/native/sun/bridge/jabswitch.manifest b/src/windows/native/sun/bridge/jabswitch.manifest
new file mode 100644
index 0000000..a43d11b
--- /dev/null
+++ b/src/windows/native/sun/bridge/jabswitch.manifest
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
diff --git a/src/windows/native/sun/bridge/jabswitch_manifest.rc b/src/windows/native/sun/bridge/jabswitch_manifest.rc
new file mode 100644
index 0000000..a3a3138
--- /dev/null
+++ b/src/windows/native/sun/bridge/jabswitch_manifest.rc
@@ -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)
diff --git a/src/windows/native/sun/bridge/resource.h b/src/windows/native/sun/bridge/resource.h
new file mode 100644
index 0000000..60fbf82
--- /dev/null
+++ b/src/windows/native/sun/bridge/resource.h
@@ -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
diff --git a/src/windows/native/sun/net/spi/DefaultProxySelector.c b/src/windows/native/sun/net/spi/DefaultProxySelector.c
index 3dffe94..6fd5764 100644
--- a/src/windows/native/sun/net/spi/DefaultProxySelector.c
+++ b/src/windows/native/sun/net/spi/DefaultProxySelector.c
@@ -169,6 +169,11 @@
*/
s = strtok(override, "; ");
urlhost = (*env)->GetStringUTFChars(env, host, &isCopy);
+ if (urlhost == NULL) {
+ if (!(*env)->ExceptionCheck(env))
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return NULL;
+ }
while (s != NULL) {
if (strncmp(s, urlhost, strlen(s)) == 0) {
/**
@@ -186,8 +191,11 @@
}
cproto = (*env)->GetStringUTFChars(env, proto, &isCopy);
- if (cproto == NULL)
- goto noproxy;
+ if (cproto == NULL) {
+ if (!(*env)->ExceptionCheck(env))
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return NULL;
+ }
/*
* Set default port value & proxy type from protocol.
@@ -245,7 +253,9 @@
if (pport == 0)
pport = defport;
jhost = (*env)->NewStringUTF(env, phost);
+ CHECK_NULL_RETURN(jhost, NULL);
isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, pport);
+ CHECK_NULL_RETURN(isa, NULL);
proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
return proxy;
}
diff --git a/src/windows/native/sun/nio/ch/DatagramChannelImpl.c b/src/windows/native/sun/nio/ch/DatagramChannelImpl.c
index ab46f8d..ecc96a1 100644
--- a/src/windows/native/sun/nio/ch/DatagramChannelImpl.c
+++ b/src/windows/native/sun/nio/ch/DatagramChannelImpl.c
@@ -45,18 +45,28 @@
Java_sun_nio_ch_DatagramChannelImpl_initIDs(JNIEnv *env, jclass clazz)
{
clazz = (*env)->FindClass(env, "java/net/InetSocketAddress");
+ CHECK_NULL(clazz);
isa_class = (*env)->NewGlobalRef(env, clazz);
+ if (isa_class == NULL) {
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return;
+ }
isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
"(Ljava/net/InetAddress;I)V");
+ CHECK_NULL(isa_ctorID);
clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
+ CHECK_NULL(clazz);
dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
"Ljava/net/SocketAddress;");
+ CHECK_NULL(dci_senderID);
dci_senderAddrID = (*env)->GetFieldID(env, clazz,
"cachedSenderInetAddress",
"Ljava/net/InetAddress;");
+ CHECK_NULL(dci_senderAddrID);
dci_senderPortID = (*env)->GetFieldID(env, clazz,
"cachedSenderPort", "I");
+ CHECK_NULL(dci_senderPortID);
}
/*
@@ -185,17 +195,11 @@
if (senderAddr == NULL) {
jobject isa = NULL;
int port;
- jobject ia = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa,
- &port);
-
+ jobject ia = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
if (ia != NULL) {
isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
}
-
- if (isa == NULL) {
- JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
- return IOS_THROWN;
- }
+ CHECK_NULL_RETURN(isa, IOS_THROWN);
// update cachedSenderInetAddress/cachedSenderPort
(*env)->SetObjectField(env, this, dci_senderAddrID, ia);
diff --git a/src/windows/native/sun/nio/ch/FileChannelImpl.c b/src/windows/native/sun/nio/ch/FileChannelImpl.c
index 89215f2..cb72478 100644
--- a/src/windows/native/sun/nio/ch/FileChannelImpl.c
+++ b/src/windows/native/sun/nio/ch/FileChannelImpl.c
@@ -31,6 +31,10 @@
#include "nio.h"
#include "nio_util.h"
#include "sun_nio_ch_FileChannelImpl.h"
+#include "java_lang_Integer.h"
+
+#include <Mswsock.h>
+#pragma comment(lib, "Mswsock.lib")
static jfieldID chan_fd; /* id for jobject 'fd' in java.io.FileChannel */
@@ -174,9 +178,42 @@
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
- jint srcFD,
+ jobject srcFD,
jlong position, jlong count,
- jint dstFD)
+ jobject dstFD)
{
- return IOS_UNSUPPORTED;
+ const int PACKET_SIZE = 524288;
+
+ HANDLE src = (HANDLE)(handleval(env, srcFD));
+ SOCKET dst = (SOCKET)(fdval(env, dstFD));
+ DWORD chunkSize = (count > java_lang_Integer_MAX_VALUE) ?
+ java_lang_Integer_MAX_VALUE : (DWORD)count;
+ BOOL result = 0;
+
+ jlong pos = Java_sun_nio_ch_FileChannelImpl_position0(env, this, srcFD, position);
+ if (pos == IOS_THROWN) {
+ return IOS_THROWN;
+ }
+
+ result = TransmitFile(
+ dst,
+ src,
+ chunkSize,
+ PACKET_SIZE,
+ NULL,
+ NULL,
+ TF_USE_KERNEL_APC
+ );
+ if (!result) {
+ int error = WSAGetLastError();
+ if (WSAEINVAL == error && count >= 0) {
+ return IOS_UNSUPPORTED_CASE;
+ }
+ if (WSAENOTSOCK == error) {
+ return IOS_UNSUPPORTED_CASE;
+ }
+ JNU_ThrowIOExceptionWithLastError(env, "transfer failed");
+ return IOS_THROWN;
+ }
+ return chunkSize;
}
diff --git a/src/windows/native/sun/nio/ch/FileKey.c b/src/windows/native/sun/nio/ch/FileKey.c
index e095296..65306d1 100644
--- a/src/windows/native/sun/nio/ch/FileKey.c
+++ b/src/windows/native/sun/nio/ch/FileKey.c
@@ -38,9 +38,9 @@
JNIEXPORT void JNICALL
Java_sun_nio_ch_FileKey_initIDs(JNIEnv *env, jclass clazz)
{
- key_volumeSN = (*env)->GetFieldID(env, clazz, "dwVolumeSerialNumber", "J");
- key_indexHigh = (*env)->GetFieldID(env, clazz, "nFileIndexHigh", "J");
- key_indexLow = (*env)->GetFieldID(env, clazz, "nFileIndexLow", "J");
+ CHECK_NULL(key_volumeSN = (*env)->GetFieldID(env, clazz, "dwVolumeSerialNumber", "J"));
+ CHECK_NULL(key_indexHigh = (*env)->GetFieldID(env, clazz, "nFileIndexHigh", "J"));
+ CHECK_NULL(key_indexLow = (*env)->GetFieldID(env, clazz, "nFileIndexLow", "J"));
}
diff --git a/src/windows/native/sun/nio/ch/IOUtil.c b/src/windows/native/sun/nio/ch/IOUtil.c
index 10c72e4..370dcf5 100644
--- a/src/windows/native/sun/nio/ch/IOUtil.c
+++ b/src/windows/native/sun/nio/ch/IOUtil.c
@@ -52,9 +52,9 @@
JNIEXPORT void JNICALL
Java_sun_nio_ch_IOUtil_initIDs(JNIEnv *env, jclass clazz)
{
- clazz = (*env)->FindClass(env, "java/io/FileDescriptor");
- fd_fdID = (*env)->GetFieldID(env, clazz, "fd", "I");
- handle_fdID = (*env)->GetFieldID(env, clazz, "handle", "J");
+ CHECK_NULL(clazz = (*env)->FindClass(env, "java/io/FileDescriptor"));
+ CHECK_NULL(fd_fdID = (*env)->GetFieldID(env, clazz, "fd", "I"));
+ CHECK_NULL(handle_fdID = (*env)->GetFieldID(env, clazz, "handle", "J"));
}
/**************************************************************
diff --git a/src/windows/native/sun/nio/ch/Iocp.c b/src/windows/native/sun/nio/ch/Iocp.c
index 8f87a89..f955623 100644
--- a/src/windows/native/sun/nio/ch/Iocp.c
+++ b/src/windows/native/sun/nio/ch/Iocp.c
@@ -46,16 +46,15 @@
jclass clazz;
clazz = (*env)->FindClass(env, "sun/nio/ch/Iocp$CompletionStatus");
- if (clazz == NULL) {
- return;
- }
+ CHECK_NULL(clazz);
completionStatus_error = (*env)->GetFieldID(env, clazz, "error", "I");
- if (completionStatus_error == NULL) return;
+ CHECK_NULL(completionStatus_error);
completionStatus_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
- if (completionStatus_bytesTransferred == NULL) return;
+ CHECK_NULL(completionStatus_bytesTransferred);
completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "I");
- if (completionStatus_completionKey == NULL) return;
+ CHECK_NULL(completionStatus_completionKey);
completionStatus_overlapped = (*env)->GetFieldID(env, clazz, "overlapped", "J");
+ CHECK_NULL(completionStatus_overlapped);
}
JNIEXPORT jint JNICALL
diff --git a/src/windows/native/sun/nio/ch/Net.c b/src/windows/native/sun/nio/ch/Net.c
index fb0faa8..e68951b 100644
--- a/src/windows/native/sun/nio/ch/Net.c
+++ b/src/windows/native/sun/nio/ch/Net.c
@@ -127,7 +127,7 @@
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
- jboolean stream, jboolean reuse)
+ jboolean stream, jboolean reuse, jboolean fastLoopback)
{
SOCKET s;
int domain = (preferIPv6) ? AF_INET6 : AF_INET;
@@ -152,6 +152,20 @@
NET_ThrowNew(env, WSAGetLastError(), "socket");
}
+ if (stream && fastLoopback) {
+ static int loopback_available = 1;
+ if (loopback_available) {
+ int rv = NET_EnableFastTcpLoopback((jint)s);
+ if (rv) {
+ if (rv == WSAEOPNOTSUPP) {
+ loopback_available = 0;
+ } else {
+ NET_ThrowNew(env, rv, "fastLoopback");
+ }
+ }
+ }
+ }
+
return (jint)s;
}
diff --git a/src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c b/src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c
index 2af833c..8cd94ea 100644
--- a/src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c
+++ b/src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c
@@ -56,12 +56,20 @@
Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(JNIEnv *env, jclass cls)
{
cls = (*env)->FindClass(env, "java/io/FileDescriptor");
+ CHECK_NULL(cls);
fd_fdID = (*env)->GetFieldID(env, cls, "fd", "I");
+ CHECK_NULL(fd_fdID);
cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
+ CHECK_NULL(cls);
isa_class = (*env)->NewGlobalRef(env, cls);
+ if (isa_class == NULL) {
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return;
+ }
isa_ctorID = (*env)->GetMethodID(env, cls, "<init>",
"(Ljava/net/InetAddress;I)V");
+ CHECK_NULL(isa_ctorID);
}
JNIEXPORT void JNICALL
@@ -97,12 +105,13 @@
return IOS_THROWN;
}
+ SetHandleInformation((HANDLE)(UINT_PTR)newfd, HANDLE_FLAG_INHERIT, 0);
(*env)->SetIntField(env, newfdo, fd_fdID, newfd);
remote_ia = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, (int *)&remote_port);
+ CHECK_NULL_RETURN(remote_ia, IOS_THROWN);
- isa = (*env)->NewObject(env, isa_class, isa_ctorID,
- remote_ia, remote_port);
+ isa = (*env)->NewObject(env, isa_class, isa_ctorID, remote_ia, remote_port);
+ CHECK_NULL_RETURN(isa, IOS_THROWN);
(*env)->SetObjectArrayElement(env, isaa, 0, isa);
-
return 1;
}
diff --git a/src/windows/native/sun/nio/ch/SocketChannelImpl.c b/src/windows/native/sun/nio/ch/SocketChannelImpl.c
index a8ba14b..4ba86a9 100644
--- a/src/windows/native/sun/nio/ch/SocketChannelImpl.c
+++ b/src/windows/native/sun/nio/ch/SocketChannelImpl.c
@@ -42,8 +42,8 @@
JNIEXPORT void JNICALL
Java_sun_nio_ch_SocketChannelImpl_initIDs(JNIEnv *env, jclass cls)
{
- cls = (*env)->FindClass(env, "java/net/InetAddress");
- ia_addrID = (*env)->GetFieldID(env, cls, "address", "I");
+ CHECK_NULL(cls = (*env)->FindClass(env, "java/net/InetAddress"));
+ CHECK_NULL(ia_addrID = (*env)->GetFieldID(env, cls, "address", "I"));
}
jint
diff --git a/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c b/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c
index 566d2ae..94e060f 100644
--- a/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c
+++ b/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c
@@ -111,65 +111,70 @@
HMODULE h;
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstFile");
- if (clazz == NULL) {
- return;
- }
+ CHECK_NULL(clazz);
findFirst_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
+ CHECK_NULL(findFirst_handle);
findFirst_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
+ CHECK_NULL(findFirst_name);
findFirst_attributes = (*env)->GetFieldID(env, clazz, "attributes", "I");
+ CHECK_NULL(findFirst_attributes);
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstStream");
- if (clazz == NULL) {
- return;
- }
+ CHECK_NULL(clazz);
findStream_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
+ CHECK_NULL(findStream_handle);
findStream_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
+ CHECK_NULL(findStream_name);
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$VolumeInformation");
- if (clazz == NULL) {
- return;
- }
+ CHECK_NULL(clazz);
volumeInfo_fsName = (*env)->GetFieldID(env, clazz, "fileSystemName", "Ljava/lang/String;");
+ CHECK_NULL(volumeInfo_fsName);
volumeInfo_volName = (*env)->GetFieldID(env, clazz, "volumeName", "Ljava/lang/String;");
+ CHECK_NULL(volumeInfo_volName);
volumeInfo_volSN = (*env)->GetFieldID(env, clazz, "volumeSerialNumber", "I");
+ CHECK_NULL(volumeInfo_volSN);
volumeInfo_flags = (*env)->GetFieldID(env, clazz, "flags", "I");
+ CHECK_NULL(volumeInfo_flags);
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$DiskFreeSpace");
- if (clazz == NULL) {
- return;
- }
+ CHECK_NULL(clazz);
diskSpace_bytesAvailable = (*env)->GetFieldID(env, clazz, "freeBytesAvailable", "J");
+ CHECK_NULL(diskSpace_bytesAvailable);
diskSpace_totalBytes = (*env)->GetFieldID(env, clazz, "totalNumberOfBytes", "J");
+ CHECK_NULL(diskSpace_totalBytes);
diskSpace_totalFree = (*env)->GetFieldID(env, clazz, "totalNumberOfFreeBytes", "J");
+ CHECK_NULL(diskSpace_totalFree);
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$Account");
- if (clazz == NULL) {
- return;
- }
+ CHECK_NULL(clazz);
account_domain = (*env)->GetFieldID(env, clazz, "domain", "Ljava/lang/String;");
+ CHECK_NULL(account_domain);
account_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
+ CHECK_NULL(account_name);
account_use = (*env)->GetFieldID(env, clazz, "use", "I");
+ CHECK_NULL(account_use);
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$AclInformation");
- if (clazz == NULL) {
- return;
- }
+ CHECK_NULL(clazz);
aclInfo_aceCount = (*env)->GetFieldID(env, clazz, "aceCount", "I");
+ CHECK_NULL(aclInfo_aceCount);
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$CompletionStatus");
- if (clazz == NULL) {
- return;
- }
+ CHECK_NULL(clazz);
completionStatus_error = (*env)->GetFieldID(env, clazz, "error", "I");
+ CHECK_NULL(completionStatus_error);
completionStatus_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
+ CHECK_NULL(completionStatus_bytesTransferred);
completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "J");
+ CHECK_NULL(completionStatus_completionKey);
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$BackupResult");
- if (clazz == NULL) {
- return;
- }
+ CHECK_NULL(clazz);
backupResult_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
+ CHECK_NULL(backupResult_bytesTransferred);
backupResult_context = (*env)->GetFieldID(env, clazz, "context", "J");
+ CHECK_NULL(backupResult_context);
// get handle to kernel32
if (GetModuleHandleExW((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
diff --git a/src/windows/native/sun/windows/awt_Component.cpp b/src/windows/native/sun/windows/awt_Component.cpp
index 3baae0f..5a29590 100644
--- a/src/windows/native/sun/windows/awt_Component.cpp
+++ b/src/windows/native/sun/windows/awt_Component.cpp
@@ -3761,12 +3761,14 @@
void AwtComponent::OpenCandidateWindow(int x, int y)
{
UINT bits = 1;
- RECT rc;
- GetWindowRect(GetHWnd(), &rc);
+ POINT p = {0, 0}; // upper left corner of the client area
+ HWND hWnd = GetHWnd();
+ HWND hTop = GetTopLevelParentForWindow(hWnd);
+ ::ClientToScreen(hTop, &p);
for (int iCandType=0; iCandType<32; iCandType++, bits<<=1) {
if ( m_bitsCandType & bits )
- SetCandidateWindow(iCandType, x-rc.left, y-rc.top);
+ SetCandidateWindow(iCandType, x - p.x, y - p.y);
}
if (m_bitsCandType != 0) {
// REMIND: is there any chance GetProxyFocusOwner() returns NULL here?
diff --git a/src/windows/native/sun/windows/awt_Desktop.cpp b/src/windows/native/sun/windows/awt_Desktop.cpp
index 828818b..36b5467 100644
--- a/src/windows/native/sun/windows/awt_Desktop.cpp
+++ b/src/windows/native/sun/windows/awt_Desktop.cpp
@@ -52,6 +52,7 @@
// 6457572: ShellExecute possibly changes FPU control word - saving it here
unsigned oldcontrol87 = _control87(0, 0);
HINSTANCE retval = ::ShellExecute(NULL, verb_c, fileOrUri_c, NULL, NULL, SW_SHOWNORMAL);
+ DWORD error = ::GetLastError();
_control87(oldcontrol87, 0xffffffff);
JNU_ReleaseStringPlatformChars(env, fileOrUri_j, fileOrUri_c);
@@ -65,7 +66,7 @@
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
- (int)retval,
+ error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&buffer,
0,
diff --git a/src/windows/native/sun/windows/awt_Frame.cpp b/src/windows/native/sun/windows/awt_Frame.cpp
index 6822a09..6ac3c5f 100644
--- a/src/windows/native/sun/windows/awt_Frame.cpp
+++ b/src/windows/native/sun/windows/awt_Frame.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -82,6 +82,15 @@
HHOOK mouseHook;
HHOOK modalHook;
};
+
+
+// Communication with plugin control
+
+// The value must be the same as in AxControl.h
+#define WM_AX_REQUEST_FOCUS_TO_EMBEDDER (WM_USER + 197)
+
+static bool SetFocusToPluginControl(HWND hwndPlugin);
+
/************************************************************************
* AwtFrame fields
*/
@@ -93,6 +102,7 @@
jmethodID AwtFrame::setExtendedStateMID;
jmethodID AwtFrame::activateEmbeddingTopLevelMID;
+jfieldID AwtFrame::isEmbeddedInIEID;
Hashtable AwtFrame::sm_BlockedThreads("AWTBlockedThreads");
@@ -104,6 +114,7 @@
m_parentWnd = NULL;
menuBar = NULL;
m_isEmbedded = FALSE;
+ m_isEmbeddedInIE = FALSE;
m_isLightweight = FALSE;
m_ignoreWmSize = FALSE;
m_isMenuDropped = FALSE;
@@ -199,6 +210,13 @@
if (isEmbedded) {
hwndParent = (HWND)handle;
+
+ // JDK-8056915: Handle focus communication between plugin and frame
+ frame->m_isEmbeddedInIE = IsEmbeddedInIE(hwndParent);
+ if (frame->m_isEmbeddedInIE) {
+ env->SetBooleanField(target, isEmbeddedInIEID, JNI_TRUE);
+ }
+
RECT rect;
::GetClientRect(hwndParent, &rect);
//Fix for 6328675: SWT_AWT.new_Frame doesn't occupy client area under JDK6
@@ -338,6 +356,21 @@
return frame;
}
+/*
+ * Returns true if the frame is embedded into Internet Explorer.
+ * The function checks the class name of the parent window of the embedded frame.
+ */
+BOOL AwtFrame::IsEmbeddedInIE(HWND hwndParent)
+{
+ const char *pluginClass = "Java Plug-in Control Window";
+ #define PARENT_CLASS_BUFFER_SIZE 64
+ char parentClass[PARENT_CLASS_BUFFER_SIZE];
+
+ return (::GetClassNameA(hwndParent, parentClass, PARENT_CLASS_BUFFER_SIZE) > 0)
+ && (strncmp(parentClass, pluginClass, PARENT_CLASS_BUFFER_SIZE) == 0);
+}
+
+
LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, MsgRouting &mr)
{
LRESULT retValue = 0L;
@@ -1039,6 +1072,19 @@
if (IsLightweightFrame()) {
return TRUE;
}
+ if (isMouseEventCause && IsEmbeddedFrame() && m_isEmbeddedInIE) {
+ HWND hwndProxy = GetProxyFocusOwner();
+ // Do nothing if this frame is focused already
+ if (::GetFocus() != hwndProxy) {
+ // Fix for JDK-8056915:
+ // If window activated with mouse, set focus to plugin control window
+ // first to preserve focus owner inside browser window
+ if (SetFocusToPluginControl(::GetParent(GetHWnd()))) {
+ return TRUE;
+ }
+ // Plugin control window is already focused, so do normal processing
+ }
+ }
return AwtWindow::AwtSetActiveWindow(isMouseEventCause);
}
@@ -1819,6 +1865,9 @@
AwtFrame::activateEmbeddingTopLevelMID = env->GetMethodID(cls, "activateEmbeddingTopLevel", "()V");
DASSERT(AwtFrame::activateEmbeddingTopLevelMID != NULL);
+ AwtFrame::isEmbeddedInIEID = env->GetFieldID(cls, "isEmbeddedInIE", "Z");
+ DASSERT(AwtFrame::isEmbeddedInIEID != NULL);
+
CATCH_BAD_ALLOC;
}
@@ -1911,4 +1960,44 @@
CATCH_BAD_ALLOC;
}
+JNIEXPORT jboolean JNICALL
+Java_sun_awt_windows_WEmbeddedFramePeer_requestFocusToEmbedder(JNIEnv *env, jobject self)
+{
+ jboolean result = JNI_FALSE;
+
+ TRY;
+
+ AwtFrame *frame = NULL;
+
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(self, ret);
+ frame = (AwtFrame *)pData;
+
+ // JDK-8056915: During initial applet activation, set focus to plugin control window
+ HWND hwndParent = ::GetParent(frame->GetHWnd());
+
+ result = SetFocusToPluginControl(hwndParent);
+
+ CATCH_BAD_ALLOC_RET(JNI_FALSE);
+ret:
+ return result;
+}
+
} /* extern "C" */
+
+static bool SetFocusToPluginControl(HWND hwndPlugin)
+{
+ HWND hwndFocus = ::GetFocus();
+
+ if (hwndFocus == hwndPlugin) {
+ return false;
+ }
+
+ ::SetFocus(hwndPlugin);
+ DWORD dwError = ::GetLastError();
+ if (dwError != ERROR_SUCCESS) {
+ // If direct call failed, use a special message to set focus
+ return (::SendMessage(hwndPlugin, WM_AX_REQUEST_FOCUS_TO_EMBEDDER, 0, 0) == 0);
+ }
+ return true;
+}
diff --git a/src/windows/native/sun/windows/awt_Frame.h b/src/windows/native/sun/windows/awt_Frame.h
index eac23e9..3257312 100644
--- a/src/windows/native/sun/windows/awt_Frame.h
+++ b/src/windows/native/sun/windows/awt_Frame.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -60,6 +60,9 @@
/* method id for WEmbeddedFrame.requestActivate() method */
static jmethodID activateEmbeddingTopLevelMID;
+ /* field id for WEmbeddedFrame.isEmbeddedInIE */
+ static jfieldID isEmbeddedInIEID;
+
AwtFrame();
virtual ~AwtFrame();
@@ -171,6 +174,13 @@
/* The frame is an EmbeddedFrame. */
BOOL m_isEmbedded;
+ /* Fix for JDK-8056915:
+ The embedded frame must gain focus by setting focus to its parent. */
+ BOOL m_isEmbeddedInIE;
+
+ /* Checks whether the frame is embedded in IE */
+ static BOOL IsEmbeddedInIE(HWND hwndParent);
+
/* The frame is a LightweightFrame */
BOOL m_isLightweight;
diff --git a/src/windows/native/sun/windows/awt_InputTextInfor.cpp b/src/windows/native/sun/windows/awt_InputTextInfor.cpp
index 4ccf0d5..de9248f 100644
--- a/src/windows/native/sun/windows/awt_InputTextInfor.cpp
+++ b/src/windows/native/sun/windows/awt_InputTextInfor.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -310,6 +310,8 @@
readingMergedClauseW = new jstring[cMergedClauseW];
} catch (std::bad_alloc&) {
delete [] bndMergedClauseW;
+ delete [] bndClauseW;
+ delete [] readingClauseW;
throw;
}
@@ -394,6 +396,8 @@
valMergedAttrW = new BYTE[cMergedAttrW];
} catch (std::bad_alloc&) {
delete [] bndMergedAttrW;
+ delete [] bndAttrW;
+ delete [] valAttrW;
throw;
}
bndMergedAttrW[0] = 0;
diff --git a/src/windows/native/sun/windows/awt_TrayIcon.cpp b/src/windows/native/sun/windows/awt_TrayIcon.cpp
index a7e7078..e9c74d7 100644
--- a/src/windows/native/sun/windows/awt_TrayIcon.cpp
+++ b/src/windows/native/sun/windows/awt_TrayIcon.cpp
@@ -709,7 +709,7 @@
{
if (tooltip == NULL) {
m_nid.szTip[0] = '\0';
- } else if (lstrlen(tooltip) > TRAY_ICON_TOOLTIP_MAX_SIZE) {
+ } else if (lstrlen(tooltip) >= TRAY_ICON_TOOLTIP_MAX_SIZE) {
_tcsncpy(m_nid.szTip, tooltip, TRAY_ICON_TOOLTIP_MAX_SIZE);
m_nid.szTip[TRAY_ICON_TOOLTIP_MAX_SIZE - 1] = '\0';
} else {
@@ -814,7 +814,7 @@
if (caption[0] == '\0') {
m_nid.szInfoTitle[0] = '\0';
- } else if (lstrlen(caption) > TRAY_ICON_BALLOON_TITLE_MAX_SIZE) {
+ } else if (lstrlen(caption) >= TRAY_ICON_BALLOON_TITLE_MAX_SIZE) {
_tcsncpy(m_nid.szInfoTitle, caption, TRAY_ICON_BALLOON_TITLE_MAX_SIZE);
m_nid.szInfoTitle[TRAY_ICON_BALLOON_TITLE_MAX_SIZE - 1] = '\0';
@@ -827,7 +827,7 @@
m_nid.szInfo[0] = ' ';
m_nid.szInfo[1] = '\0';
- } else if (lstrlen(text) > TRAY_ICON_BALLOON_INFO_MAX_SIZE) {
+ } else if (lstrlen(text) >= TRAY_ICON_BALLOON_INFO_MAX_SIZE) {
_tcsncpy(m_nid.szInfo, text, TRAY_ICON_BALLOON_INFO_MAX_SIZE);
m_nid.szInfo[TRAY_ICON_BALLOON_INFO_MAX_SIZE - 1] = '\0';
diff --git a/test/ProblemList.txt b/test/ProblemList.txt
index 93fdaed..25ada7c 100644
--- a/test/ProblemList.txt
+++ b/test/ProblemList.txt
@@ -272,7 +272,4 @@
# Filed 6772009
java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java generic-all
-# 8051641
-sun/util/calendar/zi/TestZoneInfo310.java generic-all
-
############################################################################
diff --git a/test/com/sun/corba/5036554/TestCorbaBug.sh b/test/com/sun/corba/5036554/TestCorbaBug.sh
index 7e057e7..09cbed3 100644
--- a/test/com/sun/corba/5036554/TestCorbaBug.sh
+++ b/test/com/sun/corba/5036554/TestCorbaBug.sh
@@ -75,13 +75,13 @@
mkdir bug
cp ${TESTSRC}${FS}bug.idl .
-${TESTJAVA}${FS}bin${FS}idlj bug.idl
+${COMPILEJAVA}${FS}bin${FS}idlj bug.idl
cp ${TESTSRC}${FS}JavaBug.java bug
chmod -fR 777 bug
-${TESTJAVA}${FS}bin${FS}javac -d . bug${FS}*.java
+${COMPILEJAVA}${FS}bin${FS}javac -d . bug${FS}*.java
${TESTJAVA}${FS}bin${FS}java -cp . bug/JavaBug > test.out 2>&1
diff --git a/test/com/sun/corba/cachedSocket/7056731.sh b/test/com/sun/corba/cachedSocket/7056731.sh
index 3b58ad6..0d7c036 100644
--- a/test/com/sun/corba/cachedSocket/7056731.sh
+++ b/test/com/sun/corba/cachedSocket/7056731.sh
@@ -55,8 +55,8 @@
cp -r ${TESTSRC}${FS}*.java ${TESTSRC}${FS}Hello.idl .
echo "Testing...please wait"
-${TESTJAVA}${FS}bin${FS}idlj -fall Hello.idl
-${TESTJAVA}${FS}bin${FS}javac *.java HelloApp/*.java
+${COMPILEJAVA}${FS}bin${FS}idlj -fall Hello.idl
+${COMPILEJAVA}${FS}bin${FS}javac *.java HelloApp/*.java
echo "starting orbd"
${TESTJAVA}${FS}bin${FS}orbd -ORBInitialPort $PORT -ORBInitialHost localhost &
diff --git a/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java b/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java
new file mode 100644
index 0000000..8d05806
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2015, Red Hat, Inc.
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8069072
+ * @summary Test vectors for com.sun.crypto.provider.GHASH
+ */
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+
+public class TestGHASH {
+
+ private final Constructor<?> GHASH;
+ private final Method UPDATE;
+ private final Method DIGEST;
+
+ TestGHASH(String className) throws Exception {
+ Class<?> cls = Class.forName(className);
+ GHASH = cls.getDeclaredConstructor(byte[].class);
+ GHASH.setAccessible(true);
+ UPDATE = cls.getDeclaredMethod("update", byte[].class);
+ UPDATE.setAccessible(true);
+ DIGEST = cls.getDeclaredMethod("digest");
+ DIGEST.setAccessible(true);
+ }
+
+
+ private Object newGHASH(byte[] H) throws Exception {
+ return GHASH.newInstance(H);
+ }
+
+ private void updateGHASH(Object hash, byte[] data)
+ throws Exception {
+ UPDATE.invoke(hash, data);
+ }
+
+ private byte[] digestGHASH(Object hash) throws Exception {
+ return (byte[]) DIGEST.invoke(hash);
+ }
+
+ private static final String HEX_DIGITS = "0123456789abcdef";
+
+ private static String hex(byte[] bs) {
+ StringBuilder sb = new StringBuilder(2 * bs.length);
+ for (byte b : bs) {
+ sb.append(HEX_DIGITS.charAt((b >> 4) & 0xF));
+ sb.append(HEX_DIGITS.charAt(b & 0xF));
+ }
+ return sb.toString();
+ }
+
+ private static byte[] bytes(String hex) {
+ if ((hex.length() & 1) != 0) {
+ throw new AssertionError();
+ }
+ byte[] result = new byte[hex.length() / 2];
+ for (int i = 0; i < result.length; ++i) {
+ int a = HEX_DIGITS.indexOf(hex.charAt(2 * i));
+ int b = HEX_DIGITS.indexOf(hex.charAt(2 * i + 1));
+ if ((a | b) < 0) {
+ if (a < 0) {
+ throw new AssertionError(
+ "bad character " + (int) hex.charAt(2 * i));
+ }
+ throw new AssertionError(
+ "bad character " + (int) hex.charAt(2 * i + 1));
+ }
+ result[i] = (byte) ((a << 4) | b);
+ }
+ return result;
+ }
+
+ private static byte[] bytes(long L0, long L1) {
+ return ByteBuffer.allocate(16)
+ .putLong(L0)
+ .putLong(L1)
+ .array();
+ }
+
+ private void check(int testCase, String H, String A,
+ String C, String expected) throws Exception {
+ int lenA = A.length() * 4;
+ while ((A.length() % 32) != 0) {
+ A += '0';
+ }
+ int lenC = C.length() * 4;
+ while ((C.length() % 32) != 0) {
+ C += '0';
+ }
+
+ Object hash = newGHASH(bytes(H));
+ updateGHASH(hash, bytes(A));
+ updateGHASH(hash, bytes(C));
+ updateGHASH(hash, bytes(lenA, lenC));
+ byte[] digest = digestGHASH(hash);
+ String actual = hex(digest);
+ if (!expected.equals(actual)) {
+ throw new AssertionError(String.format("%d: expected %s, got %s",
+ testCase, expected, actual));
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ TestGHASH test;
+ if (args.length == 0) {
+ test = new TestGHASH("com.sun.crypto.provider.GHASH");
+ } else {
+ test = new TestGHASH(args[0]);
+ }
+
+ // Test vectors from David A. McGrew, John Viega,
+ // "The Galois/Counter Mode of Operation (GCM)", 2005.
+ // <http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf>
+
+ test.check(1, "66e94bd4ef8a2c3b884cfa59ca342b2e", "", "",
+ "00000000000000000000000000000000");
+ test.check(2,
+ "66e94bd4ef8a2c3b884cfa59ca342b2e", "",
+ "0388dace60b6a392f328c2b971b2fe78",
+ "f38cbb1ad69223dcc3457ae5b6b0f885");
+ test.check(3,
+ "b83b533708bf535d0aa6e52980d53b78", "",
+ "42831ec2217774244b7221b784d0d49c" +
+ "e3aa212f2c02a4e035c17e2329aca12e" +
+ "21d514b25466931c7d8f6a5aac84aa05" +
+ "1ba30b396a0aac973d58e091473f5985",
+ "7f1b32b81b820d02614f8895ac1d4eac");
+ test.check(4,
+ "b83b533708bf535d0aa6e52980d53b78",
+ "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
+ "42831ec2217774244b7221b784d0d49c" +
+ "e3aa212f2c02a4e035c17e2329aca12e" +
+ "21d514b25466931c7d8f6a5aac84aa05" +
+ "1ba30b396a0aac973d58e091",
+ "698e57f70e6ecc7fd9463b7260a9ae5f");
+ test.check(5, "b83b533708bf535d0aa6e52980d53b78",
+ "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
+ "61353b4c2806934a777ff51fa22a4755" +
+ "699b2a714fcdc6f83766e5f97b6c7423" +
+ "73806900e49f24b22b097544d4896b42" +
+ "4989b5e1ebac0f07c23f4598",
+ "df586bb4c249b92cb6922877e444d37b");
+ }
+}
diff --git a/test/com/sun/jdi/InstanceFilter.java b/test/com/sun/jdi/InstanceFilter.java
index 0d30472..43a0910 100644
--- a/test/com/sun/jdi/InstanceFilter.java
+++ b/test/com/sun/jdi/InstanceFilter.java
@@ -104,7 +104,10 @@
return;
}
if (theThis == null) {
- // This happens when the thread has exited.
+ // This happens when the thread has exited or when a
+ // static method is called. Setting an instance
+ // filter does not prevent this event from being
+ // emitted with a this that is null.
methodEntryRequest.disable();
return;
}
@@ -138,6 +141,10 @@
EventRequestManager mgr = vm().eventRequestManager();
methodEntryRequest = mgr.createMethodEntryRequest();
methodEntryRequest.addInstanceFilter(theInstance);
+ // Thread filter is needed to prevent MethodEntry events
+ // to be emitted by the debugee when a static method
+ // is called on any thread.
+ methodEntryRequest.addThreadFilter(bpe.thread());
methodEntryRequest.enable();
listenUntilVMDisconnect();
diff --git a/test/com/sun/jdi/InterfaceMethodsTest.java b/test/com/sun/jdi/InterfaceMethodsTest.java
index e127fa5..b2fd758 100644
--- a/test/com/sun/jdi/InterfaceMethodsTest.java
+++ b/test/com/sun/jdi/InterfaceMethodsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -24,6 +24,7 @@
/**
* @test
* @bug 8031195
+ * @bug 8071657
* @summary JDI: Add support for static and default methods in interfaces
*
* @run build TestScaffold VMConnection TargetListener TargetAdapter
@@ -38,6 +39,7 @@
private static final int RESULT_A = 1;
private static final int RESULT_B = 1;
private static final int RESULT_TARGET = 1;
+
static interface InterfaceA {
static int staticMethodA() {
System.out.println("-InterfaceA: static interface method A-");
@@ -202,6 +204,9 @@
// try to invoke static method B on the instance
testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
+
+ // try to invoke a virtual method
+ testInvokePos(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_A), true);
}
private void testInterfaceB(ObjectReference ref) {
@@ -302,9 +307,14 @@
private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value) {
+ testInvokePos(targetClass, ref, methodName, methodSig, value, false);
+ }
+
+ private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
+ String methodSig, Value value, boolean virtual) {
logInvocation(ref, methodName, methodSig, targetClass);
try {
- invoke(targetClass, ref, methodName, methodSig, value);
+ invoke(targetClass, ref, methodName, methodSig, value, virtual);
System.err.println("--- PASSED");
} catch (Exception e) {
System.err.println("--- FAILED");
@@ -314,9 +324,14 @@
private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value, String msg) {
+ testInvokeNeg(targetClass, ref, methodName, methodSig, value, msg, false);
+ }
+
+ private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
+ String methodSig, Value value, String msg, boolean virtual) {
logInvocation(ref, methodName, methodSig, targetClass);
try {
- invoke(targetClass, ref, methodName, methodSig, value);
+ invoke(targetClass, ref, methodName, methodSig, value, virtual);
System.err.println("--- FAILED");
failure("FAILED: " + msg);
} catch (Exception e) {
@@ -326,7 +341,7 @@
}
private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName,
- String methodSig, Value value)
+ String methodSig, Value value, boolean virtual)
throws Exception {
Method method = getMethod(targetClass, methodName, methodSig);
if (method == null) {
@@ -334,10 +349,15 @@
}
println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method);
+ println(method.declaringType().toString());
Value returnValue = null;
if (ref != null) {
- returnValue = invokeInstance(ref, method);
+ if (virtual) {
+ returnValue = invokeVirtual(ref, method);
+ } else {
+ returnValue = invokeInstance(ref, method);
+ }
} else {
returnValue = invokeStatic(targetClass, method);
}
@@ -362,6 +382,10 @@
return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
}
+ private Value invokeVirtual(ObjectReference ref, Method method) throws Exception {
+ return ref.invokeMethod(mainThread, method, Collections.emptyList(), 0);
+ }
+
private Value invokeStatic(ReferenceType refType, Method method) throws Exception {
if (refType instanceof ClassType) {
return ((ClassType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
diff --git a/test/com/sun/jdi/InvokeVarArgs.java b/test/com/sun/jdi/InvokeVarArgs.java
new file mode 100644
index 0000000..45af920
--- /dev/null
+++ b/test/com/sun/jdi/InvokeVarArgs.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 8075331
+ * @summary Verify that we can call varargs methods
+ * @run build TestScaffold VMConnection TargetAdapter TargetListener
+ * @run compile -g InvokeVarArgs.java
+ * @run driver InvokeVarArgs
+ */
+
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import java.util.Arrays;
+
+interface MyInterface {
+}
+
+class SomeClass implements MyInterface {
+}
+
+class InvokeVarArgsTarg {
+
+ public static void main(String args[]) {
+ new InvokeVarArgsTarg().run();
+ }
+
+ SomeClass someClass1 = new SomeClass();
+ SomeClass someClass2 = new SomeClass();
+
+ MyInterface[] array = new MyInterface[]{someClass1, someClass2};
+ SomeClass[] array2 = new SomeClass[]{someClass1, someClass2};
+
+ public void run() {
+ System.out.println("size(array) : " + size(array));
+ System.out.println("size(array2) : " + size(array2));
+ }
+
+ int size(Object... value) {
+ return value.length;
+ }
+}
+
+public class InvokeVarArgs extends TestScaffold {
+
+ public static void main(String args[]) throws Exception {
+ new InvokeVarArgs(args).startTests();
+ }
+
+ InvokeVarArgs(String args[]) throws Exception {
+ super(args);
+ }
+
+ protected void runTests() throws Exception {
+
+ BreakpointEvent bpe = startTo("InvokeVarArgsTarg", "run", "()V");
+ StackFrame frame = bpe.thread().frame(0);
+ ObjectReference targetObj = frame.thisObject();
+ ReferenceType targetType = (ReferenceType) targetObj.type();
+ Value arrayVal = targetObj.getValue(targetType.fieldByName("array"));
+ Value array2Val = targetObj.getValue(targetType.fieldByName("array2"));
+ Method sizeMethod = targetType.methodsByName("size", "([Ljava/lang/Object;)I").get(0);
+
+ IntegerValue size = (IntegerValue) targetObj.invokeMethod(bpe.thread(), sizeMethod, Arrays.asList(new Value[]{arrayVal}), 0);
+ if (size.value() != 2) {
+ throw new Exception("size(array) should be 2, but was " + size.value());
+ }
+
+ size = (IntegerValue) targetObj.invokeMethod(bpe.thread(), sizeMethod, Arrays.asList(new Value[]{array2Val}), 0);
+ if (size.value() != 2) {
+ throw new Exception("size(array2) should be 2, but was " + size.value());
+ }
+
+ listenUntilVMDisconnect();
+ }
+}
diff --git a/test/com/sun/jndi/dns/IPv6NameserverPlatformParsingTest.java b/test/com/sun/jndi/dns/IPv6NameserverPlatformParsingTest.java
new file mode 100644
index 0000000..ad1dd86
--- /dev/null
+++ b/test/com/sun/jndi/dns/IPv6NameserverPlatformParsingTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2015, Red Hat, Inc.
+ * 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.
+ *
+ * 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.
+ */
+
+import java.lang.reflect.Field;
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.spi.NamingManager;
+
+import com.sun.jndi.dns.DnsContext;
+
+/**
+ * @test
+ * @bug 6991580
+ * @summary IPv6 Nameservers in resolv.conf throws NumberFormatException
+ * @run main/manual IPv6NameserverPlatformParsingTest
+ *
+ * In order to run this test be sure to place, for example, the following
+ * snippet into your platform's {@code /etc/resolv.conf}:
+ * <pre>
+ * nameserver 127.0.0.1
+ * nameserver 2001:4860:4860::8888
+ * nameserver [::1]:5353
+ * nameserver 127.0.0.1:5353
+ * </pre>
+ *
+ * Then, run this test as manual jtreg test.
+ *
+ * @author Severin Gehwolf
+ *
+ */
+public class IPv6NameserverPlatformParsingTest {
+
+ private static boolean foundIPv6 = false;
+
+ public static void main(String[] args) {
+ Hashtable<String, String> env = new Hashtable<>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, com.sun.jndi.dns.DnsContextFactory.class.getName());
+
+ String[] servers;
+ try {
+ Context ctx = NamingManager.getInitialContext(env);
+ if (!com.sun.jndi.dns.DnsContextFactory.platformServersAvailable()) {
+ throw new RuntimeException("FAIL: no platform servers available, test does not make sense");
+ }
+ DnsContext context = (DnsContext)ctx;
+ servers = getServersFromContext(context);
+ } catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
+ for (String server: servers) {
+ System.out.println("DEBUG: 'nameserver = " + server + "'");
+ if (server.indexOf(':') >= 0 && server.indexOf('.') < 0) {
+ System.out.println("DEBUG: ==> Found IPv6 address in servers list: " + server);
+ foundIPv6 = true;
+ }
+ }
+ try {
+ new com.sun.jndi.dns.DnsClient(servers, 100, 1);
+ } catch (NumberFormatException e) {
+ throw new RuntimeException("FAIL: Tried to parse non-[]-encapsulated IPv6 address.", e);
+ } catch (Exception e) {
+ throw new RuntimeException("ERROR: Something unexpected happened.");
+ }
+ if (!foundIPv6) {
+ // This is a manual test, since it requires changing /etc/resolv.conf on Linux/Unix
+ // platforms. See comment as to how to run this test.
+ throw new RuntimeException("ERROR: No IPv6 address returned from platform.");
+ }
+ System.out.println("PASS: Found IPv6 address and DnsClient parsed it correctly.");
+ }
+
+ private static String[] getServersFromContext(DnsContext context) {
+ try {
+ Field serversField = DnsContext.class.getDeclaredField("servers");
+ serversField.setAccessible(true);
+ return (String[])serversField.get(context);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/test/com/sun/management/OperatingSystemMXBean/GetTotalSwapSpaceSize.java b/test/com/sun/management/OperatingSystemMXBean/GetTotalSwapSpaceSize.java
deleted file mode 100644
index 26d49cc..0000000
--- a/test/com/sun/management/OperatingSystemMXBean/GetTotalSwapSpaceSize.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2003, 2005, 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.
- *
- * 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.
- */
-
-/*
- *
- *
- * @bug 4858522
- * @summary Basic unit test of OperatingSystemMXBean.getTotalSwapSpaceSize()
- * @author Steve Bohne
- */
-
-/*
- * This test tests the actual swap size on linux and solaris.
- * The correct value should be checked manually:
- * Solaris:
- * 1. In a shell, enter the command: "swap -l"
- * 2. The value (reported in blocks) is in the "blocks" column.
- * Linux:
- * 1. In a shell, enter the command: "cat /proc/meminfo"
- * 2. The value (reported in bytes) is in "Swap" entry, "total" column.
- * Windows NT/XP/2000:
- * 1. Run Start->Accessories->System Tools->System Information.
- * 2. The value (reported in Kbytes) is in the "Page File Space" entry
- * Windows 98/ME:
- * Unknown.
- *
- * Usage: GetTotalSwapSpaceSize <expected swap size | "sanity-only"> [trace]
- */
-
-import com.sun.management.OperatingSystemMXBean;
-import java.lang.management.*;
-
-public class GetTotalSwapSpaceSize {
-
- private static OperatingSystemMXBean mbean =
- (com.sun.management.OperatingSystemMXBean)
- ManagementFactory.getOperatingSystemMXBean();
-
- // Careful with these values.
- // Min size for pass dynamically determined below.
- // zero if no swap space is configured.
- private static long min_size_for_pass = 0;
- private static final long MAX_SIZE_FOR_PASS = Long.MAX_VALUE;
-
- private static boolean trace = false;
-
- public static void main(String args[]) throws Exception {
- if (args.length > 1 && args[1].equals("trace")) {
- trace = true;
- }
-
- long expected_swap_size = 0;
-
- if (args.length < 1 || args.length > 2) {
- throw new IllegalArgumentException("Unexpected number of args " + args.length);
- }
-
-
- long min_size = mbean.getFreeSwapSpaceSize();
- if (min_size > 0) {
- min_size_for_pass = min_size;
- }
-
- long size = mbean.getTotalSwapSpaceSize();
-
- if (trace) {
- System.out.println("Total swap space size in bytes: " + size);
- }
-
- if (!args[0].matches("sanity-only")) {
- expected_swap_size = Long.parseLong(args[0]);
- if (size != expected_swap_size) {
- throw new RuntimeException("Expected total swap size : " +
- expected_swap_size +
- " but getTotalSwapSpaceSize returned: " +
- size);
- }
- }
-
- if (size < min_size_for_pass || size > MAX_SIZE_FOR_PASS) {
- throw new RuntimeException("Total swap space size " +
- "illegal value: " + size + " bytes " +
- "(MIN = " + min_size_for_pass + "; " +
- "MAX = " + MAX_SIZE_FOR_PASS + ")");
- }
-
- System.out.println("Test passed.");
- }
-}
diff --git a/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.java b/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.java
new file mode 100644
index 0000000..b21eb29
--- /dev/null
+++ b/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2003, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 4858522
+ * @summary Basic unit test of OperatingSystemMXBean.getTotalSwapSpaceSize()
+ *
+ * @library /lib/testlibrary
+ * @build TestTotalSwap jdk.testlibrary.*
+ * @run main TestTotalSwap
+ *
+ * @author Steve Bohne
+ * @author Jaroslav Bachorik
+ */
+
+/*
+ * This test tests the actual swap size on linux and solaris.
+ * The correct value should be checked manually:
+ * Solaris:
+ * 1. In a shell, enter the command: "swap -l"
+ * 2. The value (reported in blocks) is in the "blocks" column.
+ * Linux:
+ * 1. In a shell, enter the command: "cat /proc/meminfo"
+ * 2. The value (reported in bytes) is in "Swap" entry, "total" column.
+ * Windows NT/XP/2000:
+ * 1. Run Start->Accessories->System Tools->System Information.
+ * 2. The value (reported in Kbytes) is in the "Page File Space" entry
+ * Windows 98/ME:
+ * Unknown.
+ *
+ * Usage: GetTotalSwapSpaceSize <expected swap size | "sanity-only"> [trace]
+ */
+
+import com.sun.management.OperatingSystemMXBean;
+import java.lang.management.*;
+
+import jdk.testlibrary.OSInfo;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.OutputAnalyzer;
+
+public class TestTotalSwap {
+
+ private static final OperatingSystemMXBean mbean =
+ (com.sun.management.OperatingSystemMXBean)
+ ManagementFactory.getOperatingSystemMXBean();
+
+ // Careful with these values.
+ // Min size for pass dynamically determined below.
+ // zero if no swap space is configured.
+ private static long min_size_for_pass = 0;
+ private static final long MAX_SIZE_FOR_PASS = Long.MAX_VALUE;
+
+ public static void main(String args[]) throws Throwable {
+
+ long expected_swap_size = getSwapSizeFromOs();
+
+ long min_size = mbean.getFreeSwapSpaceSize();
+ if (min_size > 0) {
+ min_size_for_pass = min_size;
+ }
+
+ long size = mbean.getTotalSwapSpaceSize();
+
+ System.out.println("Total swap space size in bytes: " + size);
+
+ if (expected_swap_size > -1) {
+ if (size != expected_swap_size) {
+ throw new RuntimeException("Expected total swap size : " +
+ expected_swap_size +
+ " but getTotalSwapSpaceSize returned: " +
+ size);
+ }
+ }
+
+ // sanity check
+ if (size < min_size_for_pass || size > MAX_SIZE_FOR_PASS) {
+ throw new RuntimeException("Total swap space size " +
+ "illegal value: " + size + " bytes " +
+ "(MIN = " + min_size_for_pass + "; " +
+ "MAX = " + MAX_SIZE_FOR_PASS + ")");
+ }
+
+ System.out.println("Test passed.");
+ }
+
+ private static long getSwapSizeFromOs() throws Throwable {
+ OSInfo.OSType os = OSInfo.getOSType();
+
+ switch (os) {
+ // total used free shared buffers cached
+ // Mem: 16533540864 13638467584 2895073280 534040576 1630248960 6236909568
+ // -/+ buffers/cache: 5771309056 10762231808
+ // Swap: 15999168512 0 15999168512
+
+ case LINUX: {
+ String swapSizeStr = ProcessTools.executeCommand("free", "-b")
+ .firstMatch("Swap:\\s+([0-9]+)\\s+.*", 1);
+ return Long.parseLong(swapSizeStr);
+ }
+ case SOLARIS: {
+ // swapfile dev swaplo blocks free
+ // /dev/dsk/c0t0d0s1 136,1 16 1638608 1600528
+ OutputAnalyzer out= ProcessTools.executeCommand(
+ "/usr/sbin/swap",
+ "-l"
+ );
+
+ long swapSize = 0;
+
+ for (String line : out.asLines()) {
+ if (line.contains("swapfile")) continue;
+
+ String[] vals = line.split("\\s+");
+ if (vals.length == 5) {
+ swapSize += Long.parseLong(vals[3]) * 512; // size is reported in 512b blocks
+ }
+ }
+
+ return swapSize;
+ }
+ case MACOSX: {
+ // total = 8192.00M used = 7471.11M free = 720.89M (encrypted)
+ String swapSizeStr = ProcessTools.executeCommand(
+ "/usr/sbin/sysctl",
+ "-n",
+ "vm.swapusage"
+ ).firstMatch("total\\s+=\\s+([0-9]+(\\.[0-9]+)?[Mm]?).*", 1);
+ if (swapSizeStr.toLowerCase().endsWith("m")) {
+ swapSizeStr = swapSizeStr.substring(0, swapSizeStr.length() - 1);
+ return (long)(Double.parseDouble(swapSizeStr) * 1024 * 1024); // size in MB
+ }
+ return (long)(Double.parseDouble(swapSizeStr) * 1024 * 1024);
+ }
+ default: {
+ System.err.println("Unsupported operating system: " + os);
+ }
+ }
+
+ return -1;
+ }
+}
diff --git a/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.sh b/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.sh
deleted file mode 100644
index a4f3726..0000000
--- a/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.sh
+++ /dev/null
@@ -1,99 +0,0 @@
-#
-# Copyright (c) 2005, 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.
-#
-# 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.
-#
-
-#
-# @test
-# @summary Tests MM getTotalSwapSpaceSize() api.
-# @author Swamy V
-# @bug 6252770
-#
-# @run build GetTotalSwapSpaceSize
-# @run shell TestTotalSwap.sh
-#
-
-#
-# This test tests the actual swap size on linux and solaris.
-# On windows this is just a sanity check and correct size should
-# be checked manually:
-#
-# Windows NT/XP/2000:
-# 1. Run Start->Accessories->System Tools->System Information.
-# 2. The value (reported in Kbytes) is in the "Page File Space" entry
-# Windows 98/ME:
-# Unknown.
-#
-
-
-#set -x
-
-#Set appropriate jdk
-#
-
-if [ ! -z "${TESTJAVA}" ] ; then
- jdk="$TESTJAVA"
-else
- echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test."
- exit 1
-fi
-
-runOne()
-{
- echo "runOne $@"
- $TESTJAVA/bin/java ${TESTVMOPTS} -classpath $TESTCLASSES $@ || exit 3
-}
-
-solaris_swap_size()
-{
- total_swap=0
- for i in `/usr/sbin/swap -l | awk '{print $4}' | grep -v blocks`
- do
- # swap -l returns size in blocks of 512 bytes.
- total_swap=`expr $i \* 512 + $total_swap`
- done
-}
-
-# Test GetTotalSwapSpaceSize if we are running on Unix
-total_swap=0
-case `uname -s` in
- SunOS )
- solaris_swap_size
- runOne GetTotalSwapSpaceSize $total_swap
- ;;
- Linux )
- total_swap=`free -b | grep -i swap | awk '{print $2}'`
- runOne GetTotalSwapSpaceSize $total_swap
- ;;
- Darwin )
- # $ sysctl -n vm.swapusage
- # total = 8192.00M used = 7471.11M free = 720.89M (encrypted)
- swap=`/usr/sbin/sysctl -n vm.swapusage | awk '{ print $3 }' | awk -F . '{ print $1 }'` || exit 2
- total_swap=`expr $swap \* 1024 \* 1024` || exit 2
- runOne GetTotalSwapSpaceSize $total_swap
- ;;
- * )
- runOne GetTotalSwapSpaceSize "sanity-only"
- ;;
-esac
-
-exit 0
-
diff --git a/test/com/sun/net/httpserver/MissingTrailingSpace.java b/test/com/sun/net/httpserver/MissingTrailingSpace.java
new file mode 100644
index 0000000..5ecb074
--- /dev/null
+++ b/test/com/sun/net/httpserver/MissingTrailingSpace.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 8068795
+ * @summary HttpServer missing tailing space for some response codes
+ * @author lev.priima@oracle.com
+ */
+
+import java.net.InetSocketAddress;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+public class MissingTrailingSpace {
+
+ private static final int noMsgCode = 207;
+ private static final String someContext = "/context";
+
+ public static void main(String[] args) throws Exception {
+ HttpServer server = HttpServer.create(new InetSocketAddress(0), 0);
+ try {
+ server.setExecutor(Executors.newFixedThreadPool(1));
+ server.createContext(someContext, new HttpHandler() {
+ @Override
+ public void handle(HttpExchange msg) {
+ try {
+ try {
+ msg.sendResponseHeaders(noMsgCode, -1);
+ } catch(IOException ioe) {
+ ioe.printStackTrace();
+ }
+ } finally {
+ msg.close();
+ }
+ }
+ });
+ server.start();
+ System.out.println("Server started at port "
+ + server.getAddress().getPort());
+
+ runRawSocketHttpClient("localhost", server.getAddress().getPort());
+ } finally {
+ ((ExecutorService)server.getExecutor()).shutdown();
+ server.stop(0);
+ }
+ System.out.println("Server finished.");
+ }
+
+ static void runRawSocketHttpClient(String hostname, int port)
+ throws Exception
+ {
+ Socket socket = null;
+ PrintWriter writer = null;
+ BufferedReader reader = null;
+ final String CRLF = "\r\n";
+ try {
+ socket = new Socket(hostname, port);
+ writer = new PrintWriter(new OutputStreamWriter(
+ socket.getOutputStream()));
+ System.out.println("Client connected by socket: " + socket);
+
+ writer.print("GET " + someContext + "/ HTTP/1.1" + CRLF);
+ writer.print("User-Agent: Java/"
+ + System.getProperty("java.version")
+ + CRLF);
+ writer.print("Host: " + hostname + CRLF);
+ writer.print("Accept: */*" + CRLF);
+ writer.print("Connection: keep-alive" + CRLF);
+ writer.print(CRLF); // Important, else the server will expect that
+ // there's more into the request.
+ writer.flush();
+ System.out.println("Client wrote rquest to socket: " + socket);
+
+ reader = new BufferedReader(new InputStreamReader(
+ socket.getInputStream()));
+ System.out.println("Client start reading from server:" );
+ String line = reader.readLine();
+ if ( !line.endsWith(" ") ) {
+ throw new RuntimeException("respond to unknown code "
+ + noMsgCode
+ + " doesn't return space at the end of the first header.\n"
+ + "Should be: " + "\"" + line + " \""
+ + ", but returns: " + "\"" + line + "\".");
+ }
+ for (; line != null; line = reader.readLine()) {
+ if (line.isEmpty()) {
+ break;
+ }
+ System.out.println("\"" + line + "\"");
+ }
+ System.out.println("Client finished reading from server" );
+ } finally {
+ if (reader != null)
+ try {
+ reader.close();
+ } catch (IOException logOrIgnore) {
+ logOrIgnore.printStackTrace();
+ }
+ if (writer != null) {
+ writer.close();
+ }
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (IOException logOrIgnore) {
+ logOrIgnore.printStackTrace();
+ }
+ }
+ }
+ System.out.println("Client finished." );
+ }
+}
+
diff --git a/test/com/sun/nio/sctp/SctpMultiChannel/SendFailed.java b/test/com/sun/nio/sctp/SctpMultiChannel/SendFailed.java
new file mode 100644
index 0000000..be50b4e
--- /dev/null
+++ b/test/com/sun/nio/sctp/SctpMultiChannel/SendFailed.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/* @test
+ * @bug 8067846
+ * @summary Test for send failed notification
+ */
+
+import com.sun.nio.sctp.*;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import static java.lang.System.out;
+import static java.nio.ByteBuffer.*;
+
+public class SendFailed {
+
+ static final SocketAddress remoteAddress = new InetSocketAddress("127.0.0.1", 3000);
+
+ static final int[] bufferSizes =
+ { 20, 49, 50, 51, 100, 101, 1024, 1025, 4095, 4096, 4097, 8191, 8192, 8193};
+
+ void test(String[] args) throws IOException {
+ SocketAddress address = null;
+ String os = System.getProperty("os.name").toLowerCase();
+
+ if (!Util.isSCTPSupported()) {
+ out.println("SCTP protocol is not supported");
+ out.println("Test cannot be run");
+ return;
+ } else if (os.startsWith("sunos")) {
+ out.println("Test not supported on Solaris");
+ out.println("Test cannot be run");
+ return;
+ }
+
+ System.out.println("remote address: " + remoteAddress);
+ System.out.println("Note, remote address should not be up");
+
+ /* combinations with various buffer sizes, and offsets */
+ for (int send=0; send < bufferSizes.length; send++) {
+ for (int recv=0; recv < bufferSizes.length; recv++) {
+ for (boolean direct : new boolean[] {true, false})
+ runWithManyOffsets(bufferSizes[send], bufferSizes[recv], direct);
+ }
+ }
+ }
+
+ void runWithManyOffsets(int sendBufferSize, int recvBufferSize, boolean direct)
+ throws IOException
+ {
+ doTest(sendBufferSize, recvBufferSize, direct, 0);
+ doTest(sendBufferSize, recvBufferSize, direct, 1);
+ doTest(sendBufferSize, recvBufferSize, direct, 3);
+ doTest(sendBufferSize, recvBufferSize, direct, 7);
+ doTest(sendBufferSize, recvBufferSize, direct, 9);
+ doTest(sendBufferSize, recvBufferSize, direct, 13);
+ doTest(sendBufferSize, recvBufferSize, direct, 15);
+ }
+
+ void doTest(int sendBufferSize, int recvBufferSize, boolean direct, int offset)
+ throws IOException
+ {
+ debug("%n--- Testing with send size:[%d], recv size:[%d], offset:[%d] "
+ + ", direct [%s]. ", sendBufferSize, recvBufferSize, offset, direct);
+
+ try (SctpMultiChannel channel = SctpMultiChannel.open()) {
+ MessageInfo messageInfo = MessageInfo.createOutgoing(remoteAddress, 0);
+ ByteBuffer sendBuffer = filledBuffer(sendBufferSize, direct);
+
+ debug("%nAttempting to send to %s. ", remoteAddress);
+ int sent = channel.send(sendBuffer, messageInfo);
+ sendBuffer.flip();
+
+ SendFailedNotificationHandler handler =
+ new SendFailedNotificationHandler();
+ ByteBuffer recvBuffer = direct ? allocateDirect(recvBufferSize)
+ : allocate((recvBufferSize));
+ channel.receive(recvBuffer, null, handler);
+
+ // verify sent buffer received by send failed notification
+ ByteBuffer buffer = handler.getSendFailedByteBuffer();
+ check(buffer.remaining() == sent);
+ check(buffer.position() == 0);
+ check(buffer.limit() == sent);
+ assertSameContent(sendBuffer, handler.getSendFailedByteBuffer());
+ }
+ }
+
+ class SendFailedNotificationHandler extends AbstractNotificationHandler<Object>
+ {
+ /** Reference to the buffer captured in send failed notification */
+ private ByteBuffer sentBuffer;
+
+ @Override
+ public HandlerResult handleNotification(
+ Notification notification, Object attachment) {
+ fail("Unknown notification type");
+ return HandlerResult.CONTINUE;
+ }
+
+ @Override
+ public HandlerResult handleNotification(
+ AssociationChangeNotification notification, Object attachment) {
+ AssociationChangeNotification.AssocChangeEvent event = notification.event();
+ debug("%nAssociationChangeNotification");
+ debug("%n Association: %s. ", notification.association());
+ debug("%n Event: %s. ", event);
+ return HandlerResult.CONTINUE;
+ }
+
+ @Override
+ public HandlerResult handleNotification(
+ SendFailedNotification notification, Object attachment) {
+ debug("%nSendFailedNotification: %s. ", notification);
+ sentBuffer = notification.buffer();
+ return HandlerResult.RETURN;
+ }
+
+ public ByteBuffer getSendFailedByteBuffer() {
+ return sentBuffer;
+ }
+
+ @Override
+ public HandlerResult handleNotification(
+ PeerAddressChangeNotification pacn, Object attachment)
+ {
+ debug("%nPeerAddressChangeNotification: %s", pacn);
+ return HandlerResult.CONTINUE;
+ }
+
+ @Override
+ public HandlerResult handleNotification(
+ ShutdownNotification notification, Object attachment) {
+ debug("%nShutdownNotification");
+ debug("%n Association: %s. ", notification.association());
+ return HandlerResult.CONTINUE;
+ }
+ }
+
+ static ByteBuffer filledBuffer(int size, boolean direct) {
+ ByteBuffer buffer = direct ? allocateDirect(size) : allocate((size));
+ for (int i=0; i< size; i++)
+ buffer.put((byte)i);
+ buffer.flip();
+ return buffer;
+ }
+
+ static void assertSameContent(ByteBuffer bb1, ByteBuffer bb2) {
+ if (!bb1.equals(bb2))
+ throw new RuntimeException("Buffers are not equal; bb1: " + bb1 + ", bb2: " + bb2);
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ boolean debug = true;
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void check(boolean cond, String failMessage) {if (cond) pass(); else fail(failMessage);}
+ void debug(String message, Object... args) {if(debug) { out.printf(message, args); } }
+ public static void main(String[] args) throws Throwable {
+ Class<?> k = new Object(){}.getClass().getEnclosingClass();
+ try {k.getMethod("instanceMain",String[].class)
+ .invoke( k.newInstance(), (Object) args);}
+ catch (Throwable e) {throw e.getCause();}}
+ public void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/test/java/awt/Checkbox/SetStateExcessEvent/SetStateExcessEvent.java b/test/java/awt/Checkbox/SetStateExcessEvent/SetStateExcessEvent.java
new file mode 100644
index 0000000..f7235be
--- /dev/null
+++ b/test/java/awt/Checkbox/SetStateExcessEvent/SetStateExcessEvent.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.awt.Checkbox;
+import java.awt.CheckboxGroup;
+import java.awt.Frame;
+import java.awt.GridBagLayout;
+import java.awt.Robot;
+
+/**
+ * @test
+ * @bug 8074500
+ * @summary Checkbox.setState() call should not post ItemEvent
+ * @author Sergey Bylokhov
+ */
+public final class SetStateExcessEvent {
+
+ private static boolean failed;
+
+ public static void main(final String[] args) throws Exception {
+ final Robot robot = new Robot();
+ final CheckboxGroup group = new CheckboxGroup();
+ final Checkbox[] cbs = {new Checkbox("checkbox1", true, group),
+ new Checkbox("checkbox2", false, group),
+ new Checkbox("checkbox3", true, group),
+
+ new Checkbox("checkbox4", true),
+ new Checkbox("checkbox5", false),
+ new Checkbox("checkbox6", true)};
+ final Frame frame = new Frame();
+ frame.setLayout(new GridBagLayout());
+ try {
+ for (final Checkbox cb : cbs) {
+ cb.addItemListener(e -> {
+ failed = true;
+ });
+ }
+ for (final Checkbox cb : cbs) {
+ frame.add(cb);
+ }
+ frame.pack();
+
+ for (final Checkbox cb : cbs) {
+ cb.setState(!cb.getState());
+ }
+
+ for (final Checkbox cb : cbs) {
+ group.setSelectedCheckbox(cb);
+ }
+ robot.waitForIdle();
+ } finally {
+ frame.dispose();
+ }
+ if (failed) {
+ throw new RuntimeException("Listener should not be called");
+ }
+ System.out.println("Test passed");
+ }
+}
diff --git a/test/java/awt/Component/DimensionEncapsulation/DimensionEncapsulation.java b/test/java/awt/Component/DimensionEncapsulation/DimensionEncapsulation.java
new file mode 100644
index 0000000..3955453
--- /dev/null
+++ b/test/java/awt/Component/DimensionEncapsulation/DimensionEncapsulation.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.awt.Button;
+import java.awt.Canvas;
+import java.awt.Checkbox;
+import java.awt.Choice;
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.FileDialog;
+import java.awt.Frame;
+import java.awt.Label;
+import java.awt.List;
+import java.awt.Panel;
+import java.awt.ScrollPane;
+import java.awt.Scrollbar;
+import java.awt.TextArea;
+import java.awt.TextField;
+import java.awt.Window;
+import java.util.ArrayList;
+import java.util.Objects;
+
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JColorChooser;
+import javax.swing.JDesktopPane;
+import javax.swing.JDialog;
+import javax.swing.JEditorPane;
+import javax.swing.JFileChooser;
+import javax.swing.JFormattedTextField;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
+import javax.swing.JLayeredPane;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPasswordField;
+import javax.swing.JPopupMenu;
+import javax.swing.JProgressBar;
+import javax.swing.JRadioButton;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JRootPane;
+import javax.swing.JScrollPane;
+import javax.swing.JSeparator;
+import javax.swing.JSlider;
+import javax.swing.JSpinner;
+import javax.swing.JSplitPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.JTextPane;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import javax.swing.JTree;
+import javax.swing.JViewport;
+import javax.swing.JWindow;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UIManager.LookAndFeelInfo;
+import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.table.JTableHeader;
+
+import static javax.swing.UIManager.getInstalledLookAndFeels;
+
+/**
+ * @test
+ * @bug 6459798
+ * @author Sergey Bylokhov
+ */
+public final class DimensionEncapsulation implements Runnable {
+
+ java.util.List<Component> failures = new ArrayList<>();
+
+ public static void main(final String[] args) throws Exception {
+ for (final LookAndFeelInfo laf : getInstalledLookAndFeels()) {
+ SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf));
+ SwingUtilities.invokeAndWait(new DimensionEncapsulation());
+ }
+ }
+
+ @Override
+ public void run() {
+ runTest(new Panel());
+ runTest(new Button());
+ runTest(new Checkbox());
+ runTest(new Canvas());
+ runTest(new Choice());
+ runTest(new Label());
+ runTest(new Scrollbar());
+ runTest(new TextArea());
+ runTest(new TextField());
+ runTest(new Dialog(new JFrame()));
+ runTest(new Frame());
+ runTest(new Window(new JFrame()));
+ runTest(new FileDialog(new JFrame()));
+ runTest(new List());
+ runTest(new ScrollPane());
+ runTest(new JFrame());
+ runTest(new JDialog(new JFrame()));
+ runTest(new JWindow(new JFrame()));
+ runTest(new JLabel("hi"));
+ runTest(new JMenu());
+ runTest(new JTree());
+ runTest(new JTable());
+ runTest(new JMenuItem());
+ runTest(new JCheckBoxMenuItem());
+ runTest(new JToggleButton());
+ runTest(new JSpinner());
+ runTest(new JSlider());
+ runTest(Box.createVerticalBox());
+ runTest(Box.createHorizontalBox());
+ runTest(new JTextField());
+ runTest(new JTextArea());
+ runTest(new JTextPane());
+ runTest(new JPasswordField());
+ runTest(new JFormattedTextField());
+ runTest(new JEditorPane());
+ runTest(new JButton());
+ runTest(new JColorChooser());
+ runTest(new JFileChooser());
+ runTest(new JCheckBox());
+ runTest(new JInternalFrame());
+ runTest(new JDesktopPane());
+ runTest(new JTableHeader());
+ runTest(new JLayeredPane());
+ runTest(new JRootPane());
+ runTest(new JMenuBar());
+ runTest(new JOptionPane());
+ runTest(new JRadioButton());
+ runTest(new JRadioButtonMenuItem());
+ runTest(new JPopupMenu());
+ //runTest(new JScrollBar()); --> don't test defines max and min in
+ // terms of preferred
+ runTest(new JScrollPane());
+ runTest(new JViewport());
+ runTest(new JSplitPane());
+ runTest(new JTabbedPane());
+ runTest(new JToolBar());
+ runTest(new JSeparator());
+ runTest(new JProgressBar());
+ if (!failures.isEmpty()) {
+ System.out.println("These classes failed");
+ for (final Component failure : failures) {
+ System.out.println(failure.getClass());
+ }
+ throw new RuntimeException("Test failed");
+ }
+ }
+
+ public void runTest(final Component c) {
+ try {
+ test(c);
+ c.setMinimumSize(new Dimension(100, 10));
+ c.setMaximumSize(new Dimension(200, 20));
+ c.setPreferredSize(new Dimension(300, 30));
+ test(c);
+ } catch (final Throwable ignored) {
+ failures.add(c);
+ }
+ }
+
+ public void test(final Component component) {
+ final Dimension psize = component.getPreferredSize();
+ psize.width += 200;
+ if (Objects.equals(psize, component.getPreferredSize())) {
+ throw new RuntimeException("PreferredSize is wrong");
+ }
+ final Dimension msize = component.getMaximumSize();
+ msize.width += 200;
+ if (Objects.equals(msize, component.getMaximumSize())) {
+ throw new RuntimeException("MaximumSize is wrong");
+ }
+ final Dimension misize = component.getMinimumSize();
+ misize.width += 200;
+ if (Objects.equals(misize, component.getMinimumSize())) {
+ throw new RuntimeException("MinimumSize is wrong");
+ }
+ }
+
+ private static void setLookAndFeel(final LookAndFeelInfo laf) {
+ try {
+ UIManager.setLookAndFeel(laf.getClassName());
+ System.out.println("LookAndFeel: " + laf.getClassName());
+ } catch (ClassNotFoundException | InstantiationException |
+ UnsupportedLookAndFeelException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/java/awt/Component/InsetsEncapsulation/InsetsEncapsulation.java b/test/java/awt/Component/InsetsEncapsulation/InsetsEncapsulation.java
new file mode 100644
index 0000000..9a14a66
--- /dev/null
+++ b/test/java/awt/Component/InsetsEncapsulation/InsetsEncapsulation.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.awt.Component;
+import java.awt.Insets;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JColorChooser;
+import javax.swing.JComponent;
+import javax.swing.JDesktopPane;
+import javax.swing.JEditorPane;
+import javax.swing.JFileChooser;
+import javax.swing.JFormattedTextField;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
+import javax.swing.JLayeredPane;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPasswordField;
+import javax.swing.JPopupMenu;
+import javax.swing.JProgressBar;
+import javax.swing.JRadioButton;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JRootPane;
+import javax.swing.JScrollBar;
+import javax.swing.JScrollPane;
+import javax.swing.JSeparator;
+import javax.swing.JSlider;
+import javax.swing.JSpinner;
+import javax.swing.JSplitPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.JTextPane;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import javax.swing.JTree;
+import javax.swing.JViewport;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.table.JTableHeader;
+
+import static javax.swing.UIManager.LookAndFeelInfo;
+import static javax.swing.UIManager.getInstalledLookAndFeels;
+
+/**
+ * @test
+ * @bug 6459800
+ * @author Sergey Bylokhov
+ */
+public final class InsetsEncapsulation implements Runnable {
+
+ private final Collection<Component> failures = new ArrayList<>();
+
+ public static void main(final String[] args) throws Exception {
+ for (final LookAndFeelInfo laf : getInstalledLookAndFeels()) {
+ SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf));
+ SwingUtilities.invokeAndWait(new InsetsEncapsulation());
+ }
+ }
+
+ @Override
+ public void run() {
+ runTest(new JLabel("hi"));
+ runTest(new JMenu());
+ runTest(new JTree());
+ runTest(new JTable());
+ runTest(new JMenuItem());
+ runTest(new JCheckBoxMenuItem());
+ runTest(new JToggleButton());
+ runTest(new JSpinner());
+ runTest(new JSlider());
+ runTest(Box.createVerticalBox());
+ runTest(Box.createHorizontalBox());
+ runTest(new JTextField());
+ runTest(new JTextArea());
+ runTest(new JTextPane());
+ runTest(new JPasswordField());
+ runTest(new JFormattedTextField());
+ runTest(new JEditorPane());
+ runTest(new JButton());
+ runTest(new JColorChooser());
+ runTest(new JFileChooser());
+ runTest(new JCheckBox());
+ runTest(new JInternalFrame());
+ runTest(new JDesktopPane());
+ runTest(new JTableHeader());
+ runTest(new JLayeredPane());
+ runTest(new JRootPane());
+ runTest(new JMenuBar());
+ runTest(new JOptionPane());
+ runTest(new JRadioButton());
+ runTest(new JRadioButtonMenuItem());
+ runTest(new JPopupMenu());
+ runTest(new JScrollBar());
+ runTest(new JScrollPane());
+ runTest(new JViewport());
+ runTest(new JSplitPane());
+ runTest(new JTabbedPane());
+ runTest(new JToolBar());
+ runTest(new JSeparator());
+ runTest(new JProgressBar());
+ if (!failures.isEmpty()) {
+ System.out.println("These classes failed");
+ for (final Component failure : failures) {
+ System.out.println(failure.getClass());
+ }
+ throw new RuntimeException("Test failed");
+ }
+ }
+
+ void runTest(final JComponent component) {
+ try {
+ test(component);
+ } catch (final Throwable ignored) {
+ failures.add(component);
+ }
+ }
+
+ void test(final JComponent component) {
+ final Insets p = component.getInsets();
+ p.top += 3;
+ if (p.equals(component.getInsets())) {
+ throw new RuntimeException("Insets altered by altering Insets!");
+ }
+ }
+
+ private static void setLookAndFeel(final LookAndFeelInfo laf) {
+ try {
+ UIManager.setLookAndFeel(laf.getClassName());
+ System.out.println("LookAndFeel: " + laf.getClassName());
+ } catch (ClassNotFoundException | InstantiationException |
+ UnsupportedLookAndFeelException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/java/awt/Desktop/8064934/bug8064934.java b/test/java/awt/Desktop/8064934/bug8064934.java
new file mode 100644
index 0000000..8824f88
--- /dev/null
+++ b/test/java/awt/Desktop/8064934/bug8064934.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/* @test
+ * @bug 8064934
+ * @summary Incorrect Exception message from java.awt.Desktop.open()
+ * @author Dmitry Markov
+ * @run main bug8064934
+ */
+import sun.awt.OSInfo;
+
+import java.awt.*;
+import java.io.File;
+import java.io.IOException;
+import java.security.AccessController;
+
+public class bug8064934 {
+ private static final String NO_ASSOCIATION_ERROR_MESSAGE = "Error message: No application is associated with" +
+ " the specified file for this operation.";
+
+ public static void main(String[] args) {
+ // This test is intended only for Windows
+ if (AccessController.doPrivileged(OSInfo.getOSTypeAction()) != OSInfo.OSType.WINDOWS) {
+ System.out.println("The test is for Windows platform only");
+ return;
+ }
+
+ // Test whether Desktop is supported of not
+ if (!Desktop.isDesktopSupported()) {
+ System.out.println("Desktop is not supported");
+ return;
+ }
+
+ Desktop desktop = Desktop.getDesktop();
+ // Test whether open action is supported or not
+ if (!desktop.isSupported(Desktop.Action.OPEN)) {
+ System.out.println("Desktop.Action.OPEN is not supported");
+ return;
+ }
+
+ File file = null;
+ try {
+ file = File.createTempFile("test", ".foo");
+ if (!file.exists()) {
+ throw new RuntimeException("Can not create temp file");
+ }
+ desktop.open(file);
+ } catch (IOException ioe) {
+ String errorMessage = ioe.getMessage().trim();
+ if (errorMessage != null && !errorMessage.endsWith(NO_ASSOCIATION_ERROR_MESSAGE)) {
+ throw new RuntimeException("Test FAILED! Wrong Error message: \n" +
+ "Actual " + errorMessage.substring(errorMessage.indexOf("Error message:")) + "\n" +
+ "Expected " + NO_ASSOCIATION_ERROR_MESSAGE);
+ }
+ } finally {
+ if (file != null) {
+ file.delete();
+ }
+ }
+
+ System.out.println("Test PASSED!");
+ }
+}
diff --git a/test/java/awt/Focus/8073453/AWTFocusTransitionTest.java b/test/java/awt/Focus/8073453/AWTFocusTransitionTest.java
new file mode 100644
index 0000000..e4230b1
--- /dev/null
+++ b/test/java/awt/Focus/8073453/AWTFocusTransitionTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/* @test
+ * @bug 8073453
+ * @summary Focus doesn't move when pressing Shift + Tab keys
+ * @author Dmitry Markov
+ * @compile AWTFocusTransitionTest.java
+ * @run main/othervm AWTFocusTransitionTest
+ */
+import sun.awt.SunToolkit;
+
+import java.awt.*;
+import java.awt.event.KeyEvent;
+
+public class AWTFocusTransitionTest {
+ private static SunToolkit toolkit;
+ private static Robot robot;
+
+ private static Frame frame;
+ private static TextField textField;
+ private static Button button;
+
+ public static void main(String[] args) throws Exception {
+ toolkit = (SunToolkit)Toolkit.getDefaultToolkit();
+ robot = new Robot();
+ robot.setAutoDelay(50);
+
+ try {
+ createAndShowGUI();
+
+ toolkit.realSync();
+
+ checkFocusOwner(textField);
+
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ toolkit.realSync();
+
+ checkFocusOwner(button);
+
+ robot.keyPress(KeyEvent.VK_SHIFT);
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ robot.keyRelease(KeyEvent.VK_SHIFT);
+ toolkit.realSync();
+
+ checkFocusOwner(textField);
+
+ robot.keyPress(KeyEvent.VK_SHIFT);
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ robot.keyRelease(KeyEvent.VK_SHIFT);
+ toolkit.realSync();
+
+ checkFocusOwner(button);
+ } finally {
+ if (frame != null) {
+ frame.dispose();
+ }
+ }
+ System.out.println("Test Passed!");
+ }
+
+ private static void createAndShowGUI() {
+ frame = new Frame("AWTFocusTransitionTest");
+ frame.setSize(300, 300);
+ frame.setFocusTraversalPolicyProvider(true);
+ frame.setFocusTraversalPolicy(new DefaultFocusTraversalPolicy());
+
+ textField = new TextField();
+ button = new Button();
+
+ Panel panel = new Panel();
+ panel.setFocusTraversalPolicyProvider(true);
+ panel.setFocusTraversalPolicy(new DefaultFocusTraversalPolicy());
+
+ Panel p = new Panel();
+ p.setLayout(new GridLayout(3, 1));
+ p.add(textField);
+ p.add(button);
+ p.add(panel);
+
+ frame.add(p);
+ frame.setVisible(true);
+ }
+
+ private static void checkFocusOwner(Component component) {
+ if (component != frame.getFocusOwner()) {
+ throw new RuntimeException("Test Failed! Incorrect focus owner: " + frame.getFocusOwner() +
+ ", but expected: " + component);
+ }
+ }
+}
+
diff --git a/test/java/awt/Focus/8073453/SwingFocusTransitionTest.java b/test/java/awt/Focus/8073453/SwingFocusTransitionTest.java
new file mode 100644
index 0000000..ec15cd3
--- /dev/null
+++ b/test/java/awt/Focus/8073453/SwingFocusTransitionTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/* @test
+ * @bug 8073453
+ * @summary Focus doesn't move when pressing Shift + Tab keys
+ * @author Dmitry Markov
+ * @compile SwingFocusTransitionTest.java
+ * @run main/othervm SwingFocusTransitionTest
+ */
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.KeyEvent;
+
+public class SwingFocusTransitionTest {
+ private static SunToolkit toolkit;
+ private static Robot robot;
+
+ private static JFrame frame;
+ private static JTextField textField;
+ private static JButton button;
+
+ public static void main(String[] args) throws Exception {
+ toolkit = (SunToolkit)Toolkit.getDefaultToolkit();
+ robot = new Robot();
+ robot.setAutoDelay(50);
+
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+
+ toolkit.realSync();
+
+ checkFocusOwner(textField);
+
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ toolkit.realSync();
+
+ checkFocusOwner(button);
+
+ robot.keyPress(KeyEvent.VK_SHIFT);
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ robot.keyRelease(KeyEvent.VK_SHIFT);
+ toolkit.realSync();
+
+ checkFocusOwner(textField);
+
+ robot.keyPress(KeyEvent.VK_SHIFT);
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ robot.keyRelease(KeyEvent.VK_SHIFT);
+ toolkit.realSync();
+
+ checkFocusOwner(button);
+ } finally {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ if (frame != null) {
+ frame.dispose();
+ }
+ }
+ });
+ }
+ System.out.println("Test Passed!");
+ }
+
+ private static void createAndShowGUI() {
+ frame = new JFrame("SwingFocusTransitionTest");
+ frame.setSize(300, 300);
+ frame.setFocusTraversalPolicyProvider(true);
+ frame.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
+
+ textField = new JTextField();
+ button = new JButton();
+
+ JPanel panel = new JPanel();
+ panel.setFocusTraversalPolicyProvider(true);
+ panel.setFocusTraversalPolicy(new DefaultFocusTraversalPolicy());
+
+ JPanel p = new JPanel();
+ p.setLayout(new GridLayout(3, 1));
+ p.add(textField);
+ p.add(button);
+ p.add(panel);
+
+ frame.add(p);
+ frame.setVisible(true);
+ }
+
+ private static void checkFocusOwner(final Component component) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ if (component != frame.getFocusOwner()) {
+ throw new RuntimeException("Test Failed! Incorrect focus owner: " + frame.getFocusOwner() +
+ ", but expected: " + component);
+ }
+ }
+ });
+ }
+}
+
diff --git a/test/java/awt/GraphicsEnvironment/TestDetectHeadless/TestDetectHeadless.java b/test/java/awt/GraphicsEnvironment/TestDetectHeadless/TestDetectHeadless.java
new file mode 100644
index 0000000..7989776
--- /dev/null
+++ b/test/java/awt/GraphicsEnvironment/TestDetectHeadless/TestDetectHeadless.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+ * Portions Copyright (c) 2014 IBM Corporation
+ */
+
+public class TestDetectHeadless {
+ public static void main(String[] args) throws Exception {
+ Class.forName("javax.swing.plaf.basic.BasicInternalFrameTitlePane");
+ }
+}
diff --git a/test/java/awt/GraphicsEnvironment/TestDetectHeadless/TestDetectHeadless.sh b/test/java/awt/GraphicsEnvironment/TestDetectHeadless/TestDetectHeadless.sh
new file mode 100644
index 0000000..2e1fd42
--- /dev/null
+++ b/test/java/awt/GraphicsEnvironment/TestDetectHeadless/TestDetectHeadless.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+#
+# Copyright (c) 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.
+#
+# 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.
+#
+
+#
+# Portions Copyright (c) 2014 IBM Corporation
+#
+
+# @test
+# @bug 8058930 7077826
+# @summary java.awt.GraphicsEnvironment.getHeadlessProperty() does not work for AIX
+#
+# @build TestDetectHeadless
+# @run shell TestDetectHeadless.sh
+
+OS=`uname -s`
+case "$OS" in
+ Windows* | CYGWIN* | Darwin)
+ echo "Passed"; exit 0 ;;
+ * ) unset DISPLAY ;;
+esac
+
+${TESTJAVA}/bin/java ${TESTVMOPTS} \
+ -cp ${TESTCLASSES} TestDetectHeadless
+
+if [ $? -ne 0 ]; then
+ exit 1;
+fi
+
+DISPLAY=
+export DISPLAY
+
+${TESTJAVA}/bin/java ${TESTVMOPTS} \
+ -cp ${TESTCLASSES} TestDetectHeadless
+
+exit $?
diff --git a/test/java/awt/MenuBar/RemoveHelpMenu/RemoveHelpMenu.java b/test/java/awt/MenuBar/RemoveHelpMenu/RemoveHelpMenu.java
new file mode 100644
index 0000000..5d87f8e
--- /dev/null
+++ b/test/java/awt/MenuBar/RemoveHelpMenu/RemoveHelpMenu.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.awt.Frame;
+import java.awt.Menu;
+import java.awt.MenuBar;
+
+/**
+ * @test
+ * @bug 6475361
+ * @author Sergey Bylokhov
+ */
+public final class RemoveHelpMenu {
+
+ public static void main(final String[] args) {
+ final Frame frame = new Frame("RemoveHelpMenu Test");
+ try {
+ frame.pack();
+ // peer exists
+ test1(getMenuBar(frame));
+ test2(getMenuBar(frame));
+ test3(getMenuBar(frame));
+ test4(getMenuBar(frame));
+ } finally {
+ frame.dispose();
+ }
+ // peer is null
+ test1(getMenuBar(frame));
+ test2(getMenuBar(frame));
+ test3(getMenuBar(frame));
+ test4(getMenuBar(frame));
+ }
+
+ private static MenuBar getMenuBar(final Frame frame) {
+ final MenuBar menuBar = new MenuBar();
+ frame.setMenuBar(menuBar);
+ return menuBar;
+ }
+
+ private static void checkHelpMenu(final Menu menu, final boolean expected) {
+ final boolean actual = menu.toString().contains("isHelpMenu=true");
+ if (actual != expected) {
+ throw new RuntimeException("Incorrect menu type");
+ }
+ }
+
+ private static void checkMenuCount(final MenuBar bar, final int expected) {
+ final int actual = bar.getMenuCount();
+ if (actual != expected) {
+ throw new RuntimeException("Incorrect menus count");
+ }
+ }
+
+ private static void checkCurrentMenu(final MenuBar bar, final Menu menu) {
+ if (bar.getHelpMenu() != menu) {
+ throw new RuntimeException("Wrong HelpMenu");
+ }
+ }
+
+ private static void test1(final MenuBar menuBar) {
+ checkCurrentMenu(menuBar, null);
+ checkMenuCount(menuBar, 0);
+ }
+
+ private static void test2(final MenuBar menuBar) {
+ final Menu helpMenu = new Menu("Help Menu");
+ menuBar.setHelpMenu(helpMenu);
+ checkCurrentMenu(menuBar, helpMenu);
+ checkMenuCount(menuBar, 1);
+ checkHelpMenu(helpMenu, true);
+
+ menuBar.remove(helpMenu);
+ checkCurrentMenu(menuBar, null);
+ checkMenuCount(menuBar, 0);
+ checkHelpMenu(helpMenu, false);
+ }
+
+ private static void test3(final MenuBar menuBar) {
+ final Menu helpMenu1 = new Menu("Help Menu1");
+ final Menu helpMenu2 = new Menu("Help Menu2");
+ menuBar.setHelpMenu(helpMenu1);
+ checkCurrentMenu(menuBar, helpMenu1);
+ checkMenuCount(menuBar, 1);
+ checkHelpMenu(helpMenu1, true);
+ checkHelpMenu(helpMenu2, false);
+
+ menuBar.setHelpMenu(helpMenu2);
+ checkCurrentMenu(menuBar, helpMenu2);
+ checkMenuCount(menuBar, 1);
+ checkHelpMenu(helpMenu1, false);
+ checkHelpMenu(helpMenu2, true);
+
+ menuBar.remove(helpMenu2);
+ checkCurrentMenu(menuBar, null);
+ checkMenuCount(menuBar, 0);
+ checkHelpMenu(helpMenu1, false);
+ checkHelpMenu(helpMenu2, false);
+ }
+
+ private static void test4(final MenuBar menuBar) {
+ final Menu helpMenu = new Menu("Help Menu");
+ menuBar.setHelpMenu(helpMenu);
+ checkCurrentMenu(menuBar, helpMenu);
+ checkMenuCount(menuBar, 1);
+ checkHelpMenu(helpMenu, true);
+
+ menuBar.setHelpMenu(null);
+ checkCurrentMenu(menuBar, null);
+ checkMenuCount(menuBar, 0);
+ checkHelpMenu(helpMenu, false);
+ }
+}
\ No newline at end of file
diff --git a/test/java/awt/Mouse/RemovedComponentMouseListener/RemovedComponentMouseListener.java b/test/java/awt/Mouse/RemovedComponentMouseListener/RemovedComponentMouseListener.java
new file mode 100644
index 0000000..7c5d8b2
--- /dev/null
+++ b/test/java/awt/Mouse/RemovedComponentMouseListener/RemovedComponentMouseListener.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8061636
+ * @summary fix for 7079254 changes behavior of MouseListener, MouseMotionListener
+ * @library ../../regtesthelpers
+ * @build Util
+ * @author Alexander Zvegintsev
+ * @run main RemovedComponentMouseListener
+ */
+
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class RemovedComponentMouseListener extends JFrame {
+
+ static boolean mouseReleasedReceived;
+ static JButton button;
+
+ public RemovedComponentMouseListener() {
+ JPanel panel = new JPanel();
+ JPanel buttonPanel = new JPanel();
+ button = new JButton("Button");
+
+ setSize(300, 300);
+
+ buttonPanel.add(button);
+ panel.add(buttonPanel);
+ setContentPane(panel);
+
+ button.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mousePressed(MouseEvent e) {
+ buttonPanel.remove(button);
+ panel.add(button);
+ button.revalidate();
+ button.repaint();
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ mouseReleasedReceived = true;
+ }
+ });
+
+ setVisible(true);
+ }
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ new RemovedComponentMouseListener();
+ });
+
+ Robot r = Util.createRobot();
+ r.setAutoDelay(100);
+ r.waitForIdle();
+ Util.pointOnComp(button, r);
+
+ r.waitForIdle();
+ r.mousePress(InputEvent.BUTTON1_MASK);
+ r.waitForIdle();
+ r.mouseRelease(InputEvent.BUTTON1_MASK);
+ r.waitForIdle();
+ if (!mouseReleasedReceived) {
+ throw new RuntimeException("mouseReleased event was not received");
+ }
+ }
+}
diff --git a/test/java/awt/Multiscreen/MultiScreenInsetsTest/MultiScreenInsetsTest.java b/test/java/awt/Multiscreen/MultiScreenInsetsTest/MultiScreenInsetsTest.java
new file mode 100644
index 0000000..8005c03
--- /dev/null
+++ b/test/java/awt/Multiscreen/MultiScreenInsetsTest/MultiScreenInsetsTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+ @test
+ @bug 8020443
+ @summary Frame is not created on the specified GraphicsDevice with two
+monitors
+ @author Oleg Pekhovskiy
+ @run main MultiScreenInsetsTest
+ */
+
+import java.awt.Frame;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import sun.awt.OSInfo;
+
+public class MultiScreenInsetsTest {
+ private static final int SIZE = 100;
+
+ public static void main(String[] args) throws InterruptedException {
+ OSInfo.OSType type = OSInfo.getOSType();
+ if (type != OSInfo.OSType.LINUX && type != OSInfo.OSType.SOLARIS) {
+ System.out.println("This test is for Solaris and Linux only..." +
+ "skipping!");
+ return;
+ }
+
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice[] gds = ge.getScreenDevices();
+ if (gds.length < 2) {
+ System.out.println("It's a multi-screen test... skipping!");
+ return;
+ }
+
+ for (int screen = 0; screen < gds.length; ++screen) {
+ GraphicsDevice gd = gds[screen];
+ GraphicsConfiguration gc = gd.getDefaultConfiguration();
+ Rectangle bounds = gc.getBounds();
+ Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
+
+ Frame frame = new Frame(gc);
+ frame.setLocation(bounds.x + (bounds.width - SIZE) / 2,
+ bounds.y + (bounds.height - SIZE) / 2);
+ frame.setSize(SIZE, SIZE);
+ frame.setUndecorated(true);
+ frame.setVisible(true);
+
+ // Maximize Frame to reach the struts
+ frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
+ Thread.sleep(2000);
+
+ Rectangle frameBounds = frame.getBounds();
+ frame.dispose();
+ if (bounds.x + insets.left != frameBounds.x
+ || bounds.y + insets.top != frameBounds.y
+ || bounds.width - insets.right - insets.left != frameBounds.width
+ || bounds.height - insets.bottom - insets.top != frameBounds.height) {
+ throw new RuntimeException("Test FAILED! Wrong screen #" +
+ screen + " insets: " + insets);
+ }
+ }
+ System.out.println("Test PASSED!");
+ }
+}
diff --git a/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java b/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java
index 92de5f5..ec42aa9 100644
--- a/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java
+++ b/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java
@@ -23,21 +23,24 @@
import java.awt.Color;
import java.awt.Dialog;
+import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.SplashScreen;
+import java.awt.TextField;
import java.awt.Window;
+import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import sun.java2d.SunGraphics2D;
/**
- * test
- * @bug 8043869
+ * @test
+ * @bug 8043869 8075244 8078082
* @author Alexander Scherbatiy
* @summary [macosx] java -splash does not honor 2x hi dpi notation for retina
* support
@@ -45,6 +48,7 @@
* @run main/othervm -splash:splash1.png MultiResolutionSplashTest TEST_SPLASH 0
* @run main/othervm -splash:splash2 MultiResolutionSplashTest TEST_SPLASH 1
* @run main/othervm -splash:splash3. MultiResolutionSplashTest TEST_SPLASH 2
+ * @run main/othervm -splash:splash1.png MultiResolutionSplashTest TEST_FOCUS
*/
public class MultiResolutionSplashTest {
@@ -69,6 +73,9 @@
int index = Integer.parseInt(args[1]);
testSplash(tests[index]);
break;
+ case "TEST_FOCUS":
+ testFocus();
+ break;
default:
throw new RuntimeException("Unknown test: " + test);
}
@@ -92,12 +99,50 @@
float scaleFactor = getScaleFactor();
Color testColor = (1 < scaleFactor) ? test.color2x : test.color1x;
- if (!testColor.equals(splashScreenColor)) {
+ if (!compare(testColor, splashScreenColor)) {
throw new RuntimeException(
"Image with wrong resolution is used for splash screen!");
}
}
+ static void testFocus() throws Exception {
+
+ System.out.println("Focus Test!");
+ Robot robot = new Robot();
+ robot.setAutoDelay(50);
+
+ Frame frame = new Frame();
+ frame.setSize(100, 100);
+ String test = "123";
+ TextField textField = new TextField(test);
+ textField.selectAll();
+ frame.add(textField);
+ frame.setVisible(true);
+ robot.waitForIdle();
+
+ robot.keyPress(KeyEvent.VK_A);
+ robot.keyRelease(KeyEvent.VK_A);
+ robot.keyPress(KeyEvent.VK_B);
+ robot.keyRelease(KeyEvent.VK_B);
+ robot.waitForIdle();
+
+ frame.dispose();
+
+ if(!textField.getText().equals("ab")){
+ throw new RuntimeException("Focus is lost!");
+ }
+ }
+
+ static boolean compare(Color c1, Color c2){
+ return compare(c1.getRed(), c2.getRed())
+ && compare(c1.getGreen(), c2.getGreen())
+ && compare(c1.getBlue(), c2.getBlue());
+ }
+
+ static boolean compare(int n, int m){
+ return Math.abs(n - m) <= 50;
+ }
+
static float getScaleFactor() {
final Dialog dialog = new Dialog((Window) null);
diff --git a/test/java/awt/Toolkit/BadDisplayTest/BadDisplayTest.sh b/test/java/awt/Toolkit/BadDisplayTest/BadDisplayTest.sh
index e580728..acd3154 100644
--- a/test/java/awt/Toolkit/BadDisplayTest/BadDisplayTest.sh
+++ b/test/java/awt/Toolkit/BadDisplayTest/BadDisplayTest.sh
@@ -1,4 +1,4 @@
-# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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
@@ -21,23 +21,15 @@
${TESTJAVA}/bin/javac -cp ${TESTSRC} -d . ${TESTSRC}/BadDisplayTest.java
-
-DISPLAY=
-export DISPLAY
-
OS=`uname -s`
case "$OS" in
- SunOS )
- ${TESTJAVA}/bin/java BadDisplayTest
- ;;
- Linux )
- ${TESTJAVA}/bin/java BadDisplayTest
- ;;
- * )
- echo "Unsupported System: ${OS}"
- exit 0;
- ;;
+ Windows* | CYGWIN* | Darwin)
+ echo "Passed"; exit 0 ;;
esac
-exit $?
+DISPLAY=SomeBadDisplay
+export DISPLAY
+${TESTJAVA}/bin/java ${TESTVMOPTS} BadDisplayTest
+
+exit $?
diff --git a/test/java/awt/Toolkit/GetImage/bug8078165.java b/test/java/awt/Toolkit/GetImage/bug8078165.java
new file mode 100644
index 0000000..81ebc8a
--- /dev/null
+++ b/test/java/awt/Toolkit/GetImage/bug8078165.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+
+import java.awt.*;
+import java.net.URL;
+import java.security.Permission;
+
+
+/**
+ * @test
+ * @bug 8078165
+ * @summary NPE when attempting to get image from toolkit
+ * @author Anton Nashatyrev
+ */
+public final class bug8078165 {
+
+ public static void main(final String[] args) throws Exception {
+ // Mac only
+ System.setSecurityManager(new SecurityManager() {
+ @Override
+ public void checkPermission(Permission permission) {
+ // Just allows everything
+ }
+ });
+ // The method shouldn't throw NPE
+ Toolkit.getDefaultToolkit().getImage(new URL("file://./dummyImage@2x.png"));
+ Toolkit.getDefaultToolkit().getImage("./dummyImage@2x.png");
+ }
+}
diff --git a/test/java/awt/TrayIcon/8072769/bug8072769.java b/test/java/awt/TrayIcon/8072769/bug8072769.java
new file mode 100644
index 0000000..defdf07
--- /dev/null
+++ b/test/java/awt/TrayIcon/8072769/bug8072769.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/* @test
+ @bug 8072769
+ @summary System tray icon title freezes java
+ @author Semyon Sadetsky
+ @library ../../../../lib/testlibrary
+ @build jdk.testlibrary.OSInfo
+ @run main bug8072769
+ */
+
+import jdk.testlibrary.OSInfo;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Arrays;
+
+public class bug8072769 {
+
+ public static void main(String[] args) throws Exception {
+ if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS) {
+ if (SystemTray.isSupported()) {
+ test();
+ } else {
+ System.out.println("SystemTray not supported. " +
+ "Test is skipped.");
+ }
+ } else {
+ System.out.println("Test will only run on Windows platform. " +
+ "Test is skipped.");
+ }
+ System.out.println("ok");
+ }
+
+ private static void test() throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ final SystemTray tray = SystemTray.getSystemTray();
+ final TrayIcon trayIcon = new TrayIcon(icon.getImage());
+ try {
+ tray.add(trayIcon);
+ } catch (AWTException e) {
+ throw new RuntimeException(
+ "TrayIcon could not be added.");
+ }
+
+
+ try {
+ trayIcon.displayMessage(createString(63, 'A'),
+ createString(255, 'C'), TrayIcon.MessageType.ERROR);
+
+ trayIcon.setToolTip(createString(127, 'B'));
+
+ trayIcon.displayMessage(createString(64, 'A'),
+ createString(256, 'C'), TrayIcon.MessageType.ERROR);
+
+ trayIcon.setToolTip(createString(128, 'B'));
+
+ trayIcon.displayMessage(createString(65, 'A'),
+ createString(257, 'C'), TrayIcon.MessageType.ERROR);
+
+ trayIcon.setToolTip(createString(129, 'B'));
+ }
+ finally {
+ tray.remove(trayIcon);
+ }
+ }
+ });
+ }
+
+ private static String createString(int len, char letter) {
+ char[] chars = new char[len];
+ Arrays.fill(chars, letter);
+ chars[len - 2] = '=';
+ chars[len - 1] = '>';
+ return new String(chars);
+ }
+
+ private static ImageIcon icon = new ImageIcon(
+ new byte[]{71, 73, 70, 56, 57, 97, 32, 0, 35, 0, -43, 0, 0, -1, -1,
+ -1, -19, -101, 9, -18, -95, 24, -14, -76, 71, -4, -19, -46,
+ -3, -13, -31, -17, -88, 40, -12, -63, 102, -10, -51, -124,
+ -16, -82, 55, -11, -57, 117, -2, -7, -15, -7, -32, -77, -9,
+ -45, -108, -5, -26, -62, -13, -70, 86, -8, -39, -94, 83,
+ -126, -95, -8, -38, -93, -6, -26, -63, -9, -45, -109, -4,
+ -14, -32, -15, -76, 70, -12, -58, 116, -17, -89, 39, 77,
+ 121, -106, -3, -8, -17, 104, -111, -84, 126, -95, -72, 93,
+ -119, -90, -14, -70, 85, -13, -64, 101, -16, -83, 55, -109,
+ -80, -60, -7, -33, -78, -100, -84, -85, 94, -127, -104, -32,
+ -99, 39, 127, -120, -114, 83, 113, -124, -12, -9, -7, -16,
+ -16, -16, -115, 108, 45, 57, 89, 110, -50, -41, -35, 104,
+ -111, -83, 41, 65, 80, 72, 113, -116, 115, -103, -78, 88,
+ 106, 112, -82, -78, -82, -45, -38, -40, -5, -20, -48, -65,
+ -48, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, -7, 4, 0, 0, 0,
+ 0, 0, 44, 0, 0, 0, 0, 32, 0, 35, 0, 0, 6, -1, 64, -128, 112,
+ 72, 4, 16, 0, 14, -57, 2, 1, 96, 30, -117, -48, 40, -78,
+ -55, 96, 28, 28, -125, -62, 0, 96, 48, 74, -91, -116, 102,
+ 3, 97, 64, 4, 20, -25, -128, 68, -80, 16, 24, 11, 95, 98,
+ -29, -64, 72, 11, 2, 120, -68, 96, -64, 39, 116, -29, 0, 12,
+ 13, 5, 1, 3, 121, -121, -120, 9, 2, 7, 5, 15, 82, 11, 11,
+ 92, 15, 6, -120, -107, -121, 7, 2, 18, 0, 112, 80, 3, 8,
+ 104, -106, -95, 122, 88, 97, 68, 5, 11, 4, -95, 32, 8, 16,
+ 19, 16, 8, 22, -106, -114, 79, 66, 5, 2, 15, 9, -120, 22,
+ 19, 81, 21, 31, -120, 7, 6, 10, 67, 71, 4, 119, -121, 20,
+ -128, 16, -57, 120, 7, -101, -111, -58, 9, -108, 121, -55,
+ -128, 0, 16, 121, 123, -117, 67, 5, -71, 121, 30, -42, 67,
+ 23, -121, 13, 66, 14, 6, 3, -34, 120, 21, -31, 66, 26, -39,
+ 3, 6, -50, 11, -96, 120, 31, -19, 67, 30, 121, 9, 14, 0, 13,
+ 124, -121, 68, -32, 19, 98, 6, 15, 58, 71, 18, 12, -27, 97,
+ 55, 80, 68, 54, 5, 5, 24, 40, 80, 23, 96, -96, -112, 9, -39,
+ 30, 52, -112, 72, -47, 34, 0, 10, 25, -53, 37, 60, -60, 16,
+ -33, 56, 61, 16, -1, 41, -60, 83, 13, 31, -122, 60, 7, 1,
+ -48, 59, -124, 65, 3, 62, -116, 48, -5, 57, 72, -112, -18,
+ -48, 5, -103, 124, 32, -32, 37, 112, -74, -119, 98, 0, 8,
+ -31, 64, -110, 35, 38, 64, 26, 34, -92, 113, 42, 48, -45,
+ 70, -76, 24, -77, 60, 80, -91, -60, -70, -12, 76, -120, 49,
+ 92, -120, 4, -40, -116, -126, 51, 79, -80, 97, -36, 80, 89,
+ -6, 25, -91, 96, -98, 89, -99, 62, 33, -62, 32, -59, -83, 0,
+ 82, 80, 32, 1, -72, 53, 13, -113, -42, 102, -103, 54, -127,
+ 25, 84, 40, 15, -115, 40, 37, 20, 49, 34, 26, 103, 78, 29,
+ 52, 42, 88, 16, 65, 17, -94, -49, 31, 107, 97, 16, -116, 49,
+ 32, 35, -61, 6, 14, 33, 56, 68, -120, -80, -96, 11, 1, 78,
+ -31, -6, 33, 96, 48, -93, -61, -122, 21, 46, 50, -116, -10,
+ -30, -47, -117, -125, 24, 29, 94, -100, -112, 61, -94, 54,
+ -108, 20, 38, 90, -112, -128, 81, -61, 90, 16, 0, 59},
+ "try icon");
+
+}
diff --git a/test/java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java b/test/java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java
new file mode 100644
index 0000000..d47a7b0
--- /dev/null
+++ b/test/java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import sun.awt.image.MultiResolutionToolkitImage;
+import sun.java2d.SunGraphics2D;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+
+import static java.awt.event.InputEvent.BUTTON1_DOWN_MASK;
+
+/**
+ * @test
+ * @bug 8076106
+ * @author Hendrik Schreiber
+ * @summary [macosx] Drag image of TransferHandler does not honor
+ * MultiResolutionImage
+ * @run main MultiResolutionDragImageTest TEST_DRAG
+ */
+public class MultiResolutionDragImageTest {
+
+ private static final Color COLOR_1X = Color.BLUE;
+ private static final Color COLOR_2X = Color.RED;
+ private static JFrame frame;
+ private static JTextField field;
+ private static Point p;
+
+ public static void main(String[] args) throws Exception {
+
+ final String test = args[0];
+
+ switch (test) {
+ case "TEST_DRAG":
+ testDrag();
+ break;
+ default:
+ throw new RuntimeException("Unknown test: " + test);
+ }
+ }
+
+ private static void testDrag() throws Exception {
+
+
+ SwingUtilities.invokeAndWait(() -> {
+
+ frame = new JFrame();
+ field = new JTextField("Drag Me");
+ setupFrame(frame, field);
+ frame.setVisible(true);
+ });
+
+ final Robot robot = new Robot();
+ robot.setAutoDelay(500);
+ robot.setAutoWaitForIdle(true);
+ robot.waitForIdle();
+
+ // get mouse into position
+ SwingUtilities.invokeAndWait(() -> {
+
+ p = new Point(field.getWidth() / 2, field.getHeight() / 2);
+ SwingUtilities.convertPointToScreen(p, field);
+ });
+
+ robot.mouseMove(p.x, p.y);
+ // simulate dragging
+ robot.mousePress(BUTTON1_DOWN_MASK);
+ p.translate(10, 10);
+ robot.mouseMove(p.x, p.y);
+
+ p.translate(5, 5);
+ final Color color = robot.getPixelColor(p.x, p.y);
+ robot.mouseRelease(BUTTON1_DOWN_MASK);
+
+ SwingUtilities.invokeAndWait(frame::dispose);
+
+ final float scaleFactor = getScaleFactor();
+ final Color testColor = (1 < scaleFactor) ? COLOR_2X : COLOR_1X;
+
+ if (!similar(testColor, color)) {
+ throw new RuntimeException(
+ "TEST FAILED: Image with wrong resolution is used for drag image!");
+ }
+ System.out.println("TEST PASSED!");
+ }
+
+ private static void setupFrame(final JFrame frame, final JTextField field) {
+
+ frame.setBounds(0, 0, 50, 50);
+ frame.setLayout(new BorderLayout());
+ field.setDragEnabled(true);
+ final TransferHandler transferHandler = field.getTransferHandler();
+ transferHandler.setDragImage(createMultiResolutionImage());
+ frame.getContentPane().add(field, BorderLayout.CENTER);
+ }
+
+ private static boolean similar(Color c1, Color c2){
+ return similar(c1.getRed(), c2.getRed())
+ && similar(c1.getGreen(), c2.getGreen())
+ && similar(c1.getBlue(), c2.getBlue());
+ }
+
+ private static boolean similar(int n, int m){
+ return Math.abs(n - m) <= 80;
+ }
+
+ private static float getScaleFactor() {
+
+ final Dialog dialog = new Dialog((Window) null);
+ dialog.setSize(100, 100);
+ dialog.setModal(true);
+ final float[] scaleFactors = new float[1];
+ Panel panel = new Panel() {
+
+ @Override
+ public void paint(Graphics g) {
+ float scaleFactor = 1;
+ if (g instanceof SunGraphics2D) {
+ scaleFactor = ((SunGraphics2D) g).surfaceData.getDefaultScale();
+ }
+ scaleFactors[0] = scaleFactor;
+ dialog.setVisible(false);
+ }
+ };
+
+ dialog.add(panel);
+ dialog.setVisible(true);
+ dialog.dispose();
+
+ return scaleFactors[0];
+ }
+
+ private static Image createMultiResolutionImage() {
+
+ return new MultiResolutionToolkitImage(
+ createImage(50, COLOR_1X),
+ createImage(100, COLOR_2X)
+ );
+
+ }
+
+ private static Image createImage(final int length, final Color color) {
+
+ final BufferedImage image = new BufferedImage(length, length,
+ BufferedImage.TYPE_INT_ARGB_PRE);
+ final Graphics graphics = image.getGraphics();
+ graphics.setColor(color);
+ graphics.fillRect(0, 0, length, length);
+ graphics.dispose();
+ return image;
+ }
+}
\ No newline at end of file
diff --git a/test/java/awt/image/BufferedImage/GetPropertyNames.java b/test/java/awt/image/BufferedImage/GetPropertyNames.java
new file mode 100644
index 0000000..244da3a
--- /dev/null
+++ b/test/java/awt/image/BufferedImage/GetPropertyNames.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.util.Properties;
+
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+
+/**
+ * @test
+ * @bug 8066132
+ * @author Sergey Bylokhov
+ */
+public final class GetPropertyNames {
+
+ static BufferedImage defaultProps = new BufferedImage(1, 1, TYPE_INT_ARGB);
+
+ public static void main(final String[] args) {
+ // default result is null
+ if (defaultProps.getPropertyNames() != null) {
+ throw new RuntimeException("PropertyNames should be null");
+ }
+ // for null properties result is null
+ final BufferedImage emptyProps = getBufferedImage(null);
+ if (emptyProps.getPropertyNames() != null) {
+ throw new RuntimeException("PropertyNames should be null");
+ }
+ // for empty properties result is null
+ final BufferedImage nullProps = getBufferedImage(new Properties());
+ if (nullProps.getPropertyNames() != null) {
+ throw new RuntimeException("PropertyNames should be null");
+ }
+ // for non-string keys result is null
+ final Properties properties = new Properties();
+ properties.put(1, 1);
+ properties.put(2, 2);
+ properties.put(3, 3);
+ final BufferedImage nonStringProps = getBufferedImage(properties);
+ if (nonStringProps.getPropertyNames() != null) {
+ throw new RuntimeException("PropertyNames should be null");
+ }
+ // for string keys result is not null
+ properties.clear();
+ properties.setProperty("1", "1");
+ properties.setProperty("2", "2");
+ validate(getBufferedImage(properties), 2);
+ // for the mix of strings and objects result is not null
+ properties.clear();
+ properties.put(1, 1);
+ properties.put(2, 2);
+ properties.put(3, 3);
+ properties.setProperty("key1", "value1");
+ properties.setProperty("key2", "value2");
+ final BufferedImage mixProps = getBufferedImage(properties);
+ validate(mixProps, 2);
+ if (!"value1".equals(mixProps.getProperty("key1"))
+ || !"value2".equals(mixProps.getProperty("key2"))) {
+ throw new RuntimeException("Wrong key-value pair");
+ }
+ }
+
+
+ private static BufferedImage getBufferedImage(final Properties properties) {
+ return new BufferedImage(defaultProps.getColorModel(),
+ defaultProps.getRaster(),
+ defaultProps.isAlphaPremultiplied(),
+ properties);
+ }
+
+ private static void validate(final BufferedImage bi, final int expected) {
+ final String[] names = bi.getPropertyNames();
+ if (names.length != expected) {
+ throw new RuntimeException("Wrong number of names");
+ }
+ for (final String name : names) {
+ final Object property = bi.getProperty(name);
+ if (property == Image.UndefinedProperty || property == null) {
+ throw new RuntimeException("Unexpected property");
+ }
+ }
+ }
+}
diff --git a/test/java/awt/print/PageFormat/ImageableAreaTest.java b/test/java/awt/print/PageFormat/ImageableAreaTest.java
new file mode 100644
index 0000000..f9e7b4b
--- /dev/null
+++ b/test/java/awt/print/PageFormat/ImageableAreaTest.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dialog;
+import java.awt.FlowLayout;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.text.MessageFormat;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.standard.Copies;
+import javax.print.attribute.standard.DialogTypeSelection;
+import javax.print.attribute.standard.MediaPrintableArea;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableModel;
+
+/**
+ * @test
+ * @bug 8044444
+ * @summary The output's 'Page-n' footer does not show completely
+ * @author Alexandr Scherbatiy
+ * @run main/manual ImageableAreaTest
+ */
+public class ImageableAreaTest {
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+
+ createAndShowTestDialog(
+ "1. Press the Print Table button\n"
+ + " Java print dialog should appear.\n"
+ + "2. Press the Print button on the Java Print dialog.\n"
+ + "2. Check that the page number is correctly printed.\n"
+ + "If so, press PASS, else press FAIL.",
+ "Page number is not correctly printed!",
+ ImageableAreaTest::printWithJavaPrintDialog);
+
+ createAndShowTestDialog(
+ "1. Press the Print Table button\n"
+ + " The table should be printed without the print dialog.\n"
+ + "2. Check that the page number is correctly printed.\n"
+ + "If so, press PASS, else press FAIL.",
+ "Page number is not correctly printed!",
+ ImageableAreaTest::printWithoutPrintDialog);
+
+ createAndShowTestDialog(
+ "1. Press the Print Table button\n"
+ + " Java print dialog should appear.\n"
+ + "2. Press the Print button on the Java Print dialog.\n"
+ + "3. Check that the table has about half size of the printed page\n"
+ + "If so, press PASS, else press FAIL.",
+ "Custom imageable area is not correctly printed!",
+ ImageableAreaTest::printWithCustomImageareaSize);
+ }
+ });
+ }
+
+ private static void printWithJavaPrintDialog() {
+ final JTable table = createAuthorTable(42);
+ Printable printable = table.getPrintable(
+ JTable.PrintMode.NORMAL,
+ new MessageFormat("Author Table"),
+ new MessageFormat("Page - {0}"));
+
+ PrinterJob job = PrinterJob.getPrinterJob();
+ job.setPrintable(printable);
+
+ boolean printAccepted = job.printDialog();
+ if (printAccepted) {
+ try {
+ job.print();
+ closeFrame();
+ } catch (PrinterException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private static void printWithoutPrintDialog() {
+
+ final JTable table = createAuthorTable(42);
+ PrintRequestAttributeSet pras
+ = new HashPrintRequestAttributeSet();
+ pras.add(new Copies(1));
+
+ try {
+
+ boolean printAccepted = table.print(JTable.PrintMode.FIT_WIDTH,
+ new MessageFormat("Author Table"),
+ new MessageFormat("Page - {0}"),
+ false, pras, false);
+
+ closeFrame();
+ if (!printAccepted) {
+ throw new RuntimeException("User cancels the printer job!");
+ }
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static void printWithCustomImageareaSize() {
+ final JTable table = createAuthorTable(18);
+ PrintRequestAttributeSet printAttributes = new HashPrintRequestAttributeSet();
+ printAttributes.add(DialogTypeSelection.NATIVE);
+ printAttributes.add(new Copies(1));
+ printAttributes.add(new MediaPrintableArea(
+ 0.25f, 0.25f, 8.0f, 5.0f, MediaPrintableArea.INCH));
+ Printable printable = table.getPrintable(
+ JTable.PrintMode.NORMAL,
+ new MessageFormat("Author Table"),
+ new MessageFormat("Page - {0}")
+ );
+
+ PrinterJob job = PrinterJob.getPrinterJob();
+ job.setPrintable(printable);
+
+ boolean printAccepted = job.printDialog(printAttributes);
+ if (printAccepted) {
+ try {
+ job.print(printAttributes);
+ closeFrame();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ throw new RuntimeException("User cancels the printer job!");
+ }
+ }
+
+ private static JFrame frame;
+
+ private static void closeFrame() {
+ if (frame != null) {
+ frame.setVisible(false);
+ frame.dispose();
+ }
+ }
+
+ private static JTable createAuthorTable(int rows) {
+ final String[] headers = {"Book", "Title"};
+
+ final Object[][] data = new Object[rows][2];
+ for (int i = 0; i < rows; i++) {
+ int n = i + 1;
+ data[i] = new Object[]{"Book: " + n, "Title: " + n};
+ }
+
+ TableModel dataModel = new AbstractTableModel() {
+
+ public int getColumnCount() {
+ return headers.length;
+ }
+
+ public int getRowCount() {
+ return data.length;
+ }
+
+ public Object getValueAt(int row, int col) {
+ return data[row][col];
+ }
+
+ public String getColumnName(int column) {
+ return headers[column];
+ }
+
+ public Class getColumnClass(int col) {
+ return getValueAt(0, col).getClass();
+ }
+
+ public void setValueAt(Object aValue, int row, int column) {
+ data[row][column] = aValue;
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+ };
+
+ JTable table = new JTable(dataModel);
+ table.setGridColor(Color.BLUE);
+ table.setBackground(Color.WHITE);
+ table.setForeground(Color.BLACK);
+ table.setSize(600, 800);
+
+ frame = new JFrame();
+ frame.setSize(400, 600);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.add(table);
+ frame.setVisible(true);
+ return table;
+ }
+
+ private static int testCount;
+
+ private static void createAndShowTestDialog(String description,
+ String failMessage, Runnable action) {
+ final JDialog dialog = new JDialog();
+ dialog.setTitle("Test: " + (++testCount));
+ dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
+ JTextArea textArea = new JTextArea(description);
+ textArea.setEditable(false);
+ final JButton testButton = new JButton("Print Table");
+ final JButton passButton = new JButton("PASS");
+ passButton.setEnabled(false);
+ passButton.addActionListener((e) -> {
+ dialog.dispose();
+ });
+ final JButton failButton = new JButton("FAIL");
+ failButton.setEnabled(false);
+ failButton.addActionListener((e) -> {
+ throw new RuntimeException(failMessage);
+ });
+ testButton.addActionListener((e) -> {
+ testButton.setEnabled(false);
+ action.run();
+ passButton.setEnabled(true);
+ failButton.setEnabled(true);
+ });
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(textArea, BorderLayout.CENTER);
+ JPanel buttonPanel = new JPanel(new FlowLayout());
+ buttonPanel.add(testButton);
+ buttonPanel.add(passButton);
+ buttonPanel.add(failButton);
+ mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+ dialog.add(mainPanel);
+ dialog.pack();
+ dialog.setVisible(true);
+ }
+}
diff --git a/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java b/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java
new file mode 100644
index 0000000..504dcb4
--- /dev/null
+++ b/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.io.File;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.ReflectPermission;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.PropertyPermission;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.stream.Stream;
+
+/**
+ * @test
+ * @bug 8065552
+ * @summary test that all fields returned by getDeclaredFields() can be
+ * set accessible if the right permission is granted; this test
+ * loads all the classes in the BCL, get their declared fields,
+ * and call setAccessible(false) followed by setAccessible(true);
+ * @run main/othervm FieldSetAccessibleTest UNSECURE
+ * @run main/othervm FieldSetAccessibleTest SECURE
+ *
+ * @author danielfuchs
+ */
+public class FieldSetAccessibleTest {
+
+ static final List<String> skipped = new ArrayList<>();
+ static final List<String> cantread = new ArrayList<>();
+ static final List<String> failed = new ArrayList<>();
+ static final AtomicLong classCount = new AtomicLong();
+ static final AtomicLong fieldCount = new AtomicLong();
+ static long startIndex = 0;
+ static long maxSize = Long.MAX_VALUE;
+ static long maxIndex = Long.MAX_VALUE;
+
+
+ // Test that all fields for any given class can be made accessibles
+ static void testSetFieldsAccessible(Class<?> c) {
+ for (Field f : c.getDeclaredFields()) {
+ fieldCount.incrementAndGet();
+ f.setAccessible(false);
+ f.setAccessible(true);
+ }
+ }
+
+ // Performs a series of test on the given class.
+ // At this time, we only call testSetFieldsAccessible(c)
+ public static boolean test(Class<?> c) {
+ //System.out.println(c.getName());
+ classCount.incrementAndGet();
+
+ // Call getDeclaredFields() and try to set their accessible flag.
+ testSetFieldsAccessible(c);
+
+ // add more tests here...
+
+ return c == Class.class;
+ }
+
+ // Prints a summary at the end of the test.
+ static void printSummary(long secs, long millis, long nanos) {
+ System.out.println("Tested " + fieldCount.get() + " fields of "
+ + classCount.get() + " classes in "
+ + secs + "s " + millis + "ms " + nanos + "ns");
+ }
+
+
+ /**
+ * @param args the command line arguments:
+ *
+ * SECURE|UNSECURE [startIndex (default=0)] [maxSize (default=Long.MAX_VALUE)]
+ *
+ * @throws java.lang.Exception if the test fails
+ */
+ public static void main(String[] args) throws Exception {
+ if (args == null || args.length == 0) {
+ args = new String[] {"SECURE", "0"};
+ } else if (args.length > 3) {
+ throw new RuntimeException("Expected at most one argument. Found "
+ + Arrays.asList(args));
+ }
+ try {
+ if (args.length > 1) {
+ startIndex = Long.parseLong(args[1]);
+ if (startIndex < 0) {
+ throw new IllegalArgumentException("startIndex args[1]: "
+ + startIndex);
+ }
+ }
+ if (args.length > 2) {
+ maxSize = Long.parseLong(args[2]);
+ if (maxSize <= 0) {
+ maxSize = Long.MAX_VALUE;
+ }
+ maxIndex = (Long.MAX_VALUE - startIndex) < maxSize
+ ? Long.MAX_VALUE : startIndex + maxSize;
+ }
+ TestCase.valueOf(args[0]).run();
+ } catch (OutOfMemoryError oome) {
+ System.err.println(classCount.get());
+ throw oome;
+ }
+ }
+
+ public static void run(TestCase test) {
+ System.out.println("Testing " + test);
+ test(listAllClassNames());
+ System.out.println("Passed " + test);
+ }
+
+ static Iterable<String> listAllClassNames() {
+ return new ClassNameStreamBuilder();
+ }
+
+ static void test(Iterable<String> iterable) {
+ final long start = System.nanoTime();
+ boolean classFound = false;
+ int index = 0;
+ for (String s: iterable) {
+ if (index == maxIndex) break;
+ try {
+ if (index < startIndex) continue;
+ if (test(s)) {
+ classFound = true;
+ }
+ } finally {
+ index++;
+ }
+ }
+ long elapsed = System.nanoTime() - start;
+ long secs = elapsed / 1000_000_000;
+ long millis = (elapsed % 1000_000_000) / 1000_000;
+ long nanos = elapsed % 1000_000;
+ System.out.println("Unreadable path elements: " + cantread);
+ System.out.println("Skipped path elements: " + skipped);
+ System.out.println("Failed path elements: " + failed);
+ printSummary(secs, millis, nanos);
+
+ if (!failed.isEmpty()) {
+ throw new RuntimeException("Test failed for the following classes: " + failed);
+ }
+ if (!classFound && startIndex == 0 && index < maxIndex) {
+ // this is just to verify that we have indeed parsed rt.jar
+ // (or the java.base module)
+ throw new RuntimeException("Test failed: Class.class not found...");
+ }
+ if (classCount.get() == 0 && startIndex == 0) {
+ throw new RuntimeException("Test failed: no class found?");
+ }
+ }
+
+ static boolean test(String s) {
+ try {
+ if (s.startsWith("WrapperGenerator")) {
+ System.out.println("Skipping "+ s);
+ return false;
+ }
+ final Class<?> c = Class.forName(
+ s.replace('/', '.').substring(0, s.length() - 6),
+ false,
+ null);
+ return test(c);
+ } catch (Exception t) {
+ t.printStackTrace(System.err);
+ failed.add(s);
+ } catch (NoClassDefFoundError e) {
+ e.printStackTrace(System.err);
+ failed.add(s);
+ }
+ return false;
+ }
+
+ static class ClassNameStreamBuilder implements Iterable<String>{
+ String[] bcp;
+ ClassNameStreamBuilder() {
+ bcp = System.getProperty("sun.boot.class.path").split(File.pathSeparator);
+ }
+
+ Stream<String> bcpElementToStream(String s) {
+ return s.endsWith(".jar") ? jarToStream(s) : folderToStream(s);
+ }
+
+ Stream<String> jarToStream(String jarName) {
+ File f = new File(jarName);
+ if (f.canRead() && f.isFile()) {
+ try {
+ JarFile jarFile = new JarFile(f);
+ return jarFile.stream()
+ .filter(e -> !e.isDirectory())
+ .map(JarEntry::getName)
+ .filter(s -> s.endsWith(".class"));
+ } catch(IOException x) {
+ x.printStackTrace(System.err);
+ skipped.add(jarName);
+ }
+ } else {
+ cantread.add(jarName);
+ }
+ return Collections.<String>emptyList().stream();
+ }
+
+ Stream<String> folderToStream(String folderName) {
+ final File root = new File(folderName);
+ if (root.canRead() && root.isDirectory()) {
+ final Path rootPath = root.toPath();
+ try {
+ return Files.walk(rootPath)
+ .filter(p -> p.getFileName().toString().endsWith(".class"))
+ .map(rootPath::relativize)
+ .map(p -> p.toString().replace(File.separatorChar, '/'));
+ } catch (IOException x) {
+ x.printStackTrace(System.err);
+ skipped.add(folderName);
+ }
+ } else {
+ cantread.add(folderName);
+ }
+ return Collections.<String>emptyList().stream();
+ }
+
+ public Stream<String> build() {
+ return Stream.of(bcp).flatMap(this::bcpElementToStream);
+ }
+
+ @Override
+ public Iterator<String> iterator() {
+ return build().iterator();
+ }
+ }
+
+ // Test with or without a security manager
+ public static enum TestCase {
+ UNSECURE, SECURE;
+ public void run() throws Exception {
+ System.out.println("Running test case: " + name());
+ Configure.setUp(this);
+ FieldSetAccessibleTest.run(this);
+ }
+ }
+
+ // A helper class to configure the security manager for the test,
+ // and bypass it when needed.
+ static class Configure {
+ static Policy policy = null;
+ static final ThreadLocal<AtomicBoolean> allowAll = new ThreadLocal<AtomicBoolean>() {
+ @Override
+ protected AtomicBoolean initialValue() {
+ return new AtomicBoolean(false);
+ }
+ };
+ static void setUp(TestCase test) {
+ switch (test) {
+ case SECURE:
+ if (policy == null && System.getSecurityManager() != null) {
+ throw new IllegalStateException("SecurityManager already set");
+ } else if (policy == null) {
+ policy = new SimplePolicy(TestCase.SECURE, allowAll);
+ Policy.setPolicy(policy);
+ System.setSecurityManager(new SecurityManager());
+ }
+ if (System.getSecurityManager() == null) {
+ throw new IllegalStateException("No SecurityManager.");
+ }
+ if (policy == null) {
+ throw new IllegalStateException("policy not configured");
+ }
+ break;
+ case UNSECURE:
+ if (System.getSecurityManager() != null) {
+ throw new IllegalStateException("SecurityManager already set");
+ }
+ break;
+ default:
+ throw new InternalError("No such testcase: " + test);
+ }
+ }
+ static void doPrivileged(Runnable run) {
+ allowAll.get().set(true);
+ try {
+ run.run();
+ } finally {
+ allowAll.get().set(false);
+ }
+ }
+ }
+
+ // A Helper class to build a set of permissions.
+ final static class PermissionsBuilder {
+ final Permissions perms;
+ public PermissionsBuilder() {
+ this(new Permissions());
+ }
+ public PermissionsBuilder(Permissions perms) {
+ this.perms = perms;
+ }
+ public PermissionsBuilder add(Permission p) {
+ perms.add(p);
+ return this;
+ }
+ public PermissionsBuilder addAll(PermissionCollection col) {
+ if (col != null) {
+ for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {
+ perms.add(e.nextElement());
+ }
+ }
+ return this;
+ }
+ public Permissions toPermissions() {
+ final PermissionsBuilder builder = new PermissionsBuilder();
+ builder.addAll(perms);
+ return builder.perms;
+ }
+ }
+
+ // Policy for the test...
+ public static class SimplePolicy extends Policy {
+
+ final Permissions permissions;
+ final Permissions allPermissions;
+ final ThreadLocal<AtomicBoolean> allowAll;
+ public SimplePolicy(TestCase test, ThreadLocal<AtomicBoolean> allowAll) {
+ this.allowAll = allowAll;
+
+ // Permission needed by the tested code exercised in the test
+ permissions = new Permissions();
+ permissions.add(new RuntimePermission("fileSystemProvider"));
+ permissions.add(new RuntimePermission("createClassLoader"));
+ permissions.add(new RuntimePermission("closeClassLoader"));
+ permissions.add(new RuntimePermission("getClassLoader"));
+ permissions.add(new RuntimePermission("accessDeclaredMembers"));
+ permissions.add(new ReflectPermission("suppressAccessChecks"));
+ permissions.add(new PropertyPermission("*", "read"));
+ permissions.add(new FilePermission("<<ALL FILES>>", "read"));
+
+ // these are used for configuring the test itself...
+ allPermissions = new Permissions();
+ allPermissions.add(new java.security.AllPermission());
+ }
+
+ @Override
+ public boolean implies(ProtectionDomain domain, Permission permission) {
+ if (allowAll.get().get()) return allPermissions.implies(permission);
+ if (permissions.implies(permission)) return true;
+ if (permission instanceof java.lang.RuntimePermission) {
+ if (permission.getName().startsWith("accessClassInPackage.")) {
+ // add these along to the set of permission we have, when we
+ // discover that we need them.
+ permissions.add(permission);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public PermissionCollection getPermissions(CodeSource codesource) {
+ return new PermissionsBuilder().addAll(allowAll.get().get()
+ ? allPermissions : permissions).toPermissions();
+ }
+
+ @Override
+ public PermissionCollection getPermissions(ProtectionDomain domain) {
+ return new PermissionsBuilder().addAll(allowAll.get().get()
+ ? allPermissions : permissions).toPermissions();
+ }
+ }
+
+}
diff --git a/test/java/lang/Thread/ThreadStateController.java b/test/java/lang/Thread/ThreadStateController.java
index 2d876b0..e2c6341 100644
--- a/test/java/lang/Thread/ThreadStateController.java
+++ b/test/java/lang/Thread/ThreadStateController.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -27,6 +27,8 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
+import jdk.testlibrary.LockFreeLogManager;
+
/**
* ThreadStateController allows a thread to request this thread to transition
* to a specific thread state. The {@linkplain #transitionTo request} is
@@ -94,8 +96,12 @@
private static final int S_TERMINATE = 8;
// for debugging
- private AtomicInteger iterations = new AtomicInteger();
- private AtomicInteger interrupted = new AtomicInteger();
+ private final AtomicInteger iterations = new AtomicInteger();
+ private final AtomicInteger interrupted = new AtomicInteger();
+
+ private final LockFreeLogManager logManager = new LockFreeLogManager();
+
+ @Override
public void run() {
// this thread has started
while (!done) {
@@ -119,13 +125,13 @@
break;
}
case S_BLOCKED: {
- System.out.format("%d: %s is going to block (interations %d)%n",
- getId(), getName(), iterations.get());
+ log("%d: %s is going to block (iterations %d)%n",
+ getId(), getName(), iterations.get());
stateChange(nextState);
// going to block on lock
synchronized (lock) {
- System.out.format("%d: %s acquired the lock (interations %d)%n",
- getId(), getName(), iterations.get());
+ log("%d: %s acquired the lock (iterations %d)%n",
+ getId(), getName(), iterations.get());
try {
// this thread has escaped the BLOCKED state
// release the lock and a short wait before continue
@@ -139,13 +145,13 @@
}
case S_WAITING: {
synchronized (lock) {
- System.out.format("%d: %s is going to waiting (interations %d interrupted %d)%n",
- getId(), getName(), iterations.get(), interrupted.get());
+ log("%d: %s is going to waiting (iterations %d interrupted %d)%n",
+ getId(), getName(), iterations.get(), interrupted.get());
try {
stateChange(nextState);
lock.wait();
- System.out.format("%d: %s wakes up from waiting (interations %d interrupted %d)%n",
- getId(), getName(), iterations.get(), interrupted.get());
+ log("%d: %s wakes up from waiting (iterations %d interrupted %d)%n",
+ getId(), getName(), iterations.get(), interrupted.get());
} catch (InterruptedException e) {
// ignore
interrupted.incrementAndGet();
@@ -155,13 +161,13 @@
}
case S_TIMED_WAITING: {
synchronized (lock) {
- System.out.format("%d: %s is going to timed waiting (interations %d interrupted %d)%n",
- getId(), getName(), iterations.get(), interrupted.get());
+ log("%d: %s is going to timed waiting (iterations %d interrupted %d)%n",
+ getId(), getName(), iterations.get(), interrupted.get());
try {
stateChange(nextState);
lock.wait(10000);
- System.out.format("%d: %s wakes up from timed waiting (interations %d interrupted %d)%n",
- getId(), getName(), iterations.get(), interrupted.get());
+ log("%d: %s wakes up from timed waiting (iterations %d interrupted %d)%n",
+ getId(), getName(), iterations.get(), interrupted.get());
} catch (InterruptedException e) {
// ignore
interrupted.incrementAndGet();
@@ -170,23 +176,23 @@
break;
}
case S_PARKED: {
- System.out.format("%d: %s is going to park (interations %d)%n",
- getId(), getName(), iterations.get());
+ log("%d: %s is going to park (iterations %d)%n",
+ getId(), getName(), iterations.get());
stateChange(nextState);
LockSupport.park();
break;
}
case S_TIMED_PARKED: {
- System.out.format("%d: %s is going to timed park (interations %d)%n",
- getId(), getName(), iterations.get());
+ log("%d: %s is going to timed park (iterations %d)%n",
+ getId(), getName(), iterations.get());
long deadline = System.currentTimeMillis() + 10000*1000;
stateChange(nextState);
LockSupport.parkUntil(deadline);
break;
}
case S_SLEEPING: {
- System.out.format("%d: %s is going to sleep (interations %d interrupted %d)%n",
- getId(), getName(), iterations.get(), interrupted.get());
+ log("%d: %s is going to sleep (iterations %d interrupted %d)%n",
+ getId(), getName(), iterations.get(), interrupted.get());
try {
stateChange(nextState);
Thread.sleep(1000000);
@@ -219,8 +225,8 @@
if (newState == nextState) {
state = nextState;
phaser.arrive();
- System.out.format("%d: state change: %s %s%n",
- getId(), toStateName(nextState), phaserToString(phaser));
+ log("%d: state change: %s %s%n",
+ getId(), toStateName(nextState), phaserToString(phaser));
return;
}
@@ -270,12 +276,12 @@
private void nextState(int s) throws InterruptedException {
final long id = Thread.currentThread().getId();
- System.out.format("%d: wait until the thread transitions to %s %s%n",
- id, toStateName(s), phaserToString(phaser));
+ log("%d: wait until the thread transitions to %s %s%n",
+ id, toStateName(s), phaserToString(phaser));
this.newState = s;
int phase = phaser.arrive();
- System.out.format("%d: awaiting party arrive %s %s%n",
- id, toStateName(s), phaserToString(phaser));
+ log("%d: awaiting party arrive %s %s%n",
+ id, toStateName(s), phaserToString(phaser));
for (;;) {
// when this thread has changed its state before it waits or parks
// on a lock, a potential race might happen if it misses the notify
@@ -301,20 +307,22 @@
}
try {
phaser.awaitAdvanceInterruptibly(phase, 100, TimeUnit.MILLISECONDS);
- System.out.format("%d: arrived at %s %s%n",
- id, toStateName(s), phaserToString(phaser));
+ log("%d: arrived at %s %s%n",
+ id, toStateName(s), phaserToString(phaser));
return;
} catch (TimeoutException ex) {
// this thread hasn't arrived at this phase
- System.out.format("%d: Timeout: %s%n", id, phaser);
+ log("%d: Timeout: %s%n", id, phaser);
}
}
}
+
private String phaserToString(Phaser p) {
return "[phase = " + p.getPhase() +
" parties = " + p.getRegisteredParties() +
" arrived = " + p.getArrivedParties() + "]";
}
+
private String toStateName(int state) {
switch (state) {
case S_RUNNABLE:
@@ -337,4 +345,20 @@
return "unknown " + state;
}
}
+
+ private void log(String msg, Object ... params) {
+ logManager.log(msg, params);
+ }
+
+ /**
+ * Waits for the controller to complete the test run and returns the
+ * generated log
+ * @return The controller log
+ * @throws InterruptedException
+ */
+ public String getLog() throws InterruptedException {
+ this.join();
+
+ return logManager.toString();
+ }
}
diff --git a/test/java/lang/Thread/ThreadStateTest.java b/test/java/lang/Thread/ThreadStateTest.java
index 553ed78..843cfd7 100644
--- a/test/java/lang/Thread/ThreadStateTest.java
+++ b/test/java/lang/Thread/ThreadStateTest.java
@@ -30,6 +30,8 @@
* Thread.getState().
*
* @author Mandy Chung
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
* @build ThreadStateTest ThreadStateController
* @run main/othervm -Xmixed ThreadStateTest
*/
diff --git a/test/java/lang/instrument/ManyMethodsBenchmarkAgent.java b/test/java/lang/instrument/ManyMethodsBenchmarkAgent.java
new file mode 100644
index 0000000..05f9f19
--- /dev/null
+++ b/test/java/lang/instrument/ManyMethodsBenchmarkAgent.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 8046246
+ * @summary Tests and benchmarks the JVMTI RedefineClasses when a
+ * single class (and its parent) contains many methods.
+ *
+ * @run build ManyMethodsBenchmarkApp ManyMethodsBenchmarkAgent
+ * @run shell MakeJAR3.sh ManyMethodsBenchmarkAgent 'Can-Retransform-Classes: true'
+ * @run main/othervm -javaagent:ManyMethodsBenchmarkAgent.jar ManyMethodsBenchmarkApp
+ */
+import java.lang.instrument.*;
+
+public class ManyMethodsBenchmarkAgent
+{
+ public static boolean fail = false;
+ public static boolean completed = false;
+ private static Instrumentation instrumentation;
+
+ public static void
+ premain( String agentArgs,
+ Instrumentation instrumentation) {
+ System.out.println("ManyMethodsBenchmarkAgent started");
+ ManyMethodsBenchmarkAgent.instrumentation = instrumentation;
+ System.out.println("ManyMethodsBenchmarkAgent finished");
+ }
+
+ static void instr() {
+ System.out.println("ManyMethodsBenchmarkAgent.instr started");
+
+ Class[] allClasses = instrumentation.getAllLoadedClasses();
+
+ for (int i = 0; i < allClasses.length; i++) {
+ Class klass = allClasses[i];
+ String name = klass.getName();
+ if (!name.equals("Base")) {
+ continue;
+ }
+ System.err.println("Instrumenting the class: " + klass);
+
+ try {
+ instrumentation.retransformClasses(klass);
+ } catch (Throwable e) {
+ System.err.println("Error: bad return from retransform: " + klass);
+ System.err.println(" ERROR: " + e);
+ fail = true;
+ }
+ }
+ completed = true;
+ System.out.println("ManyMethodsBenchmarkAgent.instr finished");
+ }
+
+}
diff --git a/test/java/lang/instrument/ManyMethodsBenchmarkApp.java b/test/java/lang/instrument/ManyMethodsBenchmarkApp.java
new file mode 100644
index 0000000..c85bf42
--- /dev/null
+++ b/test/java/lang/instrument/ManyMethodsBenchmarkApp.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2015 Google Inc. 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.
+ *
+ * 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.
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.List;
+import javax.tools.JavaCompiler;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/**
+ * A manual benchmark of the JVMTI RedefineClasses when a
+ * single class (and its parent) contains many methods.
+ */
+public class ManyMethodsBenchmarkApp {
+ // Limit is 64k but we can not put such many as the CP limit is 32k.
+ // In practice, it means a real limit is much lower (less than 22000).
+ static final int METHOD_COUNT = 20000;
+
+ static Class<?> loadClassInNewClassLoader(String className) throws Exception {
+ URL[] urls = { new File(".").toURI().toURL() };
+ URLClassLoader ucl = new URLClassLoader(urls, null);
+ Class<?> klazz = Class.forName(className, true, ucl);
+ return klazz;
+ }
+
+ static void benchmarkClassOperations(String className) throws Exception {
+ Class<?> klazz = loadClassInNewClassLoader(className);
+
+ Method[] methods = klazz.getDeclaredMethods();
+ if (methods.length != METHOD_COUNT) {
+ throw new AssertionError("unexpected method count: " + methods.length +
+ " expected: " + METHOD_COUNT);
+ }
+
+ methods = klazz.getMethods();
+ // returned methods includes those inherited from Object
+ int objectMethodSlop = 100;
+ if (methods.length <= METHOD_COUNT ||
+ methods.length >= METHOD_COUNT + objectMethodSlop) {
+ throw new AssertionError("unexpected method count: " + methods.length);
+ }
+
+ // Invoke methods to make them appear in the constant pool cache
+ Object obj = klazz.newInstance();
+ Object[] args = new Object[0];
+ for (Method m: methods) {
+ try {
+ Class<?>[] types = m.getParameterTypes();
+ String name = m.getName();
+ // System.out.println("method: " + name + "; argno: " + types.length);
+ if (types.length == 0 && name.length() == 2 && name.startsWith("f")) {
+ m.invoke(obj, args);
+ }
+ } catch (InvocationTargetException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("test started: ManyMethodsBenchmarkApp");
+
+ // Create source files with many methods
+ File base = new File("Base.java");
+ try (FileWriter fw = new FileWriter(base)) {
+ fw.write("public class Base {\n");
+ final int L = 10;
+ // Each of the first L methods makes calls to its own chunk of METHOD_COUNT/L methods
+ for (int k = 0; k < L; k++) {
+ fw.write(" public void f" + k + "() {\n");
+ int shift = (k == 0) ? L : 0;
+ for (int i = (k * (METHOD_COUNT/L)) + shift; i < (k + 1) * METHOD_COUNT/L; i++) {
+ fw.write(" f" + i + "();\n");
+ }
+ fw.write(" }\n");
+ }
+
+ // The rest of (METHOD_COUNT - L) methods have empty body
+ for (int i = L; i < METHOD_COUNT; i++) {
+ fw.write(" public static void f" + i + "() {}\n");
+ }
+ fw.write("}\n");
+ }
+
+ // Compile the generated source files.
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ List<File> files = Arrays.asList(new File[] { base });
+ try (StandardJavaFileManager fileManager =
+ compiler.getStandardFileManager(null, null, null)) {
+ compiler.getTask(null, fileManager, null, null, null,
+ fileManager.getJavaFileObjectsFromFiles(files))
+ .call();
+ }
+
+ benchmarkClassOperations("Base");
+
+ ManyMethodsBenchmarkAgent.instr();
+
+ // Cleanup
+ base.delete();
+ new File("Base.class").delete();
+ if (!ManyMethodsBenchmarkAgent.completed) {
+ throw new Exception("ERROR: ManyMethodsBenchmarkAgent did not complete.");
+ }
+
+ if (ManyMethodsBenchmarkAgent.fail) {
+ throw new Exception("ERROR: ManyMethodsBenchmarkAgent failed.");
+ } else {
+ System.out.println("ManyMethodsBenchmarkAgent succeeded.");
+ }
+ System.out.println("test finished: ManyMethodsBenchmarkApp");
+ }
+}
diff --git a/test/java/lang/instrument/RedefineMethodInBacktrace.sh b/test/java/lang/instrument/RedefineMethodInBacktrace.sh
index 4ebaaa8..b61fe48 100644
--- a/test/java/lang/instrument/RedefineMethodInBacktrace.sh
+++ b/test/java/lang/instrument/RedefineMethodInBacktrace.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -77,7 +77,7 @@
cat output.log
-MESG="Exception"
+MESG="Test failed"
grep "$MESG" output.log
result=$?
if [ "$result" = 0 ]; then
diff --git a/test/java/lang/instrument/RedefineMethodInBacktraceApp.java b/test/java/lang/instrument/RedefineMethodInBacktraceApp.java
index 7f7ddbf..7c363c3 100644
--- a/test/java/lang/instrument/RedefineMethodInBacktraceApp.java
+++ b/test/java/lang/instrument/RedefineMethodInBacktraceApp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -46,12 +46,15 @@
* could be freed, since class redefinition didn't know about the backtraces.
*/
public class RedefineMethodInBacktraceApp {
+ static boolean failed = false;
+
public static void main(String args[]) throws Exception {
System.out.println("Hello from RedefineMethodInBacktraceApp!");
-
new RedefineMethodInBacktraceApp().doTest();
- System.exit(0);
+ if (failed) {
+ throw new Exception("ERROR: RedefineMethodInBacktraceApp failed.");
+ }
}
public static CountDownLatch stop = new CountDownLatch(1);
@@ -63,13 +66,18 @@
}
private void doMethodInBacktraceTest() throws Exception {
- Throwable t = getThrowableFromMethodToRedefine();
+ Throwable t1 = getThrowableFromMethodToRedefine();
+ Throwable t2 = getThrowableFromMethodToDelete();
doRedefine(RedefineMethodInBacktraceTarget.class);
doClassUnloading();
- touchRedefinedMethodInBacktrace(t);
+ System.out.println("checking backtrace for throwable from methodToRedefine");
+ touchRedefinedMethodInBacktrace(t1);
+
+ System.out.println("checking backtrace for throwable from methodToDelete");
+ touchRedefinedMethodInBacktrace(t2);
}
private void doMethodInBacktraceTestB() throws Exception {
@@ -115,6 +123,10 @@
if (!(thrownFromMethodToRedefine instanceof RuntimeException)) {
throw e;
}
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("\nTest failed: unexpected exception: " + e.toString());
+ failed = true;
}
method = null;
c = null;
@@ -122,15 +134,49 @@
return thrownFromMethodToRedefine;
}
+ private static Throwable getThrowableFromMethodToDelete() throws Exception {
+ Class<RedefineMethodInBacktraceTarget> c =
+ RedefineMethodInBacktraceTarget.class;
+ Method method = c.getMethod("callMethodToDelete");
+
+ Throwable thrownFromMethodToDelete = null;
+ try {
+ method.invoke(null);
+ } catch (InvocationTargetException e) {
+ thrownFromMethodToDelete = e.getCause();
+ if (!(thrownFromMethodToDelete instanceof RuntimeException)) {
+ throw e;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("\nTest failed: unexpected exception: " + e.toString());
+ failed = true;
+ }
+ return thrownFromMethodToDelete;
+ }
+
+
private static void doClassUnloading() {
// This will clean out old, unused redefined methods.
System.gc();
}
private static void touchRedefinedMethodInBacktrace(Throwable throwable) {
+ throwable.printStackTrace();
// Make sure that we can convert the backtrace, which is referring to
// the redefined method, to a StrackTraceElement[] without crashing.
- throwable.getStackTrace();
+ StackTraceElement[] stackTrace = throwable.getStackTrace();
+ for (int i = 0; i < stackTrace.length; i++) {
+ StackTraceElement frame = stackTrace[i];
+ if (frame.getClassName() == null) {
+ System.out.println("\nTest failed: trace[" + i + "].getClassName() returned null");
+ failed = true;
+ }
+ if (frame.getMethodName() == null) {
+ System.out.println("\nTest failed: trace[" + i + "].getMethodName() returned null");
+ failed = true;
+ }
+ }
}
private static void doRedefine(Class<?> clazz) throws Exception {
diff --git a/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java b/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java
index fad8811..87e817a 100644
--- a/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java
+++ b/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -29,4 +29,13 @@
public static void methodToRedefine() {
throw new RuntimeException("Test exception");
}
+
+ public static void callMethodToDelete() {
+ methodToDelete();
+ }
+
+ private static void methodToDelete() {
+ throw new RuntimeException("Test exception in methodToDelete");
+ }
+
}
diff --git a/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java b/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java
index baefeb7..80bc48f 100644
--- a/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java
+++ b/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -37,4 +37,16 @@
// ignore, test will fail
}
}
+
+ public static void callMethodToDelete() {
+ try {
+ // signal that we are here
+ RedefineMethodInBacktraceApp.called.countDown();
+
+ // wait until test is done
+ RedefineMethodInBacktraceApp.stop.await();
+ } catch (InterruptedException ex) {
+ // ignore, test will fail
+ }
+ }
}
diff --git a/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java b/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java
index de98206..c5b482d 100644
--- a/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java
+++ b/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -28,4 +28,7 @@
public class RedefineMethodInBacktraceTargetB {
public static void methodToRedefine() {
}
+
+ public static void callMethodToDelete() {
+ }
}
diff --git a/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java b/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java
index d2ba225..77d816a 100644
--- a/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java
+++ b/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -29,4 +29,8 @@
public static void methodToRedefine() {
throw new RuntimeException("Test exception 2");
}
+
+ public static void callMethodToDelete() {
+ throw new RuntimeException("Test exception 2 in callMethodToDelete");
+ }
}
diff --git a/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java b/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java
index 0980c42..9d4a748 100644
--- a/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java
+++ b/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java
@@ -27,15 +27,16 @@
* @summary Test verifies that lambda forms are garbage collected
* @author kshefov
* @library /lib/testlibrary/jsr292 /lib/testlibrary
- * @ignore 8057020
* @build TestMethods
* @build LambdaFormTestCase
* @build LFGarbageCollectedTest
- * @run main/othervm LFGarbageCollectedTest
+ * @run main/othervm -Xmx64m -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+HeapDumpOnOutOfMemoryError -DHEAP_DUMP=false LFGarbageCollectedTest
*/
import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
import java.lang.ref.PhantomReference;
+import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.InvocationTargetException;
import java.util.EnumSet;
@@ -45,6 +46,7 @@
* Lambda forms garbage collection test class.
*/
public final class LFGarbageCollectedTest extends LambdaFormTestCase {
+ private static boolean HEAP_DUMP = Boolean.getBoolean("HEAP_DUMP");
/**
* Constructor for a lambda forms garbage collection test case.
@@ -56,37 +58,85 @@
super(testMethod);
}
+ PhantomReference ph;
+ ReferenceQueue rq = new ReferenceQueue();
+ MethodType mtype;
+ Map<String, Object> data;
+
@Override
public void doTest() {
try {
- Map<String, Object> data = getTestMethod().getTestCaseData();
+ TestMethods testCase = getTestMethod();
+ data = testCase.getTestCaseData();
MethodHandle adapter;
try {
- adapter = getTestMethod().getTestCaseMH(data, TestMethods.Kind.ONE);
+ adapter = testCase.getTestCaseMH(data, TestMethods.Kind.ONE);
} catch (NoSuchMethodException ex) {
throw new Error("Unexpected exception: ", ex);
}
- Object lambdaForm = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter);
+ mtype = adapter.type();
+ Object lambdaForm = INTERNAL_FORM.invoke(adapter);
if (lambdaForm == null) {
throw new Error("Unexpected error: Lambda form of the method handle is null");
}
- ReferenceQueue rq = new ReferenceQueue();
- PhantomReference ph = new PhantomReference(lambdaForm, rq);
+
+ String debugName = (String)DEBUG_NAME.get(lambdaForm);
+ if (debugName != null && debugName.startsWith("identity_")) {
+ // Ignore identity_* LambdaForms.
+ return;
+ }
+
+ ph = new PhantomReference(lambdaForm, rq);
lambdaForm = null;
- data = null;
adapter = null;
- for (int i = 0; i < 1000 && !ph.isEnqueued(); i++) {
- System.gc();
- }
- if (!ph.isEnqueued()) {
- throw new AssertionError("Error: Lambda form is not garbage collected");
- }
+
+ collectLambdaForm();
} catch (IllegalAccessException | IllegalArgumentException |
InvocationTargetException ex) {
throw new Error("Unexpected exception: ", ex);
}
}
+ private void collectLambdaForm() throws IllegalAccessException {
+ // Usually, 2 System.GCs are necessary to enqueue a SoftReference.
+ System.gc();
+ System.gc();
+
+ Reference ref = null;
+ for (int i = 0; i < 10; i++) {
+ try {
+ ref = rq.remove(1000);
+ } catch (InterruptedException e) {
+ /* ignore */
+ }
+ if (ref != null) {
+ break;
+ }
+ System.gc(); // If the reference hasn't been queued yet, trigger one more GC.
+ }
+
+ if (ref == null) {
+ dumpTestData();
+ System.err.println("Method type: " + mtype);
+ System.err.println("LambdaForm: " + REF_FIELD.get(ph));
+
+ if (HEAP_DUMP) {
+ // Trigger OOM to force heap dump for post-mortem analysis.
+ val = new long[1_000_000_000];
+ }
+ throw new AssertionError("Error: LambdaForm is not garbage collected");
+ };
+ }
+
+ private void dumpTestData() {
+ System.err.println("Test case: " + getTestMethod());
+ for (String s : data.keySet()) {
+ System.err.printf("\t%20s => %s\n", s, data.get(s));
+ }
+ }
+
+ private static long[] val;
+
/**
* Main routine for lambda forms garbage collection test.
*
@@ -102,7 +152,9 @@
TestMethods.IDENTITY,
TestMethods.CONSTANT,
TestMethods.ARRAY_ELEMENT_GETTER,
- TestMethods.ARRAY_ELEMENT_SETTER));
+ TestMethods.ARRAY_ELEMENT_SETTER,
+ TestMethods.EXACT_INVOKER,
+ TestMethods.INVOKER));
LambdaFormTestCase.runTests(LFGarbageCollectedTest::new, testMethods);
}
}
diff --git a/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java b/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java
index 7b6ce2e..5d037ca 100644
--- a/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java
+++ b/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java
@@ -24,8 +24,11 @@
import com.oracle.testlibrary.jsr292.Helper;
import com.sun.management.HotSpotDiagnosticMXBean;
+import java.lang.invoke.MethodHandle;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
+import java.lang.ref.Reference;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
@@ -42,8 +45,6 @@
*/
public abstract class LambdaFormTestCase {
- private final static String METHOD_HANDLE_CLASS_NAME = "java.lang.invoke.MethodHandle";
- private final static String INTERNAL_FORM_METHOD_NAME = "internalForm";
private static final double ITERATIONS_TO_CODE_CACHE_SIZE_RATIO
= 45 / (128.0 * 1024 * 1024);
private static final long TIMEOUT = Helper.IS_THOROUGH ? 0L : (long) (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) * 0.9);
@@ -53,6 +54,8 @@
* used to get a lambda form from a method handle.
*/
protected final static Method INTERNAL_FORM;
+ protected final static Field DEBUG_NAME;
+ protected final static Field REF_FIELD;
private static final List<GarbageCollectorMXBean> gcInfo;
private static long gcCount() {
@@ -61,9 +64,14 @@
static {
try {
- Class mhClass = Class.forName(METHOD_HANDLE_CLASS_NAME);
- INTERNAL_FORM = mhClass.getDeclaredMethod(INTERNAL_FORM_METHOD_NAME);
+ INTERNAL_FORM = MethodHandle.class.getDeclaredMethod("internalForm");
INTERNAL_FORM.setAccessible(true);
+
+ DEBUG_NAME = Class.forName("java.lang.invoke.LambdaForm").getDeclaredField("debugName");
+ DEBUG_NAME.setAccessible(true);
+
+ REF_FIELD = Reference.class.getDeclaredField("referent");
+ REF_FIELD.setAccessible(true);
} catch (Exception ex) {
throw new Error("Unexpected exception: ", ex);
}
@@ -146,6 +154,10 @@
testCase.getTestMethod().name);
testCase.doTest();
System.err.println("PASSED");
+ } catch (OutOfMemoryError e) {
+ // Don't swallow OOME so a heap dump can be created.
+ System.err.println("FAILED");
+ throw e;
} catch (Throwable t) {
t.printStackTrace();
System.err.println("FAILED");
diff --git a/test/java/lang/invoke/lambda/LambdaStackTrace.java b/test/java/lang/invoke/lambda/LambdaStackTrace.java
new file mode 100644
index 0000000..e2cdb79
--- /dev/null
+++ b/test/java/lang/invoke/lambda/LambdaStackTrace.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8025636
+ * @summary Synthetic frames should be hidden in exceptions
+ * @compile -XDignore.symbol.file LUtils.java LambdaStackTrace.java
+ * @run main LambdaStackTrace
+ */
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_ABSTRACT;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_INTERFACE;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
+
+public class LambdaStackTrace {
+
+ static File classes = new File(System.getProperty("test.classes"));
+
+ public static void main(String[] args) throws Exception {
+ testBasic();
+ testBridgeMethods();
+ }
+
+ /**
+ * Test the simple case
+ */
+ private static void testBasic() throws Exception {
+ try {
+ Runnable r = () -> {
+ throw new RuntimeException();
+ };
+ r.run();
+ } catch (Exception ex) {
+ // Before 8025636 the stacktrace would look like:
+ // at LambdaStackTrace.lambda$main$0(LambdaStackTrace.java:37)
+ // at LambdaStackTrace$$Lambda$1/1937396743.run(<Unknown>:1000000)
+ // at LambdaStackTrace.testBasic(LambdaStackTrace.java:40)
+ // at ...
+ //
+ // We are verifying that the middle frame above is gone.
+
+ verifyFrames(ex.getStackTrace(),
+ "LambdaStackTrace\\..*",
+ "LambdaStackTrace.testBasic");
+ }
+ }
+
+ /**
+ * Test the more complicated case with bridge methods.
+ *
+ * We set up the following interfaces:
+ *
+ * interface Maker {
+ * Object make();
+ * }
+ * interface StringMaker extends Maker {
+ * String make();
+ * }
+ *
+ * And we will use them like so:
+ *
+ * StringMaker sm = () -> { throw new RuntimeException(); };
+ * sm.make();
+ * ((Maker)m).make();
+ *
+ * The first call is a "normal" interface call, the second will use a
+ * bridge method. In both cases the generated lambda frame should
+ * be removed from the stack trace.
+ */
+ private static void testBridgeMethods() throws Exception {
+ // setup
+ generateInterfaces();
+ compileCaller();
+
+ // test
+ StackTraceElement[] frames = call("Caller", "callStringMaker");
+ verifyFrames(frames,
+ "Caller\\..*",
+ "Caller.callStringMaker");
+
+ frames = call("Caller", "callMaker");
+ verifyFrames(frames,
+ "Caller\\..*",
+ "Caller.callMaker");
+ }
+
+ private static void generateInterfaces() throws IOException {
+ // We can't let javac compile these interfaces because in > 1.8 it will insert
+ // bridge methods into the interfaces - we want code that looks like <= 1.7,
+ // so we generate it.
+ try (FileOutputStream fw = new FileOutputStream(new File(classes, "Maker.class"))) {
+ fw.write(generateMaker());
+ }
+ try (FileOutputStream fw = new FileOutputStream(new File(classes, "StringMaker.class"))) {
+ fw.write(generateStringMaker());
+ }
+ }
+
+ private static byte[] generateMaker() {
+ // interface Maker {
+ // Object make();
+ // }
+ ClassWriter cw = new ClassWriter(0);
+ cw.visit(V1_7, ACC_INTERFACE | ACC_ABSTRACT, "Maker", null, "java/lang/Object", null);
+ cw.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, "make",
+ "()Ljava/lang/Object;", null, null);
+ cw.visitEnd();
+ return cw.toByteArray();
+ }
+
+ private static byte[] generateStringMaker() {
+ // interface StringMaker extends Maker {
+ // String make();
+ // }
+ ClassWriter cw = new ClassWriter(0);
+ cw.visit(V1_7, ACC_INTERFACE | ACC_ABSTRACT, "StringMaker", null, "java/lang/Object", new String[]{"Maker"});
+ cw.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, "make",
+ "()Ljava/lang/String;", null, null);
+ cw.visitEnd();
+ return cw.toByteArray();
+ }
+
+
+ static void emitCode(File f) {
+ ArrayList<String> scratch = new ArrayList<>();
+ scratch.add("public class Caller {");
+ scratch.add(" public static void callStringMaker() {");
+ scratch.add(" StringMaker sm = () -> { throw new RuntimeException(); };");
+ scratch.add(" sm.make();");
+ scratch.add(" }");
+ scratch.add(" public static void callMaker() {");
+ scratch.add(" StringMaker sm = () -> { throw new RuntimeException(); };");
+ scratch.add(" ((Maker) sm).make();"); // <-- This will call the bridge method
+ scratch.add(" }");
+ scratch.add("}");
+ LUtils.createFile(f, scratch);
+ }
+
+ static void compileCaller() {
+ File caller = new File(classes, "Caller.java");
+ emitCode(caller);
+ LUtils.compile("-cp", classes.getAbsolutePath(), "-d", classes.getAbsolutePath(), caller.getAbsolutePath());
+ }
+
+ private static void verifyFrames(StackTraceElement[] stack, String... patterns) throws Exception {
+ for (int i = 0; i < patterns.length; i++) {
+ String cm = stack[i].getClassName() + "." + stack[i].getMethodName();
+ if (!cm.matches(patterns[i])) {
+ System.err.println("Actual trace did not match expected trace at frame " + i);
+ System.err.println("Expected frame patterns:");
+ for (int j = 0; j < patterns.length; j++) {
+ System.err.println(" " + j + ": " + patterns[j]);
+ }
+ System.err.println("Actual frames:");
+ for (int j = 0; j < patterns.length; j++) {
+ System.err.println(" " + j + ": " + stack[j]);
+ }
+ throw new Exception("Incorrect stack frames found");
+ }
+ }
+ }
+
+ private static StackTraceElement[] call(String clazz, String method) throws Exception {
+ Class<?> c = Class.forName(clazz);
+ try {
+ Method m = c.getDeclaredMethod(method);
+ m.invoke(null);
+ } catch(InvocationTargetException ex) {
+ return ex.getTargetException().getStackTrace();
+ }
+ throw new Exception("Expected exception to be thrown");
+ }
+}
diff --git a/test/java/lang/management/MemoryMXBean/LowMemoryTest.java b/test/java/lang/management/MemoryMXBean/LowMemoryTest.java
index 379b129..4d081f6 100644
--- a/test/java/lang/management/MemoryMXBean/LowMemoryTest.java
+++ b/test/java/lang/management/MemoryMXBean/LowMemoryTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -33,6 +33,9 @@
* @library /lib/testlibrary/
* @build LowMemoryTest MemoryUtil RunUtil
* @run main/timeout=600 LowMemoryTest
+ * @requires vm.opt.ExplicitGCInvokesConcurrent != "true"
+ * @requires vm.opt.ExplicitGCInvokesConcurrentAndUnloadsClasses != "true"
+ * @requires vm.opt.DisableExplicitGC != "true"
*/
import java.lang.management.*;
@@ -85,9 +88,15 @@
}
static class TestListener implements NotificationListener {
+ private boolean isRelaxed = false;
private int triggers = 0;
private final long[] count = new long[NUM_TRIGGERS * 2];
private final long[] usedMemory = new long[NUM_TRIGGERS * 2];
+
+ public TestListener() {
+ isRelaxed = ManagementFactory.getRuntimeMXBean().getInputArguments().contains("-XX:+UseConcMarkSweepGC");
+ }
+
@Override
public void handleNotification(Notification notif, Object handback) {
MemoryNotificationInfo minfo = MemoryNotificationInfo.
@@ -97,7 +106,8 @@
triggers++;
}
public void checkResult() throws Exception {
- if (triggers != NUM_TRIGGERS) {
+ if ((!isRelaxed && triggers != NUM_TRIGGERS) ||
+ (isRelaxed && triggers < NUM_TRIGGERS)) {
throw new RuntimeException("Unexpected number of triggers = " +
triggers + " but expected to be " + NUM_TRIGGERS);
}
diff --git a/test/java/lang/management/ThreadMXBean/AllThreadIds.java b/test/java/lang/management/ThreadMXBean/AllThreadIds.java
index 05547b7..aa80c74 100644
--- a/test/java/lang/management/ThreadMXBean/AllThreadIds.java
+++ b/test/java/lang/management/ThreadMXBean/AllThreadIds.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -27,21 +27,19 @@
* @summary Basic unit test of ThreadMXBean.getAllThreadIds()
* @author Alexei Guibadoulline and Mandy Chung
*
- * @run build Barrier
* @run main/othervm AllThreadIds
*/
import java.lang.management.*;
-import java.util.*;
+import java.util.concurrent.Phaser;
public class AllThreadIds {
final static int DAEMON_THREADS = 20;
final static int USER_THREADS = 5;
final static int ALL_THREADS = DAEMON_THREADS + USER_THREADS;
- private static volatile boolean live[] = new boolean[ALL_THREADS];
- private static Thread allThreads[] = new Thread[ALL_THREADS];
- private static ThreadMXBean mbean
- = ManagementFactory.getThreadMXBean();
+ private static final boolean live[] = new boolean[ALL_THREADS];
+ private static final Thread allThreads[] = new Thread[ALL_THREADS];
+ private static final ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
private static boolean testFailed = false;
private static boolean trace = false;
@@ -52,8 +50,7 @@
private static int curLiveThreadCount = 0;
private static int curPeakThreadCount = 0;
- // barrier for threads communication
- private static Barrier barrier = new Barrier(ALL_THREADS);
+ private static final Phaser startupCheck = new Phaser(ALL_THREADS + 1);
private static void printThreadList() {
if (!trace) return;
@@ -124,18 +121,15 @@
curPeakThreadCount = mbean.getPeakThreadCount();
checkThreadCount(0, 0);
-
// Start all threads and wait to be sure they all are alive
- barrier.set(ALL_THREADS);
for (int i = 0; i < ALL_THREADS; i++) {
- live[i] = true;
+ setLive(i, true);
allThreads[i] = new MyThread(i);
- allThreads[i].setDaemon( (i < DAEMON_THREADS) ? true : false);
+ allThreads[i].setDaemon(i < DAEMON_THREADS);
allThreads[i].start();
}
// wait until all threads are started.
- barrier.await();
-
+ startupCheck.arriveAndAwaitAdvance();
checkThreadCount(ALL_THREADS, 0);
printThreadList();
@@ -173,15 +167,14 @@
// Stop daemon threads, wait to be sure they all are dead, and check
// that they disappeared from getAllThreadIds() list
- barrier.set(DAEMON_THREADS);
for (int i = 0; i < DAEMON_THREADS; i++) {
- live[i] = false;
+ setLive(i, false);
}
- // wait until daemon threads are terminated.
- barrier.await();
- // give chance to threads to terminate
- pause();
+ // make sure the daemon threads are completely dead
+ joinDaemonThreads();
+
+ // and check the reported thread count
checkThreadCount(0, DAEMON_THREADS);
// Check mbean now
@@ -190,11 +183,11 @@
for (int i = 0; i < ALL_THREADS; i++) {
long expectedId = allThreads[i].getId();
boolean found = false;
- boolean live = (i >= DAEMON_THREADS);
+ boolean alive = (i >= DAEMON_THREADS);
if (trace) {
System.out.print("Looking for thread with id " + expectedId +
- (live ? " expected alive." : " expected terminated."));
+ (alive ? " expected alive." : " expected terminated."));
}
for (int j = 0; j < list.length; j++) {
if (expectedId == list[j]) {
@@ -203,11 +196,11 @@
}
}
- if (live != found) {
+ if (alive != found) {
testFailed = true;
}
if (trace) {
- if (live != found) {
+ if (alive != found) {
System.out.println(" TEST FAILED.");
} else {
System.out.println();
@@ -216,15 +209,14 @@
}
// Stop all threads and wait to be sure they all are dead
- barrier.set(ALL_THREADS - DAEMON_THREADS);
for (int i = DAEMON_THREADS; i < ALL_THREADS; i++) {
- live[i] = false;
+ setLive(i, false);
}
- // wait until daemon threads are terminated .
- barrier.await();
- // give chance to threads to terminate
- pause();
+ // make sure the non-daemon threads are completely dead
+ joinNonDaemonThreads();
+
+ // and check the thread count
checkThreadCount(0, ALL_THREADS - DAEMON_THREADS);
if (testFailed)
@@ -233,6 +225,30 @@
System.out.println("Test passed.");
}
+ private static void joinDaemonThreads() throws InterruptedException {
+ for (int i = 0; i < DAEMON_THREADS; i++) {
+ allThreads[i].join();
+ }
+ }
+
+ private static void joinNonDaemonThreads() throws InterruptedException {
+ for (int i = DAEMON_THREADS; i < ALL_THREADS; i++) {
+ allThreads[i].join();
+ }
+ }
+
+ private static void setLive(int i, boolean val) {
+ synchronized(live) {
+ live[i] = val;
+ }
+ }
+
+ private static boolean isLive(int i) {
+ synchronized(live) {
+ return live[i];
+ }
+ }
+
// The MyThread thread lives as long as correspondent live[i] value is true
private static class MyThread extends Thread {
int id;
@@ -243,8 +259,8 @@
public void run() {
// signal started
- barrier.signal();
- while (live[id]) {
+ startupCheck.arrive();
+ while (isLive(id)) {
try {
sleep(100);
} catch (InterruptedException e) {
@@ -253,23 +269,6 @@
testFailed = true;
}
}
- // signal about to exit
- barrier.signal();
}
}
-
- private static Object pauseObj = new Object();
- private static void pause() {
- // Enter lock a without blocking
- synchronized (pauseObj) {
- try {
- // may need to tune this timeout for different platforms
- pauseObj.wait(50);
- } catch (Exception e) {
- System.err.println("Unexpected exception.");
- e.printStackTrace(System.err);
- }
- }
- }
-
}
diff --git a/test/java/lang/management/ThreadMXBean/Locks.java b/test/java/lang/management/ThreadMXBean/Locks.java
index e65d363..9223364 100644
--- a/test/java/lang/management/ThreadMXBean/Locks.java
+++ b/test/java/lang/management/ThreadMXBean/Locks.java
@@ -29,17 +29,21 @@
* @author Mandy Chung
* @author Jaroslav Bachorik
*
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
* @run main/othervm Locks
*/
import java.lang.management.*;
import java.util.concurrent.Phaser;
+import jdk.testlibrary.LockFreeLogManager;
public class Locks {
private static final Object objA = new Object();
private static final Object objB = new Object();
private static final Object objC = new Object();
private static final ThreadMXBean tm = ManagementFactory.getThreadMXBean();
+ private static final LockFreeLogManager logger = new LockFreeLogManager();
private static boolean testFailed = false;
@@ -126,14 +130,14 @@
public void run() {
synchronized(objA) {
// stop here for LockBThread to hold objB
- System.out.println("LockAThread about to block on objB");
+ log("LockAThread about to block on objB");
p.arriveAndAwaitAdvance(); // Phase 1 (blocking)
synchronized(objB) {
dummyCounter++;
};
}
p.arriveAndAwaitAdvance(); // Phase 2 (blocking)
- System.out.println("LockAThread about to exit");
+ log("LockAThread about to exit");
// Make sure the current thread is not holding any lock
assertNoLock(this);
}
@@ -147,7 +151,7 @@
}
public void run() {
synchronized(objB) {
- System.out.println("LockBThread about to block on objC");
+ log("LockBThread about to block on objC");
p.arriveAndAwaitAdvance(); // Phase 1 (blocking)
// Signal main thread about to block on objC
synchronized(objC) {
@@ -155,14 +159,14 @@
};
}
p.arriveAndAwaitAdvance(); // Phase 2 (blocking)
- System.out.println("LockBThread about to exit");
+ log("LockBThread about to exit");
// Make sure the current thread is not holding any lock
assertNoLock(this);
}
}
private static WaitingThread waiter;
- private static Object ready = new Object();
+ private static final Object ready = new Object();
private static CheckerThread checker;
static class WaitingThread extends Thread {
private final Phaser p;
@@ -170,9 +174,10 @@
super("WaitingThread");
this.p = p;
}
+ @Override
public void run() {
synchronized(objC) {
- System.out.println("WaitingThread about to wait on objC");
+ log("WaitingThread about to wait on objC");
try {
// Signal checker thread, about to wait on objC.
p.arriveAndAwaitAdvance(); // Phase 1 (waiting)
@@ -183,13 +188,13 @@
}
// block until CheckerThread finishes checking
- System.out.println("WaitingThread about to block on ready");
+ log("WaitingThread about to block on ready");
// signal checker thread that it is about acquire
// object ready.
p.arriveAndAwaitAdvance(); // Phase 2 (waiting)
synchronized(ready) {
dummyCounter++;
- };
+ }
}
synchronized(objC) {
try {
@@ -201,7 +206,7 @@
testFailed = true;
}
}
- System.out.println("WaitingThread about to exit waiting on objC 2");
+ log("WaitingThread about to exit waiting on objC 2");
}
}
static class CheckerThread extends Thread {
@@ -304,10 +309,10 @@
private static ThreadInfo findOwnerInfo(ThreadInfo[] infos, String lock)
throws Exception {
ThreadInfo ownerInfo = null;
- for (int i = 0; i < infos.length; i++) {
- String blockedLock = infos[i].getLockName();
+ for (ThreadInfo info : infos) {
+ String blockedLock = info.getLockName();
if (lock.equals(blockedLock)) {
- long threadId = infos[i].getLockOwnerId();
+ long threadId = info.getLockOwnerId();
if (threadId == -1) {
throw new RuntimeException("TEST FAILED: " +
lock + " expected to have owner");
@@ -338,14 +343,17 @@
throws Exception {
ThreadInfo ownerInfo = null;
// Find the thread who is blocking on lock
- for (int i = 0; i < infos.length; i++) {
- String blockedLock = infos[i].getLockName();
+ for (ThreadInfo info : infos) {
+ String blockedLock = info.getLockName();
if (lock.equals(blockedLock)) {
- System.out.print(infos[i].getThreadName() +
- " blocked on " + blockedLock);
- ownerInfo = infos[i];
+ log("%s blocked on %s", info.getThreadName(), blockedLock);
+ ownerInfo = info;
}
}
+ if (ownerInfo == null) {
+ throw new RuntimeException("TEST FAILED: " +
+ "Can't retrieve ThreadInfo for the blocked thread");
+ }
long[] threads = new long[10];
int count = 0;
@@ -353,14 +361,18 @@
while (ownerInfo != null && ownerInfo.getThreadState() == Thread.State.BLOCKED) {
ownerInfo = findOwnerInfo(infos, lock);
threads[count++] = ownerInfo.getThreadId();
- System.out.println(" Owner = " + ownerInfo.getThreadName() +
- " id = " + ownerInfo.getThreadId());
+ log(" Owner = %s id = %d",
+ ownerInfo.getThreadName(),
+ ownerInfo.getThreadId()
+ );
lock = ownerInfo.getLockName();
- System.out.print(ownerInfo.getThreadName() + " Id = " +
- ownerInfo.getThreadId() +
- " blocked on " + lock);
+ log("%s Id = %d blocked on %s",
+ ownerInfo.getThreadName(),
+ ownerInfo.getThreadId(),
+ lock
+ );
}
- System.out.println();
+ log("");
if (count != expectedThreads.length) {
throw new RuntimeException("TEST FAILED: " +
@@ -368,10 +380,15 @@
}
for (int i = 0; i < count; i++) {
if (threads[i] != expectedThreads[i]) {
- System.out.println("TEST FAILED: " +
- "Unexpected thread in the chain " + threads[i] +
- " expected to be " + expectedThreads[i]);
+ log("TEST FAILED: Unexpected thread in the chain %s expected to be %s",
+ threads[i],
+ expectedThreads[i]
+ );
}
}
}
+
+ private static void log(String format, Object ... args) {
+ logger.log(format + "%n", args);
+ }
}
diff --git a/test/java/lang/management/ThreadMXBean/SynchronizationStatistics.java b/test/java/lang/management/ThreadMXBean/SynchronizationStatistics.java
index 6986adc..6cb4bfb 100644
--- a/test/java/lang/management/ThreadMXBean/SynchronizationStatistics.java
+++ b/test/java/lang/management/ThreadMXBean/SynchronizationStatistics.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -34,6 +34,7 @@
import java.lang.management.*;
import java.util.concurrent.Phaser;
+import java.util.function.Supplier;
public class SynchronizationStatistics {
private static class LockerThread extends Thread {
@@ -74,7 +75,7 @@
}
private static void waitForThreadState(Thread t, Thread.State state) throws InterruptedException {
- while (!t.isInterrupted() && t.getState() != state) {
+ while (t.getState() != state) {
Thread.sleep(3);
}
}
@@ -86,6 +87,8 @@
private static void testBlockingOnSimpleMonitor() throws Exception {
System.out.println("testBlockingOnSimpleMonitor");
final Object lock1 = new Object();
+ System.out.println("Lock1 = " + lock1);
+
final Phaser p = new Phaser(2);
LockerThread lt = newLockerThread(new Runnable() {
@Override
@@ -106,16 +109,18 @@
synchronized(lock1) {
p.arriveAndAwaitAdvance(); // phase[1]
waitForThreadState(lt, Thread.State.BLOCKED);
- lockName = mbean.getThreadInfo(tid).getLockName();
+ do {
+ lockName = mbean.getThreadInfo(tid).getLockName();
+ } while (lockName == null);
}
p.arriveAndAwaitAdvance(); // phase[2]
- testBlocked(ti, mbean.getThreadInfo(tid), lockName, lock1);
+ testBlocked(ti, () -> mbean.getThreadInfo(tid), lockName, lock1);
p.arriveAndDeregister(); // phase[3]
lt.join();
- System.out.println("OK");
+ printok();
}
/**
@@ -128,6 +133,9 @@
final Object lock1 = new Object();
final Object lock2 = new Object();
+ System.out.println("Lock1 = " + lock1);
+ System.out.println("Lock2 = " + lock2);
+
final Phaser p = new Phaser(2);
LockerThread lt = newLockerThread(new Runnable() {
@Override
@@ -149,31 +157,32 @@
lt.start();
long tid = lt.getId();
ThreadInfo ti = mbean.getThreadInfo(tid);
- ThreadInfo ti1 = null;
String lockName = null;
synchronized(lock1) {
p.arriveAndAwaitAdvance(); // phase[1]
waitForThreadState(lt, Thread.State.BLOCKED);
- lockName = mbean.getThreadInfo(tid).getLockName();
+ do {
+ lockName = mbean.getThreadInfo(tid).getLockName();
+ } while (lockName == null);
}
p.arriveAndAwaitAdvance(); // phase[2]
- ti1 = mbean.getThreadInfo(tid);
- testBlocked(ti, ti1, lockName, lock1);
- ti = ti1;
+ ti = testBlocked(ti, () -> mbean.getThreadInfo(tid), lockName, lock1);
synchronized(lock2) {
p.arriveAndAwaitAdvance(); // phase [3]
waitForThreadState(lt, Thread.State.BLOCKED);
- lockName = mbean.getThreadInfo(tid).getLockName();
+ do {
+ lockName = mbean.getThreadInfo(tid).getLockName();
+ } while (lockName == null);
}
p.arriveAndAwaitAdvance(); // phase [4]
- testBlocked(ti, mbean.getThreadInfo(tid), lockName, lock2);
+ testBlocked(ti, () -> mbean.getThreadInfo(tid), lockName, lock2);
p.arriveAndDeregister();
lt.join();
- System.out.println("OK");
+ printok();
}
/**
@@ -209,13 +218,12 @@
}
p.arriveAndAwaitAdvance(); // phase[2]
- ThreadInfo ti2 = mbean.getThreadInfo(lt.getId());
+ testWaited(ti1, () -> mbean.getThreadInfo(lt.getId()), 1);
p.arriveAndDeregister(); // phase[3]
lt.join();
- testWaited(ti1, ti2, 1);
- System.out.println("OK");
+ printok();
}
/**
@@ -256,12 +264,12 @@
int phase = p.getPhase();
while ((p.arriveAndAwaitAdvance() - phase) < 3); // phase[2-4]
- ThreadInfo ti2 = mbean.getThreadInfo(lt.getId());
+ testWaited(ti1, () -> mbean.getThreadInfo(lt.getId()), 3);
p.arriveAndDeregister(); // phase[5]
lt.join();
- testWaited(ti1, ti2, 3);
- System.out.println("OK");
+
+ printok();
}
/**
@@ -331,44 +339,85 @@
}
p.arriveAndAwaitAdvance(); // phase[4]
- ThreadInfo ti2 = mbean.getThreadInfo(lt.getId());
+ testWaited(ti1, () -> mbean.getThreadInfo(lt.getId()), 3);
p.arriveAndDeregister(); // phase[5]
lt.join();
- testWaited(ti1, ti2, 3);
- System.out.println("OK");
+ printok();
}
- private static void testWaited(ThreadInfo ti1, ThreadInfo ti2, int waited) throws Error {
- long waitCntDiff = ti2.getWaitedCount() - ti1.getWaitedCount();
- long waitTimeDiff = ti2.getWaitedTime() - ti1.getWaitedTime();
- if (waitCntDiff < waited) {
- throw new Error("Unexpected diff in waited count. Expecting at least "
- + waited + " , got " + waitCntDiff);
- }
- if (waitTimeDiff <= 0) {
- throw new Error("Unexpected diff in waited time. Expecting increasing " +
- "value, got " + waitTimeDiff + "ms");
- }
+ private static void printok() {
+ System.out.println("OK\n");
}
- private static void testBlocked(ThreadInfo ti1, ThreadInfo ti2,
+ private static void testWaited(ThreadInfo ti1, Supplier<ThreadInfo> ti2, int waited)
+ throws InterruptedException {
+ boolean error;
+ do {
+ error = false;
+ ThreadInfo ti = ti2.get();
+ long waitCntDiff = ti.getWaitedCount() - ti1.getWaitedCount();
+ long waitTimeDiff = ti.getWaitedTime() - ti1.getWaitedTime();
+ if (waitCntDiff < waited) {
+ System.err.println(
+ "Unexpected diff in waited count. Expecting at least "
+ + waited + " , got " + waitCntDiff
+ );
+ error = true;
+ }
+ if (waitTimeDiff <= 0) {
+ System.err.println(
+ "Unexpected diff in waited time. Expecting increasing " +
+ "value, got " + waitTimeDiff + "ms"
+ );
+ error = true;
+ }
+ if (error) {
+ System.err.println("Retrying in 20ms ...");
+ Thread.sleep(20);
+ }
+ } while (error);
+ }
+
+ private static ThreadInfo testBlocked(ThreadInfo ti1, Supplier<ThreadInfo> ti2,
String lockName, final Object lock)
- throws Error {
- long blkCntDiff = ti2.getBlockedCount() - ti1.getBlockedCount();
- long blkTimeDiff = ti2.getBlockedTime() - ti1.getBlockedTime();
- if (blkCntDiff < 1) {
- throw new Error("Unexpected diff in blocked count. Expecting at least 1, " +
- "got " + blkCntDiff);
- }
- if (blkTimeDiff < 0) {
- throw new Error("Unexpected diff in blocked time. Expecting a positive " +
- "number, got " + blkTimeDiff);
- }
- if (!lockName.equals(lock.toString())) {
- throw new Error("Unexpected blocked monitor name. Expecting " +
- lock.toString() + ", got " +
- lockName);
- }
+ throws InterruptedException {
+ boolean error;
+ ThreadInfo ti = null;
+ do {
+ error = false;
+ ti = ti2.get();
+ long blkCntDiff = ti.getBlockedCount() - ti1.getBlockedCount();
+ long blkTimeDiff = ti.getBlockedTime() - ti1.getBlockedTime();
+
+ System.out.println("testBlocked: [" + blkCntDiff + ", " + blkTimeDiff + ", " + lockName + "]");
+
+ if (blkCntDiff < 1) {
+ System.err.println(
+ "Unexpected diff in blocked count. Expecting at least 1, " +
+ "got " + blkCntDiff
+ );
+ error = true;
+ }
+ if (blkTimeDiff < 0) {
+ System.err.println(
+ "Unexpected diff in blocked time. Expecting a positive " +
+ "number, got " + blkTimeDiff
+ );
+ error = true;
+ }
+ if (!lockName.equals(lock.toString())) {
+ System.err.println(
+ "Unexpected blocked monitor name. Expecting " +
+ lock.toString() + ", got " + lockName
+ );
+ error = true;
+ }
+ if (error) {
+ System.err.println("Retrying in 20ms ...");
+ Thread.sleep(20);
+ }
+ } while (error);
+ return ti;
}
}
diff --git a/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java b/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java
index 10e374f..a273bfd 100644
--- a/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java
+++ b/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -31,6 +31,8 @@
* @author Mandy Chung
*
* @library ../../Thread
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
* @build ThreadMXBeanStateTest ThreadStateController
* @run main ThreadMXBeanStateTest
*/
@@ -44,15 +46,17 @@
private static final ThreadMXBean tm = ManagementFactory.getThreadMXBean();
static class Lock {
- private String name;
+ private final String name;
Lock(String name) {
this.name = name;
}
+ @Override
public String toString() {
return name;
}
}
- private static Lock globalLock = new Lock("my lock");
+
+ private static final Lock globalLock = new Lock("my lock");
public static void main(String[] argv) throws Exception {
// Force thread state initialization now before the test
@@ -109,7 +113,7 @@
thread.checkThreadState(TERMINATED);
try {
- thread.join();
+ System.out.println(thread.getLog());
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("TEST FAILED: Unexpected exception.");
diff --git a/test/java/math/BigDecimal/DivideTests.java b/test/java/math/BigDecimal/DivideTests.java
index ba12841..a34470d 100644
--- a/test/java/math/BigDecimal/DivideTests.java
+++ b/test/java/math/BigDecimal/DivideTests.java
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4851776 4907265 6177836 6876282
+ * @bug 4851776 4907265 6177836 6876282 8066842
* @summary Some tests for the divide methods.
* @author Joseph D. Darcy
*/
@@ -358,6 +358,57 @@
return failures;
}
+ private static int divideByOneTests() {
+ int failures = 0;
+
+ //problematic divisor: one with scale 17
+ BigDecimal one = BigDecimal.ONE.setScale(17);
+ RoundingMode rounding = RoundingMode.UNNECESSARY;
+
+ long[][] unscaledAndScale = new long[][] {
+ { Long.MAX_VALUE, 17},
+ {-Long.MAX_VALUE, 17},
+ { Long.MAX_VALUE, 0},
+ {-Long.MAX_VALUE, 0},
+ { Long.MAX_VALUE, 100},
+ {-Long.MAX_VALUE, 100}
+ };
+
+ for (long[] uas : unscaledAndScale) {
+ long unscaled = uas[0];
+ int scale = (int)uas[1];
+
+ BigDecimal noRound = null;
+ try {
+ noRound = BigDecimal.valueOf(unscaled, scale).
+ divide(one, RoundingMode.UNNECESSARY);
+ } catch (ArithmeticException e) {
+ failures++;
+ System.err.println("ArithmeticException for value " + unscaled
+ + " and scale " + scale + " without rounding");
+ }
+
+ BigDecimal roundDown = null;
+ try {
+ roundDown = BigDecimal.valueOf(unscaled, scale).
+ divide(one, RoundingMode.DOWN);
+ } catch (ArithmeticException e) {
+ failures++;
+ System.err.println("ArithmeticException for value " + unscaled
+ + " and scale " + scale + " with rounding down");
+ }
+
+ if (noRound != null && roundDown != null
+ && noRound.compareTo(roundDown) != 0) {
+ failures++;
+ System.err.println("Equality failure for value " + unscaled
+ + " and scale " + scale);
+ }
+ }
+
+ return failures;
+ }
+
public static void main(String argv[]) {
int failures = 0;
@@ -366,10 +417,11 @@
failures += properScaleTests();
failures += trailingZeroTests();
failures += scaledRoundedDivideTests();
+ failures += divideByOneTests();
if (failures > 0) {
throw new RuntimeException("Incurred " + failures +
- " failures while testing exact divide.");
+ " failures while testing division.");
}
}
}
diff --git a/test/java/net/ServerSocket/AcceptInheritHandle.java b/test/java/net/ServerSocket/AcceptInheritHandle.java
new file mode 100644
index 0000000..ce175f2
--- /dev/null
+++ b/test/java/net/ServerSocket/AcceptInheritHandle.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8067105
+ * @summary Socket returned by ServerSocket.accept() is inherited by child process on Windows
+ * @author Chris Hegarty
+ */
+
+import java.io.*;
+import java.net.*;
+import java.nio.channels.ServerSocketChannel;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
+public class AcceptInheritHandle {
+
+ enum ServerSocketProducer {
+ JAVA_NET(() -> {
+ try {
+ return new ServerSocket(); }
+ catch(IOException x) {
+ throw new UncheckedIOException(x);
+ }
+ }),
+ NIO_CHANNELS(() -> {
+ try {
+ return ServerSocketChannel.open().socket();
+ } catch (IOException x) {
+ throw new UncheckedIOException(x);
+ }
+ });
+
+ final Supplier<ServerSocket> supplier;
+ ServerSocketProducer(Supplier<ServerSocket> supplier) {
+ this.supplier = supplier;
+ }
+ Supplier<ServerSocket> supplier () { return supplier; }
+ }
+
+ static final String JAVA = System.getProperty("java.home")
+ + File.separator + "bin" + File.separator + "java";
+
+ static final String CLASSPATH = System.getProperty("java.class.path");
+
+ public static void main(String[] args) throws Exception {
+ if (args.length == 1)
+ server(ServerSocketProducer.valueOf(args[0]));
+ else
+ mainEntry();
+ }
+
+ static void mainEntry() throws Exception {
+ testJavaNetServerSocket();
+ testNioServerSocketChannel();
+ }
+
+ static void testJavaNetServerSocket() throws Exception {
+ test(ServerSocketProducer.JAVA_NET);
+ test(ServerSocketProducer.JAVA_NET, "-Djava.net.preferIPv4Stack=true");
+ }
+ static void testNioServerSocketChannel() throws Exception {
+ test(ServerSocketProducer.NIO_CHANNELS);
+ }
+
+ static void test(ServerSocketProducer ssp, String... sysProps) throws Exception {
+ System.out.println("\nStarting test for " + ssp.name());
+
+ List<String> commands = new ArrayList<>();
+ commands.add(JAVA);
+ for (String prop : sysProps)
+ commands.add(prop);
+ commands.add("-cp");
+ commands.add(CLASSPATH);
+ commands.add("AcceptInheritHandle");
+ commands.add(ssp.name());
+
+ System.out.println("Executing: "+ commands);
+ ProcessBuilder pb = new ProcessBuilder(commands);
+ pb.redirectError(ProcessBuilder.Redirect.INHERIT);
+ Process serverProcess = pb.start();
+ DataInputStream dis = new DataInputStream(serverProcess.getInputStream());
+
+ int port = dis.readInt();
+ System.out.println("Server process listening on " + port + ", connecting...");
+
+ Socket socket = new Socket("localhost", port);
+ String s = dis.readUTF();
+ System.out.println("Server process said " + s);
+
+ serverProcess.destroy();
+ serverProcess.waitFor(30, TimeUnit.SECONDS);
+ System.out.println("serverProcess exitCode:" + serverProcess.exitValue());
+
+ try {
+ socket.setSoTimeout(10 * 1000);
+ socket.getInputStream().read();
+ } catch (SocketTimeoutException x) {
+ // failed
+ throw new RuntimeException("Failed: should get reset, not " + x);
+ } catch (SocketException x) {
+ System.out.println("Expected:" + x);
+ }
+ }
+
+ static void server(ServerSocketProducer producer) throws Exception {
+ try (ServerSocket ss = producer.supplier().get()) {
+ ss.bind(new InetSocketAddress(0));
+ int port = ss.getLocalPort();
+ DataOutputStream dos = new DataOutputStream(System.out);
+ dos.writeInt(port);
+ dos.flush();
+
+ ss.accept(); // do not close
+
+ Runtime.getRuntime().exec("sleep 20");
+ Thread.sleep(3 * 1000);
+
+ dos.writeUTF("kill me!");
+ dos.flush();
+ Thread.sleep(30 * 1000);
+ }
+ }
+}
diff --git a/test/java/nio/channels/AsynchronousSocketChannel/StressLoopback.java b/test/java/nio/channels/AsynchronousSocketChannel/StressLoopback.java
index 46b326b..4627aaa 100644
--- a/test/java/nio/channels/AsynchronousSocketChannel/StressLoopback.java
+++ b/test/java/nio/channels/AsynchronousSocketChannel/StressLoopback.java
@@ -24,6 +24,8 @@
/* @test
* @bug 6834246 6842687
* @summary Stress test connections through the loopback interface
+ * @run main StressLoopback
+ * @run main/othervm -Djdk.net.useFastTcpLoopback StressLoopback
*/
import java.nio.ByteBuffer;
diff --git a/test/java/nio/channels/FileChannel/TransferToChannel.java b/test/java/nio/channels/FileChannel/TransferToChannel.java
index 05069d2..44e9633 100644
--- a/test/java/nio/channels/FileChannel/TransferToChannel.java
+++ b/test/java/nio/channels/FileChannel/TransferToChannel.java
@@ -24,6 +24,8 @@
/* @test
* @bug 4652496
* @summary Test transferTo with different target channels
+ * @run main TransferToChannel
+ * @run main/othervm -Djdk.nio.enableFastFileTransfer TransferToChannel
*/
import java.nio.channels.FileChannel;
diff --git a/test/java/nio/channels/SocketChannel/OutOfBand.java b/test/java/nio/channels/SocketChannel/OutOfBand.java
index 83b3266..68b973d 100644
--- a/test/java/nio/channels/SocketChannel/OutOfBand.java
+++ b/test/java/nio/channels/SocketChannel/OutOfBand.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -58,8 +58,6 @@
test1(sc1, sc2);
test2(sc1, sc2);
test3(sc1, sc2);
- test4(sc1);
-
} finally {
if (sc1 != null) sc1.close();
if (sc2 != null) sc2.close();
@@ -175,17 +173,4 @@
thr.join();
}
-
- static void test4(SocketChannel sc) throws IOException {
- boolean blocking = sc.isBlocking();
- sc.configureBlocking(false);
- try {
- sc.socket().sendUrgentData(0);
- throw new RuntimeException("IllegalBlockingModeException expected");
- } catch (IllegalBlockingModeException x) {
- // expected
- } finally {
- sc.configureBlocking(blocking);
- }
- }
}
diff --git a/test/java/nio/channels/SocketChannel/SendUrgentData.java b/test/java/nio/channels/SocketChannel/SendUrgentData.java
new file mode 100644
index 0000000..91f5b3f
--- /dev/null
+++ b/test/java/nio/channels/SocketChannel/SendUrgentData.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/* @test
+ * @bug 8071599
+ * @run main/othervm SendUrgentData
+ * @run main/othervm SendUrgentData -inline
+ * @summary Test sending of urgent data.
+ */
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+
+public class SendUrgentData {
+
+ /**
+ * The arguments may be one of the following:
+ * <ol>
+ * <li>-server</li>
+ * <li>-client host port [-inline]</li>
+ * <li>[-inline]</li>
+ * </ol>
+ * The first option creates a standalone server, the second a standalone
+ * client, and the third a self-contained server-client pair on the
+ * local host.
+ *
+ * @param args
+ * @throws Exception
+ */
+ public static void main(String[] args) throws Exception {
+
+ ServerSocketChannelThread serverThread
+ = new ServerSocketChannelThread("SendUrgentDataServer");
+ serverThread.start();
+ boolean b = serverThread.isAlive();
+
+ String host = null;
+ int port = 0;
+ boolean inline = false;
+ if (args.length > 0 && args[0].equals("-server")) {
+ System.out.println(serverThread.getAddress());
+ Thread.currentThread().suspend();
+ } else {
+ if (args.length > 0 && args[0].equals("-client")) {
+ host = args[1];
+ port = Integer.parseInt(args[2]);
+ if (args.length > 3) {
+ inline = args[2].equals("-inline");
+ }
+ } else {
+ host = "localhost";
+ port = serverThread.getAddress().getPort();
+ if (args.length > 0) {
+ inline = args[0].equals("-inline");
+ }
+ }
+ }
+
+ System.out.println("OOB Inline : "+inline);
+
+ SocketAddress sa = new InetSocketAddress(host, port);
+
+ try (SocketChannel sc = SocketChannel.open(sa)) {
+ sc.configureBlocking(false);
+ sc.socket().setOOBInline(inline);
+
+ sc.socket().sendUrgentData(0);
+ System.out.println("wrote 1 OOB byte");
+
+ ByteBuffer bb = ByteBuffer.wrap(new byte[100 * 1000]);
+
+ int blocked = 0;
+ long total = 0;
+
+ int n;
+ do {
+ n = sc.write(bb);
+ if (n == 0) {
+ System.out.println("blocked, wrote " + total + " so far");
+ if (++blocked == 10) {
+ break;
+ }
+ Thread.sleep(100);
+ } else {
+ total += n;
+ bb.rewind();
+ }
+ } while (n > 0);
+
+ long attempted = 0;
+ while (attempted < total) {
+ bb.rewind();
+ n = sc.write(bb);
+ System.out.println("wrote " + n + " normal bytes");
+ attempted += bb.capacity();
+
+ String osName = System.getProperty("os.name").toLowerCase();
+
+ try {
+ sc.socket().sendUrgentData(0);
+ } catch (IOException ex) {
+ if (osName.contains("linux")) {
+ if (!ex.getMessage().contains("Socket buffer full")) {
+ throw new RuntimeException("Unexpected message", ex);
+ }
+ } else if (osName.contains("os x") || osName.contains("mac")) {
+ if (!ex.getMessage().equals("No buffer space available")) {
+ throw new RuntimeException("Unexpected message", ex);
+ }
+ } else if (osName.contains("windows")) {
+ if (!(ex instanceof SocketException)) {
+ throw new RuntimeException("Unexpected exception", ex);
+ } else if (!ex.getMessage().contains("Resource temporarily unavailable")) {
+ throw new RuntimeException("Unexpected message", ex);
+ }
+ } else {
+ throw new RuntimeException("Unexpected IOException", ex);
+ }
+ }
+
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ex) {
+ // don't want to fail on this so just print trace and break
+ ex.printStackTrace();
+ break;
+ }
+ }
+ } finally {
+ serverThread.close();
+ }
+ }
+
+ static class ServerSocketChannelThread extends Thread {
+
+ private ServerSocketChannel ssc;
+
+ private ServerSocketChannelThread(String name) {
+ super(name);
+ try {
+ ssc = ServerSocketChannel.open();
+ ssc.bind(new InetSocketAddress((0)));
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public void run() {
+ while (ssc.isOpen()) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ try {
+ ssc.close();
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ System.out.println("ServerSocketChannelThread exiting ...");
+ }
+
+ public InetSocketAddress getAddress() throws IOException {
+ if (ssc == null) {
+ throw new IllegalStateException("ServerSocketChannel not created");
+ }
+
+ return (InetSocketAddress) ssc.getLocalAddress();
+ }
+
+ public void close() {
+ try {
+ ssc.close();
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+}
diff --git a/test/java/nio/charset/Charset/RegisteredCharsets.java b/test/java/nio/charset/Charset/RegisteredCharsets.java
index d942369..b7a4b25 100644
--- a/test/java/nio/charset/Charset/RegisteredCharsets.java
+++ b/test/java/nio/charset/Charset/RegisteredCharsets.java
@@ -135,6 +135,7 @@
"x-IBM1122",
"x-IBM1123",
"x-IBM1124",
+ "x-IBM1166",
"x-IBM875",
"x-IBM921",
"x-IBM922",
@@ -863,6 +864,14 @@
"1124"
} );
+ aliasCheck("x-IBM1166" ,
+ new String[] {
+ "cp1166", // JDK historical
+ "ibm1166",
+ "ibm-1166",
+ "1166"
+ } );
+
aliasCheck("IBM273" ,
new String[] {
"cp273", // JDK historical
diff --git a/test/java/nio/charset/RemovingSunIO/SunioAlias.java b/test/java/nio/charset/RemovingSunIO/SunioAlias.java
index af527fc..fe9c359 100644
--- a/test/java/nio/charset/RemovingSunIO/SunioAlias.java
+++ b/test/java/nio/charset/RemovingSunIO/SunioAlias.java
@@ -675,6 +675,12 @@
aliasTable.put("1124", "Cp1124");
// MIBenum: ????
+ aliasTable.put("ibm1166", "Cp1166");
+ aliasTable.put("ibm-1166", "Cp1166");
+ aliasTable.put("cp1166", "Cp1166");
+ aliasTable.put("1166", "Cp1166");
+
+ // MIBenum: ????
aliasTable.put("ibm1381", "Cp1381"); /* MDA */
aliasTable.put("ibm-1381", "Cp1381"); /* MDA */
aliasTable.put("cp1381", "Cp1381"); /* MDA */
diff --git a/test/java/security/ProtectionDomain/PreserveCombinerTest.java b/test/java/security/ProtectionDomain/PreserveCombinerTest.java
new file mode 100644
index 0000000..596d2c1
--- /dev/null
+++ b/test/java/security/ProtectionDomain/PreserveCombinerTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.DomainCombiner;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import sun.misc.SharedSecrets;
+
+/*
+ * @test
+ * @bug 8064331
+ * @summary Make sure that JavaSecurityAccess.doIntersectionPrivilege()
+ * is not dropping the information about the domain combiner of
+ * the stack ACC
+ */
+
+public class PreserveCombinerTest {
+ public static void main(String[]args) throws Exception {
+ final DomainCombiner dc = new DomainCombiner() {
+ @Override
+ public ProtectionDomain[] combine(ProtectionDomain[] currentDomains, ProtectionDomain[] assignedDomains) {
+ return currentDomains; // basically a no-op
+ }
+ };
+
+ // Get an instance of the saved ACC
+ AccessControlContext saved = AccessController.getContext();
+ // Simulate the stack ACC with a DomainCombiner attached
+ AccessControlContext stack = new AccessControlContext(AccessController.getContext(), dc);
+
+ // Now try to run JavaSecurityAccess.doIntersectionPrivilege() and assert
+ // whether the DomainCombiner from the stack ACC is preserved
+ boolean ret = SharedSecrets.getJavaSecurityAccess().doIntersectionPrivilege(new PrivilegedAction<Boolean>() {
+ @Override
+ public Boolean run() {
+ return dc == AccessController.getContext().getDomainCombiner();
+ }
+ }, stack, saved);
+
+ if (!ret) {
+ System.exit(1);
+ }
+ }
+}
+
diff --git a/test/java/util/Arrays/TimSortStackSize2.java b/test/java/util/Arrays/TimSortStackSize2.java
new file mode 100644
index 0000000..a456c88
--- /dev/null
+++ b/test/java/util/Arrays/TimSortStackSize2.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8072909
+ * @run main/othervm -Xms385m TimSortStackSize2 67108864
+ * @summary Test TimSort stack size on big arrays
+ * big tests not for regular execution on all platforms:
+ * run main/othervm -Xmx8g TimSortStackSize2 1073741824
+ * run main/othervm -Xmx16g TimSortStackSize2 2147483644
+ */
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Consumer;
+
+public class TimSortStackSize2 {
+
+ public static void main(String[] args) {
+ int lengthOfTest = Integer.parseInt(args[0]);
+ boolean passed = doTest("TimSort", lengthOfTest,
+ (Integer [] a) -> Arrays.sort(a));
+ passed = doTest("ComparableTimSort", lengthOfTest, (Integer [] a) ->
+ Arrays.sort(a, (Object first, Object second) -> {
+ return ((Comparable<Object>)first).compareTo(second);
+ }))
+ && passed;
+ if ( !passed ){
+ throw new RuntimeException();
+ }
+ }
+
+ private static boolean doTest(final String msg, final int lengthOfTest,
+ final Consumer<Integer[]> c){
+ Integer [] a = null;
+ try {
+ a = new TimSortStackSize2(lengthOfTest).createArray();
+ long begin = System.nanoTime();
+ c.accept(a);
+ long end = System.nanoTime();
+ System.out.println(msg + " OK. Time: " + (end - begin) + "ns");
+ } catch (ArrayIndexOutOfBoundsException e){
+ System.out.println(msg + " broken:");
+ e.printStackTrace();
+ return false;
+ } finally {
+ a = null;
+ }
+ return true;
+ }
+
+ private static final int MIN_MERGE = 32;
+ private final int minRun;
+ private final int length;
+ private final List<Long> runs = new ArrayList<Long>();
+
+ public TimSortStackSize2(final int len) {
+ this.length = len;
+ minRun = minRunLength(len);
+ fillRunsJDKWorstCase();
+ }
+
+ private static int minRunLength(int n) {
+ assert n >= 0;
+ int r = 0; // Becomes 1 if any 1 bits are shifted off
+ while (n >= MIN_MERGE) {
+ r |= (n & 1);
+ n >>= 1;
+ }
+ return n + r;
+ }
+
+ /**
+ * Adds a sequence x_1, ..., x_n of run lengths to <code>runs</code> such that:<br>
+ * 1. X = x_1 + ... + x_n <br>
+ * 2. x_j >= minRun for all j <br>
+ * 3. x_1 + ... + x_{j-2} < x_j < x_1 + ... + x_{j-1} for all j <br>
+ * These conditions guarantee that TimSort merges all x_j's one by one
+ * (resulting in X) using only merges on the second-to-last element.
+ * @param X The sum of the sequence that should be added to runs.
+ */
+ private void generateJDKWrongElem(long X) {
+ for(long newTotal; X >= 2 * minRun + 1; X = newTotal) {
+ //Default strategy
+ newTotal = X / 2 + 1;
+ //Specialized strategies
+ if(3 * minRun + 3 <= X && X <= 4*minRun+1) {
+ // add x_1=MIN+1, x_2=MIN, x_3=X-newTotal to runs
+ newTotal = 2 * minRun + 1;
+ } else if (5 * minRun + 5 <= X && X <= 6 * minRun + 5) {
+ // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=X-newTotal to runs
+ newTotal = 3 * minRun + 3;
+ } else if (8 * minRun + 9 <= X && X <= 10 * minRun + 9) {
+ // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=2MIN+2, x_5=X-newTotal to runs
+ newTotal = 5 * minRun + 5;
+ } else if (13 * minRun + 15 <= X && X <= 16 * minRun + 17) {
+ // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=2MIN+2, x_5=3MIN+4, x_6=X-newTotal to runs
+ newTotal = 8 * minRun + 9;
+ }
+ runs.add(0, X - newTotal);
+ }
+ runs.add(0, X);
+ }
+
+ /**
+ * Fills <code>runs</code> with a sequence of run lengths of the form<br>
+ * Y_n x_{n,1} x_{n,2} ... x_{n,l_n} <br>
+ * Y_{n-1} x_{n-1,1} x_{n-1,2} ... x_{n-1,l_{n-1}} <br>
+ * ... <br>
+ * Y_1 x_{1,1} x_{1,2} ... x_{1,l_1}<br>
+ * The Y_i's are chosen to satisfy the invariant throughout execution,
+ * but the x_{i,j}'s are merged (by <code>TimSort.mergeCollapse</code>)
+ * into an X_i that violates the invariant.
+ * X is the sum of all run lengths that will be added to <code>runs</code>.
+ */
+ private void fillRunsJDKWorstCase() {
+ long runningTotal = 0;
+ long Y = minRun + 4;
+ long X = minRun;
+
+ while (runningTotal + Y + X <= length) {
+ runningTotal += X + Y;
+ generateJDKWrongElem(X);
+ runs.add(0, Y);
+
+ // X_{i+1} = Y_i + x_{i,1} + 1, since runs.get(1) = x_{i,1}
+ X = Y + runs.get(1) + 1;
+
+ // Y_{i+1} = X_{i+1} + Y_i + 1
+ Y += X + 1;
+ }
+
+ if (runningTotal + X <= length) {
+ runningTotal += X;
+ generateJDKWrongElem(X);
+ }
+
+ runs.add(length - runningTotal);
+ }
+
+ private Integer [] createArray() {
+ Integer [] a = new Integer[length];
+ Arrays.fill(a, 0);
+ int endRun = -1;
+ for (long len : runs) {
+ a[endRun += len] = 1;
+ }
+ a[length - 1] = 0;
+ return a;
+ }
+
+}
diff --git a/test/java/util/Calendar/Bug8075548.java b/test/java/util/Calendar/Bug8075548.java
new file mode 100644
index 0000000..121a28b
--- /dev/null
+++ b/test/java/util/Calendar/Bug8075548.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 8075548
+ * @summary Make sure that the format form of month names are produced when there are
+ * no stand-alone ones available.
+ */
+
+import java.text.*;
+import java.util.*;
+import static java.util.Calendar.*;
+
+public class Bug8075548 {
+ static int errors = 0;
+
+ public static void main(String[] args) throws Throwable {
+ Date date = new SimpleDateFormat("yyyy-MM-dd", Locale.US).parse("2010-09-15");
+ String[][] FORMAT_PAIRS = {
+ { "LLLL", "MMMM" },
+ { "LLL", "MMM" }
+ };
+ Locale[] LOCALES = {
+ Locale.ENGLISH, Locale.FRENCH, Locale.GERMAN, Locale.JAPANESE
+ };
+
+ for (Locale locale : LOCALES) {
+ for (String[] formats : FORMAT_PAIRS) {
+ String el = new SimpleDateFormat(formats[0], locale).format(date);
+ String em = new SimpleDateFormat(formats[1], locale).format(date);
+ if (!el.equals(em)) {
+ errors++;
+ System.err.println(locale + ": " +
+ formats[0] + " -> " + el + ", " +
+ formats[1] + " -> " + em);
+ }
+ }
+ }
+
+ // Test Calendar.getDisplayName() and .getDisplayNames().
+ for (Locale locale : LOCALES) {
+ testDisplayNames(locale, LONG_FORMAT, LONG_STANDALONE);
+ testDisplayNames(locale, SHORT_FORMAT, SHORT_STANDALONE);
+ testDisplayNames(locale, NARROW_FORMAT, NARROW_STANDALONE);
+ }
+
+ if (errors > 0) {
+ throw new RuntimeException("Failed");
+ }
+ }
+
+ private static void testDisplayNames(Locale locale, int formatStyle, int standaloneStyle) {
+ Map<String, Integer> map = new HashMap<>();
+ for (int month = JANUARY; month <= DECEMBER; month++) {
+ Calendar cal = new GregorianCalendar(2015, month, 1);
+ String format = cal.getDisplayName(MONTH, formatStyle, locale);
+ String standalone = cal.getDisplayName(MONTH, standaloneStyle, locale);
+ if (!format.equals(standalone)) {
+ System.err.println("Calendar.getDisplayName: " + (month+1) +
+ ", locale=" + locale +
+ ", format=" + format + ", standalone=" + standalone);
+ errors++;
+ }
+ if (standalone != null) {
+ map.put(standalone, month);
+ }
+ }
+ if (formatStyle == NARROW_FORMAT) {
+ // Narrow styles don't support unique names.
+ // (e.g., "J" for JANUARY, JUNE, and JULY)
+ return;
+ }
+ Calendar cal = new GregorianCalendar(2015, JANUARY, 1);
+ Map<String, Integer> mapStandalone = cal.getDisplayNames(MONTH, standaloneStyle, locale);
+ if (!map.equals(mapStandalone)) {
+ System.err.printf("Calendar.getDisplayNames: locale=%s%n map=%s%n mapStandalone=%s%n",
+ locale, map, mapStandalone);
+ errors++;
+ }
+ Map<String, Integer> mapAll = cal.getDisplayNames(MONTH, ALL_STYLES, locale);
+ if (!mapAll.entrySet().containsAll(map.entrySet())) {
+ System.err.printf("Calendar.getDisplayNames: locale=%s%n map=%s%n mapAll=%s%n",
+ locale, map, mapAll);
+ errors++;
+ }
+ }
+}
diff --git a/test/java/util/Calendar/NarrowNamesTest.java b/test/java/util/Calendar/NarrowNamesTest.java
index 7338792..1df0476 100644
--- a/test/java/util/Calendar/NarrowNamesTest.java
+++ b/test/java/util/Calendar/NarrowNamesTest.java
@@ -86,7 +86,19 @@
"\u6728",
"\u91d1",
"\u571f");
- testMap(THTH, MONTH, NARROW_FORMAT); // expect null
+ testMap(THTH, MONTH, NARROW_FORMAT,
+ "\u0e21.\u0e04.",
+ "\u0e01.\u0e1e.",
+ "\u0e21\u0e35.\u0e04.",
+ "\u0e40\u0e21.\u0e22.",
+ "\u0e1e.\u0e04.",
+ "\u0e21\u0e34.\u0e22", // no last dot
+ "\u0e01.\u0e04.",
+ "\u0e2a.\u0e04.",
+ "\u0e01.\u0e22.",
+ "\u0e15.\u0e04.",
+ "\u0e1e.\u0e22.",
+ "\u0e18.\u0e04.");
testMap(THTH, MONTH, NARROW_STANDALONE,
"\u0e21.\u0e04.",
"\u0e01.\u0e1e.",
@@ -146,7 +158,7 @@
Calendar cal = Calendar.getInstance(locale);
Map<String, Integer> got = cal.getDisplayNames(field, style, locale);
if (!(expectedMap == null && got == null)
- && !expectedMap.equals(got)) {
+ && !(expectedMap != null && expectedMap.equals(got))) {
System.err.printf("testMap: locale=%s, field=%d, style=%d, expected=%s, got=%s%n",
locale, field, style, expectedMap, got);
errors++;
diff --git a/test/java/util/Currency/CurrencyTest.java b/test/java/util/Currency/CurrencyTest.java
index 6971442..cb6d35a 100644
--- a/test/java/util/Currency/CurrencyTest.java
+++ b/test/java/util/Currency/CurrencyTest.java
@@ -23,7 +23,7 @@
/*
* @test
* @bug 4290801 4692419 4693631 5101540 5104960 6296410 6336600 6371531
- * 6488442 7036905
+ * 6488442 7036905 8074350 8074351
* @summary Basic tests for Currency class.
*/
@@ -49,6 +49,7 @@
testFractionDigits();
testSerialization();
testDisplayNames();
+ testFundsCodes();
}
static void testCurrencyCodeValidation() {
@@ -265,4 +266,41 @@
}
}
+ static void testFundsCodes() {
+ testValidCurrency("BOV");
+ testValidCurrency("CHE");
+ testValidCurrency("CHW");
+ testValidCurrency("CLF");
+ testValidCurrency("COU");
+ testValidCurrency("MXV");
+ testValidCurrency("USN");
+ testValidCurrency("UYI");
+
+ testFractionDigits("BOV", 2);
+ testFractionDigits("CHE", 2);
+ testFractionDigits("CHW", 2);
+ testFractionDigits("CLF", 4);
+ testFractionDigits("COU", 2);
+ testFractionDigits("MXV", 2);
+ testFractionDigits("USN", 2);
+ testFractionDigits("UYI", 0);
+
+ testNumericCode("BOV", 984);
+ testNumericCode("CHE", 947);
+ testNumericCode("CHW", 948);
+ testNumericCode("CLF", 990);
+ testNumericCode("COU", 970);
+ testNumericCode("MXV", 979);
+ testNumericCode("USN", 997);
+ testNumericCode("UYI", 940);
+ }
+
+ static void testNumericCode(String currencyCode, int expectedNumeric) {
+ int numeric = Currency.getInstance(currencyCode).getNumericCode();
+ if (numeric != expectedNumeric) {
+ throw new RuntimeException("Wrong numeric code for currency " +
+ currencyCode +": expected " + expectedNumeric +
+ ", got " + numeric);
+ }
+ }
}
diff --git a/test/java/util/Currency/PropertiesTest.java b/test/java/util/Currency/PropertiesTest.java
index 4b84e06..96127bf 100644
--- a/test/java/util/Currency/PropertiesTest.java
+++ b/test/java/util/Currency/PropertiesTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -107,7 +107,7 @@
keys = p.stringPropertyNames();
Pattern propertiesPattern =
Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" +
- "([0-3])\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" +
+ "(\\d+)\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" +
"\\d{2}:\\d{2})?");
for (String key: keys) {
String val = p.getProperty(key);
@@ -135,14 +135,20 @@
// ignore this
continue;
}
+
+ String code = m.group(1);
+ int numeric = Integer.parseInt(m.group(2));
+ int fraction = Integer.parseInt(m.group(3));
+ if (fraction > 9) {
+ System.out.println("Skipping since the fraction is greater than 9");
+ continue;
+ }
+
Matcher mAfter = propertiesPattern.matcher(afterVal);
mAfter.find();
- String code = m.group(1);
String codeAfter = mAfter.group(1);
- int numeric = Integer.parseInt(m.group(2));
int numericAfter = Integer.parseInt(mAfter.group(2));
- int fraction = Integer.parseInt(m.group(3));
int fractionAfter = Integer.parseInt(mAfter.group(3));
if (code.equals(codeAfter) &&
(numeric == numericAfter)&&
diff --git a/test/java/util/Currency/PropertiesTest.sh b/test/java/util/Currency/PropertiesTest.sh
index 01f1326..aa4f8d1 100644
--- a/test/java/util/Currency/PropertiesTest.sh
+++ b/test/java/util/Currency/PropertiesTest.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-# Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 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
@@ -23,7 +23,7 @@
#
# @test
-# @bug 6332666 6863624 7180362 8003846
+# @bug 6332666 6863624 7180362 8003846 8074350 8074351
# @summary tests the capability of replacing the currency data with user
# specified currency properties file
# @build PropertiesTest
diff --git a/test/java/util/Currency/ValidateISO4217.java b/test/java/util/Currency/ValidateISO4217.java
index bf433a1..c65c980 100644
--- a/test/java/util/Currency/ValidateISO4217.java
+++ b/test/java/util/Currency/ValidateISO4217.java
@@ -23,6 +23,7 @@
/*
* @test
* @bug 4691089 4819436 4942982 5104960 6544471 6627549 7066203 7195759
+ * 8074350 8074351
* @summary Validate ISO 4217 data for Currency class.
*/
@@ -92,7 +93,7 @@
/* Codes that are obsolete, do not have related country */
static final String otherCodes =
- "ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-CLF-CUC-CYP-DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LUF-MGF-MTL-MXV-MZM-NLG-PTE-ROL-RUR-SDD-SIT-SKK-SRG-TMM-TPE-TRL-VEF-USN-USS-VEB-XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-YUM-ZMK-ZWD-ZWN-ZWR";
+ "ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-CHE-CHW-CLF-COU-CUC-CYP-DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LUF-MGF-MTL-MXV-MZM-NLG-PTE-ROL-RUR-SDD-SIT-SKK-SRG-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-YUM-ZMK-ZWD-ZWN-ZWR";
static boolean err = false;
diff --git a/test/java/util/Currency/currency.properties b/test/java/util/Currency/currency.properties
index ce3c7bb..d8e874d 100644
--- a/test/java/util/Currency/currency.properties
+++ b/test/java/util/Currency/currency.properties
@@ -1,20 +1,30 @@
#
# Test data for replacing the currency data
#
-JP=JPZ,123,2
-ES=ESD,877,2
-US=euR,978,2,2001-01-01T00:00:00
+
+# valid entries
+CL=CLF,990,4
CM=IED,111,2, 2004-01-01T00:70:00
-SB=EUR,111,2, 2099-01-01T00:00:00
-ZZ = ZZZ , 999 , 3
+ES=ESD,877,2
+JP=JPZ,123,2
+MA=MAA,555,5
+MC=MCC,555,6
+MD=MDD,555,7
+ME=MEE,555,8
+MF=MFF,555,9
NO=EUR ,978 ,2, 2099-01-01T00:00:00
+SB=EUR,111,2, 2099-01-01T00:00:00
+US=euR,978,2,2001-01-01T00:00:00
+ZZ = ZZZ , 999 , 3
# invalid entries
-GB=123
-FR=zzzzz.123
DE=2009-01-01T00:00:00,EUR,111,2
-IE=euR,111,2,#testcomment
-=euR,111,2, 2099-01-01-00-00-00
FM=DED,194,2,eeee-01-01T00:00:00
-PE=EUR ,978 ,2, 20399-01-01T00:00:00
+FR=zzzzz.123
+GB=123
+IE=euR,111,2,#testcomment
+MG=MGG,990,10
MX=SSS,493,2,2001-01-01-00-00-00
+PE=EUR ,978 ,2, 20399-01-01T00:00:00
+MG=MGG,990,10
+=euR,111,2, 2099-01-01-00-00-00
diff --git a/test/java/util/Currency/tablea1.txt b/test/java/util/Currency/tablea1.txt
index 2988567..12c9f7e 100644
--- a/test/java/util/Currency/tablea1.txt
+++ b/test/java/util/Currency/tablea1.txt
@@ -5,7 +5,7 @@
#
# Version
-FILEVERSION=1
+FILEVERSION=2
DATAVERSION=159
# ISO 4217 currency data
@@ -55,7 +55,7 @@
CF XAF 950 0
TD XAF 950 0
CL CLP 152 0
-#CL CLF 990 0
+#CL CLF 990 4
CN CNY 156 2
CX AUD 36 2
CC AUD 36 2
@@ -265,6 +265,7 @@
#US USN 997 2
UM USD 840 2
UY UYU 858 2
+#UY UYI 940 0
UZ UZS 860 2
VU VUV 548 0
VE VEF 937 2
diff --git a/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java b/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java
index edd991b..8eab994 100644
--- a/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java
+++ b/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java
@@ -25,6 +25,7 @@
*/
import java.text.*;
+import java.time.format.TextStyle;
import java.util.*;
import sun.util.locale.provider.*;
import sun.util.resources.*;
@@ -42,6 +43,7 @@
test2();
test3();
aliasTest();
+ genericFallbackTest();
}
void test1() {
@@ -169,9 +171,9 @@
for (int style : new int[] { TimeZone.LONG, TimeZone.SHORT }) {
String osakaStd = tz.getDisplayName(false, style, OSAKA);
if (osakaStd != null) {
- // No API for getting generic time zone names
- String generic = TimeZoneNameUtility.retrieveGenericDisplayName(tzname,
- style, GENERIC);
+ String generic = tz.toZoneId().getDisplayName(
+ style == TimeZone.LONG ? TextStyle.FULL : TextStyle.SHORT,
+ GENERIC);
String expected = "Generic " + osakaStd;
if (!expected.equals(generic)) {
throw new RuntimeException("Wrong generic name: got=\"" + generic
@@ -230,4 +232,20 @@
throw new RuntimeException("Provider's localized name is not available for an alias ID: "+JAPAN+". result: "+japan+" expected: "+JST_IN_OSAKA);
}
}
+
+ /*
+ * Tests whether generic names can be retrieved through fallback.
+ * The test assumes the provider impl for OSAKA locale does NOT
+ * provide generic names.
+ */
+ final String PT = "PT"; // SHORT generic name for "America/Los_Angeles"
+ void genericFallbackTest() {
+ String generic =
+ TimeZone.getTimeZone(LATIME)
+ .toZoneId()
+ .getDisplayName(TextStyle.SHORT, OSAKA);
+ if (!PT.equals(generic)) {
+ throw new RuntimeException("Generic name fallback failed. got: "+generic);
+ }
+ }
}
diff --git a/test/java/util/concurrent/CompletableFuture/ThenComposeExceptionTest.java b/test/java/util/concurrent/CompletableFuture/ThenComposeExceptionTest.java
new file mode 100644
index 0000000..877bbb9
--- /dev/null
+++ b/test/java/util/concurrent/CompletableFuture/ThenComposeExceptionTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+
+
+/**
+ * @test
+ * @bug 8068432 8072030
+ * @run testng ThenComposeExceptionTest
+ * @summary Test that CompletableFuture.thenCompose works correctly if the
+ * composing future completes exceptionally
+ */
+@Test
+public class ThenComposeExceptionTest {
+
+ static final BiFunction<CompletableFuture<String>, CompletableFuture<String>, CompletableFuture<String>>
+ THEN_COMPOSE = (f, fe) -> f.thenCompose(s -> fe);
+
+ static final BiFunction<CompletableFuture<String>, CompletableFuture<String>, CompletableFuture<String>>
+ THEN_COMPOSE_ASYNC = (f, fe) -> f.thenComposeAsync(s -> fe);
+
+ static final Consumer<CompletableFuture<String>>
+ COMPLETE_EXCEPTIONALLY = f -> f.completeExceptionally(new RuntimeException());
+
+ static final Consumer<CompletableFuture<String>>
+ NOP = f -> { };
+
+ static Object[][] actionsDataProvider;
+
+ @DataProvider(name = "actions")
+ static Object[][] actionsDataProvider() {
+ if (actionsDataProvider != null) {
+ return actionsDataProvider;
+ }
+
+ List<Object[]> data = new ArrayList<>();
+ data.add(new Object[]{"thenCompose and completeExceptionally", NOP, THEN_COMPOSE, COMPLETE_EXCEPTIONALLY});
+ data.add(new Object[]{"thenComposeAsync and completeExceptionally", NOP, THEN_COMPOSE_ASYNC, COMPLETE_EXCEPTIONALLY});
+ data.add(new Object[]{"completeExceptionally and thenCompose", COMPLETE_EXCEPTIONALLY, THEN_COMPOSE, NOP});
+ data.add(new Object[]{"completeExceptionally and thenComposeAsync", COMPLETE_EXCEPTIONALLY, THEN_COMPOSE_ASYNC, NOP});
+
+ return actionsDataProvider = data.toArray(new Object[0][]);
+ }
+
+ @Test(dataProvider = "actions")
+ public void testThenCompose(
+ String description,
+ Consumer<CompletableFuture<String>> beforeAction,
+ BiFunction<CompletableFuture<String>, CompletableFuture<String>, CompletableFuture<String>> composeFunction,
+ Consumer<CompletableFuture<String>> afterAction) throws Exception {
+ CompletableFuture<String> f = new CompletableFuture<>();
+ CompletableFuture<String> fe = new CompletableFuture<>();
+
+ // Ensure pre-composed stage is completed to trigger
+ // processing the composing future
+ f.complete("");
+
+ beforeAction.accept(fe);
+
+ CompletableFuture<String> f_thenCompose = composeFunction.apply(f, fe);
+ Assert.assertNotSame(f_thenCompose, fe, "Composed CompletableFuture returned directly");
+
+ AtomicReference<Throwable> eOnWhenComplete = new AtomicReference<>();
+ CompletableFuture<String> f_whenComplete = f_thenCompose.
+ whenComplete((r, e) -> eOnWhenComplete.set(e));
+
+ afterAction.accept(fe);
+
+ Throwable eOnJoined = null;
+ try {
+ f_thenCompose.join();
+ }
+ catch (Throwable t) {
+ eOnJoined = t;
+ }
+ Assert.assertTrue(eOnJoined instanceof CompletionException,
+ "Incorrect exception reported when joined on thenCompose: " + eOnJoined);
+
+ // Need to wait for f_whenComplete to complete to avoid
+ // race condition when updating eOnWhenComplete
+ eOnJoined = null;
+ try {
+ f_whenComplete.join();
+ } catch (Throwable t) {
+ eOnJoined = t;
+ }
+ Assert.assertTrue(eOnJoined instanceof CompletionException,
+ "Incorrect exception reported when joined on whenComplete: " + eOnJoined);
+ Assert.assertTrue(eOnWhenComplete.get() instanceof CompletionException,
+ "Incorrect exception passed to whenComplete: " + eOnWhenComplete.get());
+ }
+}
\ No newline at end of file
diff --git a/test/java/util/concurrent/forkjoin/SubmissionTest.java b/test/java/util/concurrent/forkjoin/SubmissionTest.java
new file mode 100644
index 0000000..5a3db57
--- /dev/null
+++ b/test/java/util/concurrent/forkjoin/SubmissionTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/*
+ * @test
+ * @bug 8078490
+ * @summary Test submission and execution of task without joining
+ */
+public class SubmissionTest {
+ public static void main(String[] args) throws Throwable {
+ final ForkJoinPool e = new ForkJoinPool(1);
+ final AtomicBoolean b = new AtomicBoolean();
+ final Runnable setFalse = () -> b.set(false);
+ for (int i = 0; i < 100000; i++) {
+ b.set(true);
+ e.execute(setFalse);
+ long st = System.nanoTime();
+ while (b.get()) {
+ if (System.nanoTime() - st >= TimeUnit.SECONDS.toNanos(10)) {
+ throw new RuntimeException("Submitted task failed to execute");
+ }
+ }
+ }
+ }
+}
diff --git a/test/java/util/logging/HigherResolutionTimeStamps/SerializeLogRecord.java b/test/java/util/logging/HigherResolutionTimeStamps/SerializeLogRecord.java
new file mode 100644
index 0000000..dce4185
--- /dev/null
+++ b/test/java/util/logging/HigherResolutionTimeStamps/SerializeLogRecord.java
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.time.ZoneId;
+import java.util.Base64;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.SimpleFormatter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+/**
+ * @test
+ * @bug 8074125
+ * @summary tests the compatibility of LogRecord serial form between
+ * JDK 8 and JDK 9. Ideally this test should be run on both platforms.
+ * (It is designed to run on both).
+ * @run main/othervm SerializeLogRecord
+ * @author danielfuchs
+ */
+public class SerializeLogRecord {
+
+ /**
+ * Serializes a log record, encode the serialized bytes in base 64, and
+ * prints pseudo java code that can be cut and pasted into this test.
+ * @param record the log record to serialize, encode in base 64, and for
+ * which test data will be generated.
+ * @return A string containing the generated pseudo java code.
+ * @throws IOException Unexpected.
+ * @throws ClassNotFoundException Unexpected.
+ */
+ public static String generate(LogRecord record) throws IOException, ClassNotFoundException {
+
+ // Format the given logRecord using the SimpleFormatter
+ SimpleFormatter formatter = new SimpleFormatter();
+ String str = formatter.format(record);
+
+ // Serialize the given LogRecord
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(record);
+ oos.flush();
+ oos.close();
+
+ // Now we're going to perform a number of smoke tests before
+ // generating the Java pseudo code.
+ //
+ // First checks that the log record can be deserialized
+ final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ final ObjectInputStream ois = new ObjectInputStream(bais);
+ final LogRecord record2 = (LogRecord)ois.readObject();
+
+ // Format the deserialized LogRecord using the SimpleFormatter, and
+ // check that the string representation obtained matches the string
+ // representation of the original LogRecord
+ String str2 = formatter.format(record2);
+ if (!str.equals(str2)) throw new RuntimeException("Unexpected values in deserialized object:"
+ + "\n\tExpected: " + str
+ + "\n\tRetrieved: "+str);
+
+ // Now get a Base64 string representation of the serialized bytes.
+ final String base64 = Base64.getEncoder().encodeToString(baos.toByteArray());
+
+ // Check that we can deserialize a log record from the Base64 string
+ // representation we just computed.
+ final ByteArrayInputStream bais2 = new ByteArrayInputStream(Base64.getDecoder().decode(base64));
+ final ObjectInputStream ois2 = new ObjectInputStream(bais2);
+ final LogRecord record3 = (LogRecord)ois2.readObject();
+
+ // Format the new deserialized LogRecord using the SimpleFormatter, and
+ // check that the string representation obtained matches the string
+ // representation of the original LogRecord
+ String str3 = formatter.format(record3);
+ if (!str.equals(str3)) throw new RuntimeException("Unexpected values in deserialized object:"
+ + "\n\tExpected: " + str
+ + "\n\tRetrieved: "+str);
+ //System.out.println(base64);
+ //System.out.println();
+
+ // Generates the Java Pseudo code that can be cut & pasted into
+ // this test (see Jdk8SerializedLog and Jdk9SerializedLog below)
+ final StringBuilder sb = new StringBuilder();
+ sb.append(" /**").append('\n');
+ sb.append(" * Base64 encoded string for LogRecord object.").append('\n');
+ sb.append(" * Java version: ").append(System.getProperty("java.version")).append('\n');
+ sb.append(" **/").append('\n');
+ sb.append(" final String base64 = ").append("\n ");
+ final int last = base64.length() - 1;
+ for (int i=0; i<base64.length();i++) {
+ if (i%64 == 0) sb.append("\"");
+ sb.append(base64.charAt(i));
+ if (i%64 == 63 || i == last) {
+ sb.append("\"");
+ if (i == last) sb.append(";\n");
+ else sb.append("\n + ");
+ }
+ }
+ sb.append('\n');
+ sb.append(" /**").append('\n');
+ sb.append(" * SimpleFormatter output for LogRecord object.").append('\n');
+ sb.append(" * Java version: ").append(System.getProperty("java.version")).append('\n');
+ sb.append(" **/").append('\n');
+ sb.append(" final String str = ").append("\n ");
+ sb.append("\"").append(str.replace("\n", "\\n")).append("\";\n");
+ return sb.toString();
+ }
+
+ /**
+ * An abstract class to test that a log record previously serialized on a
+ * different java version can be deserialized in the current java version.
+ * (see Jdk8SerializedLog and Jdk9SerializedLog below)
+ */
+ public static abstract class SerializedLog {
+ public abstract String getBase64();
+ public abstract String getString();
+
+ /**
+ * Deserializes the Base64 encoded string returned by {@link
+ * #getBase64()}, format the obtained LogRecord using a
+ * SimpleFormatter, and checks that the string representation obtained
+ * matches the original string representation returned by {@link
+ * #getString()}.
+ */
+ protected void dotest() {
+ try {
+ final String base64 = getBase64();
+ final ByteArrayInputStream bais =
+ new ByteArrayInputStream(Base64.getDecoder().decode(base64));
+ final ObjectInputStream ois = new ObjectInputStream(bais);
+ final LogRecord record = (LogRecord)ois.readObject();
+ final SimpleFormatter formatter = new SimpleFormatter();
+ String expected = getString();
+ String str2 = formatter.format(record);
+ check(expected, str2);
+ System.out.println(str2);
+ System.out.println("PASSED: "+this.getClass().getName()+"\n");
+ } catch (IOException | ClassNotFoundException x) {
+ throw new RuntimeException(x);
+ }
+ }
+ /**
+ * Check that the actual String representation obtained matches the
+ * expected String representation.
+ * @param expected Expected String representation, as returned by
+ * {@link #getString()}.
+ * @param actual Actual String representation obtained by formatting
+ * the LogRecord obtained by the deserialization of the
+ * bytes encoded in {@link #getBase64()}.
+ */
+ protected void check(String expected, String actual) {
+ if (!expected.equals(actual)) {
+ throw new RuntimeException(this.getClass().getName()
+ + " - Unexpected values in deserialized object:"
+ + "\n\tExpected: " + expected
+ + "\n\tRetrieved: "+ actual);
+ }
+ }
+ }
+
+ public static class Jdk8SerializedLog extends SerializedLog {
+
+ // Generated by generate() on JDK 8.
+ // --------------------------------
+ // BEGIN
+
+ /**
+ * Base64 encoded string for LogRecord object.
+ * Java version: 1.8.0_11
+ **/
+ final String base64 =
+ "rO0ABXNyABtqYXZhLnV0aWwubG9nZ2luZy5Mb2dSZWNvcmRKjVk982lRlgMACkoA"
+ + "Bm1pbGxpc0oADnNlcXVlbmNlTnVtYmVySQAIdGhyZWFkSURMAAVsZXZlbHQAGUxq"
+ + "YXZhL3V0aWwvbG9nZ2luZy9MZXZlbDtMAApsb2dnZXJOYW1ldAASTGphdmEvbGFu"
+ + "Zy9TdHJpbmc7TAAHbWVzc2FnZXEAfgACTAAScmVzb3VyY2VCdW5kbGVOYW1lcQB+"
+ + "AAJMAA9zb3VyY2VDbGFzc05hbWVxAH4AAkwAEHNvdXJjZU1ldGhvZE5hbWVxAH4A"
+ + "AkwABnRocm93bnQAFUxqYXZhL2xhbmcvVGhyb3dhYmxlO3hwAAABSjUCgo0AAAAA"
+ + "AAAAAAAAAAFzcgAXamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWyOiHETUXM2kgIAA0kA"
+ + "BXZhbHVlTAAEbmFtZXEAfgACTAAScmVzb3VyY2VCdW5kbGVOYW1lcQB+AAJ4cAAA"
+ + "AyB0AARJTkZPdAAic3VuLnV0aWwubG9nZ2luZy5yZXNvdXJjZXMubG9nZ2luZ3QA"
+ + "BHRlc3R0ABFKYXZhIFZlcnNpb246IHswfXBwcHB3BgEAAAAAAXQACDEuOC4wXzEx"
+ + "eA==";
+
+ /**
+ * SimpleFormatter output for LogRecord object.
+ * Java version: 1.8.0_11
+ **/
+ final String str =
+ "Dec 10, 2014 4:22:44.621000000 PM test - INFO: Java Version: 1.8.0_11";
+ // ^^^
+ // Notice the milli second resolution above...
+
+ // END
+ // --------------------------------
+
+ @Override
+ public String getBase64() {
+ return base64;
+ }
+
+ @Override
+ public String getString() {
+ return str;
+ }
+
+ public static void test() {
+ new Jdk8SerializedLog().dotest();
+ }
+ }
+
+ public static class Jdk9SerializedLog extends SerializedLog {
+
+ // Generated by generate() on JDK 9.
+ // --------------------------------
+ // BEGIN
+
+ /**
+ * Base64 encoded string for LogRecord object.
+ * Java version: 1.9.0-internal
+ **/
+ final String base64 =
+ "rO0ABXNyABtqYXZhLnV0aWwubG9nZ2luZy5Mb2dSZWNvcmRKjVk982lRlgMAC0oA"
+ + "Bm1pbGxpc0kADm5hbm9BZGp1c3RtZW50SgAOc2VxdWVuY2VOdW1iZXJJAAh0aHJl"
+ + "YWRJREwABWxldmVsdAAZTGphdmEvdXRpbC9sb2dnaW5nL0xldmVsO0wACmxvZ2dl"
+ + "ck5hbWV0ABJMamF2YS9sYW5nL1N0cmluZztMAAdtZXNzYWdlcQB+AAJMABJyZXNv"
+ + "dXJjZUJ1bmRsZU5hbWVxAH4AAkwAD3NvdXJjZUNsYXNzTmFtZXEAfgACTAAQc291"
+ + "cmNlTWV0aG9kTmFtZXEAfgACTAAGdGhyb3dudAAVTGphdmEvbGFuZy9UaHJvd2Fi"
+ + "bGU7eHAAAAFLl3u6OAAOU/gAAAAAAAAAAAAAAAFzcgAXamF2YS51dGlsLmxvZ2dp"
+ + "bmcuTGV2ZWyOiHETUXM2kgIAA0kABXZhbHVlTAAEbmFtZXEAfgACTAAScmVzb3Vy"
+ + "Y2VCdW5kbGVOYW1lcQB+AAJ4cAAAAyB0AARJTkZPdAAic3VuLnV0aWwubG9nZ2lu"
+ + "Zy5yZXNvdXJjZXMubG9nZ2luZ3QABHRlc3R0ABFKYXZhIFZlcnNpb246IHswfXBw"
+ + "cHB3BgEAAAAAAXQADjEuOS4wLWludGVybmFseA==";
+
+ /**
+ * SimpleFormatter output for LogRecord object.
+ * Java version: 1.9.0-internal
+ **/
+ final String str =
+ "Feb 17, 2015 12:20:43.192939000 PM test - INFO: Java Version: 1.9.0-internal";
+ // ^^^
+ // Notice the micro second resolution above...
+
+ // END
+ // --------------------------------
+
+ @Override
+ public String getBase64() {
+ return base64;
+ }
+
+ @Override
+ public String getString() {
+ return str;
+ }
+
+ @Override
+ protected void check(String expected, String actual) {
+ if (System.getProperty("java.version").startsWith("1.8")) {
+ // If we are in JDK 8 and print a log record serialized in JDK 9,
+ // then we won't be able to print anything below the millisecond
+ // precision, since that hasn't been implemented in JDK 8.
+ // Therefore - we need to replace anything below millseconds by
+ // zeroes in the expected string (which was generated on JDK 9).
+ Pattern pattern = Pattern.compile("^"
+ + "(.*\\.[0-9][0-9][0-9])" // group1: everything up to milliseconds
+ + "([0-9][0-9][0-9][0-9][0-9][0-9])" // group 2: micros and nanos
+ + "(.* - .*)$"); // group three: all the rest...
+ Matcher matcher = pattern.matcher(expected);
+ if (matcher.matches()) {
+ expected = matcher.group(1) + "000000" + matcher.group(3);
+ }
+ }
+ super.check(expected, actual);
+ }
+
+ public static void test() {
+ new Jdk9SerializedLog().dotest();
+ }
+ }
+
+ public static void generate() {
+ try {
+ LogRecord record = new LogRecord(Level.INFO, "Java Version: {0}");
+ record.setLoggerName("test");
+ record.setParameters(new Object[] {System.getProperty("java.version")});
+ System.out.println(generate(record));
+ } catch (IOException | ClassNotFoundException x) {
+ throw new RuntimeException(x);
+ }
+ }
+
+ static enum TestCase { GENERATE, TESTJDK8, TESTJDK9 };
+
+ public static void main(String[] args) {
+ // Set the locale and time zone to make sure we won't depend on the
+ // test env - in particular we don't want to depend on the
+ // time zone in which the test machine might be located.
+ // So we're gong to use Locale English and Time Zone UTC for this test.
+ // (Maybe that should be Locale.ROOT?)
+ Locale.setDefault(Locale.ENGLISH);
+ TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("UTC")));
+
+ // Set the format property to make sure we always have the nanos, and
+ // to make sure it's the same format than what we used when
+ // computing the formatted string for Jdk8SerializedLog and
+ // Jdk9SerializedLog above.
+ //
+ // If you change the formatting, then you will need to regenerate
+ // the data for Jdk8SerializedLog and Jdk9SerializedLog.
+ //
+ // To do that - just run this test on JDK 8, and cut & paste the
+ // pseudo code printed by generate() into Jdk8SerializedLog.
+ // Then run this test again on JDK 9, and cut & paste the
+ // pseudo code printed by generate() into Jdk9SerializedLog.
+ // [Note: you can pass GENERATE as single arg to main() to avoid
+ // running the actual test]
+ // Finally run the test again to check that it still passes after
+ // your modifications.
+ //
+ System.setProperty("java.util.logging.SimpleFormatter.format",
+ "%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS.%1$tN %1$Tp %2$s - %4$s: %5$s%6$s");
+
+ // If no args, then run everything....
+ if (args == null || args.length == 0) {
+ args = new String[] { "GENERATE", "TESTJDK8", "TESTJDK9" };
+ }
+
+ // Run the specified test case(s)
+ Stream.of(args).map(x -> TestCase.valueOf(x)).forEach((x) -> {
+ switch(x) {
+ case GENERATE: generate(); break;
+ case TESTJDK8: Jdk8SerializedLog.test(); break;
+ case TESTJDK9: Jdk9SerializedLog.test(); break;
+ }
+ });
+ }
+}
diff --git a/test/java/util/zip/TestExtraTime.java b/test/java/util/zip/TestExtraTime.java
index b96c85f..3f965b3 100644
--- a/test/java/util/zip/TestExtraTime.java
+++ b/test/java/util/zip/TestExtraTime.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 4759491 6303183 7012868 8015666 8023713
+ * @bug 4759491 6303183 7012868 8015666 8023713 8068790 8074694 8076641
* @summary Test ZOS and ZIS timestamp in extra field correctly
*/
@@ -40,7 +40,6 @@
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
-
public class TestExtraTime {
public static void main(String[] args) throws Throwable{
@@ -69,6 +68,10 @@
test(mtime, atime, ctime, tz, extra);
}
}
+
+ testNullHandling();
+ testTagOnlyHandling();
+ testTimeConversions();
}
static void test(FileTime mtime, FileTime atime, FileTime ctime,
@@ -154,4 +157,93 @@
}
}
}
+
+ static void testNullHandling() {
+ ZipEntry ze = new ZipEntry("TestExtraTime.java");
+ try {
+ ze.setLastAccessTime(null);
+ throw new RuntimeException("setLastAccessTime(null) should throw NPE");
+ } catch (NullPointerException ignored) {
+ // pass
+ }
+ try {
+ ze.setCreationTime(null);
+ throw new RuntimeException("setCreationTime(null) should throw NPE");
+ } catch (NullPointerException ignored) {
+ // pass
+ }
+ try {
+ ze.setLastModifiedTime(null);
+ throw new RuntimeException("setLastModifiedTime(null) should throw NPE");
+ } catch (NullPointerException ignored) {
+ // pass
+ }
+ }
+
+ // verify that setting and getting any time is possible as per the intent
+ // of 4759491
+ static void testTimeConversions() {
+ // Sample across the entire range
+ long step = Long.MAX_VALUE / 100L;
+ testTimeConversions(Long.MIN_VALUE, Long.MAX_VALUE - step, step);
+
+ // Samples through the near future
+ long currentTime = System.currentTimeMillis();
+ testTimeConversions(currentTime, currentTime + 1_000_000, 10_000);
+ }
+
+ static void testTimeConversions(long from, long to, long step) {
+ ZipEntry ze = new ZipEntry("TestExtraTime.java");
+ for (long time = from; time <= to; time += step) {
+ ze.setTime(time);
+ FileTime lastModifiedTime = ze.getLastModifiedTime();
+ if (lastModifiedTime.toMillis() != time) {
+ throw new RuntimeException("setTime should make getLastModifiedTime " +
+ "return the specified instant: " + time +
+ " got: " + lastModifiedTime.toMillis());
+ }
+ if (ze.getTime() != time) {
+ throw new RuntimeException("getTime after setTime, expected: " +
+ time + " got: " + ze.getTime());
+ }
+ }
+ }
+
+ static void check(ZipEntry ze, byte[] extra) {
+ if (extra != null) {
+ byte[] extra1 = ze.getExtra();
+ if (extra1 == null || extra1.length < extra.length ||
+ !Arrays.equals(Arrays.copyOfRange(extra1,
+ extra1.length - extra.length,
+ extra1.length),
+ extra)) {
+ throw new RuntimeException("Timestamp: storing extra field failed!");
+ }
+ }
+ }
+
+ static void testTagOnlyHandling() throws Throwable {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] extra = new byte[] { 0x0a, 0, 4, 0, 0, 0, 0, 0 };
+ try (ZipOutputStream zos = new ZipOutputStream(baos)) {
+ ZipEntry ze = new ZipEntry("TestExtraTime.java");
+ ze.setExtra(extra);
+ zos.putNextEntry(ze);
+ zos.write(new byte[] { 1,2 ,3, 4});
+ }
+ try (ZipInputStream zis = new ZipInputStream(
+ new ByteArrayInputStream(baos.toByteArray()))) {
+ ZipEntry ze = zis.getNextEntry();
+ check(ze, extra);
+ }
+ Path zpath = Paths.get(System.getProperty("test.dir", "."),
+ "TestExtraTime.zip");
+ Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath);
+ try (ZipFile zf = new ZipFile(zpath.toFile())) {
+ ZipEntry ze = zf.getEntry("TestExtraTime.java");
+ check(ze, extra);
+ } finally {
+ Files.delete(zpath);
+ }
+ }
}
diff --git a/test/javax/accessibility/8069268/bug8069268.java b/test/javax/accessibility/8069268/bug8069268.java
new file mode 100644
index 0000000..488bdd4
--- /dev/null
+++ b/test/javax/accessibility/8069268/bug8069268.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+
+/*
+ @test
+ @bug 8069268
+ @summary Tests that only one ContainerListener exists for AccessibleJComponent of JRootPane
+ @author Vivi An
+*/
+import javax.swing.*;
+import java.awt.event.*;
+import javax.accessibility.*;
+
+public class bug8069268{
+ public static void main(String[] args) throws Exception {
+ TestableRootPane rootPane = new TestableRootPane();
+
+ // Get accesibleContext and then AccessibleJComponent, call the function
+ // addPropertyChangeListener to trigger container listener to be added
+ AccessibleContext acc = rootPane.getAccessibleContext();
+ JComponent.AccessibleJComponent accJ = (JComponent.AccessibleJComponent) acc;
+ accJ.addPropertyChangeListener(null);
+
+ // Test how many container listener(s) exist(s), should only have 1
+ if (!rootPane.testContainerListener())
+ throw new RuntimeException("Failed test for bug 8069268");
+ }
+
+ private static class TestableRootPane extends JRootPane {
+ public boolean testContainerListener() {
+ boolean result = false;
+ ContainerListener[] listeners = getContainerListeners();
+ System.out.println("ContainerListener number is " + listeners.length);
+ result = (listeners.length == 1) ? true : false;
+ return result;
+ }
+ }
+}
diff --git a/test/javax/imageio/plugins/shared/CanWriteSequence.java b/test/javax/imageio/plugins/shared/CanWriteSequence.java
new file mode 100644
index 0000000..54da1b7
--- /dev/null
+++ b/test/javax/imageio/plugins/shared/CanWriteSequence.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.stream.ImageOutputStream;
+
+/**
+ * @test
+ * @bug 4958064
+ * @author Sergey Bylokhov
+ */
+public final class CanWriteSequence {
+
+ public static void main(final String[] args) throws Exception {
+ final IIORegistry registry = IIORegistry.getDefaultInstance();
+ final Iterator<ImageWriterSpi> iter =
+ registry.getServiceProviders(ImageWriterSpi.class,
+ provider -> true, true);
+ // Validates all supported ImageWriters
+ while (iter.hasNext()) {
+ final ImageWriter writer = iter.next().createWriterInstance();
+ System.out.println("ImageWriter = " + writer);
+ test(writer);
+ }
+ System.out.println("Test passed");
+ }
+
+ private static void test(final ImageWriter writer) throws Exception {
+ final File file = File.createTempFile("temp", ".img");
+ file.deleteOnExit();
+ final FileOutputStream fos = new FileOutputStream(file);
+ final ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
+ writer.setOutput(ios);
+ final IIOMetadata data = writer.getDefaultStreamMetadata(null);
+
+ if (writer.canWriteSequence()) {
+ writer.prepareWriteSequence(data);
+ } else {
+ try {
+ writer.prepareWriteSequence(data);
+ throw new RuntimeException(
+ "UnsupportedOperationException was not thrown");
+ } catch (final UnsupportedOperationException ignored) {
+ // expected
+ }
+ }
+ writer.dispose();
+ ios.close();
+ }
+}
\ No newline at end of file
diff --git a/test/javax/imageio/plugins/shared/WriteAfterAbort.java b/test/javax/imageio/plugins/shared/WriteAfterAbort.java
new file mode 100644
index 0000000..4b503d2
--- /dev/null
+++ b/test/javax/imageio/plugins/shared/WriteAfterAbort.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.event.IIOWriteProgressListener;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.stream.ImageOutputStream;
+
+import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
+
+/**
+ * @test
+ * @bug 4952954
+ * @summary abortFlag must be cleared for every ImageWriter.write operation
+ * @author Sergey Bylokhov
+ */
+public final class WriteAfterAbort implements IIOWriteProgressListener {
+
+ private volatile boolean abortFlag = true;
+ private volatile boolean isAbortCalled;
+ private volatile boolean isCompleteCalled;
+ private volatile boolean isProgressCalled;
+ private volatile boolean isStartedCalled;
+ private static final int WIDTH = 100;
+ private static final int HEIGHT = 100;
+
+ private void test(final ImageWriter writer) throws IOException {
+ // Image initialization
+ final BufferedImage imageWrite = new BufferedImage(WIDTH, HEIGHT,
+ TYPE_BYTE_BINARY);
+ final Graphics2D g = imageWrite.createGraphics();
+ g.setColor(Color.WHITE);
+ g.fillRect(0, 0, WIDTH, HEIGHT);
+ g.dispose();
+
+ // File initialization
+ final File file = File.createTempFile("temp", ".img");
+ file.deleteOnExit();
+ final FileOutputStream fos = new SkipWriteOnAbortOutputStream(file);
+ final ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
+ writer.setOutput(ios);
+ writer.addIIOWriteProgressListener(this);
+
+ // This write will be aborted, and file will not be touched
+ writer.write(imageWrite);
+ if (!isStartedCalled) {
+ throw new RuntimeException("Started should be called");
+ }
+ if (!isProgressCalled) {
+ throw new RuntimeException("Progress should be called");
+ }
+ if (!isAbortCalled) {
+ throw new RuntimeException("Abort should be called");
+ }
+ if (isCompleteCalled) {
+ throw new RuntimeException("Complete should not be called");
+ }
+ // Flush aborted data
+ ios.flush();
+
+ // This write should be completed successfully and the file should
+ // contain correct image data.
+ abortFlag = false;
+ isAbortCalled = false;
+ isCompleteCalled = false;
+ isProgressCalled = false;
+ isStartedCalled = false;
+ writer.write(imageWrite);
+
+ if (!isStartedCalled) {
+ throw new RuntimeException("Started should be called");
+ }
+ if (!isProgressCalled) {
+ throw new RuntimeException("Progress should be called");
+ }
+ if (isAbortCalled) {
+ throw new RuntimeException("Abort should not be called");
+ }
+ if (!isCompleteCalled) {
+ throw new RuntimeException("Complete should be called");
+ }
+ writer.dispose();
+ ios.close();
+
+ // Validates content of the file.
+ final BufferedImage imageRead = ImageIO.read(file);
+ for (int x = 0; x < WIDTH; ++x) {
+ for (int y = 0; y < HEIGHT; ++y) {
+ if (imageRead.getRGB(x, y) != imageWrite.getRGB(x, y)) {
+ throw new RuntimeException("Test failed.");
+ }
+ }
+ }
+ }
+
+ public static void main(final String[] args) throws IOException {
+ final IIORegistry registry = IIORegistry.getDefaultInstance();
+ final Iterator<ImageWriterSpi> iter = registry.getServiceProviders(
+ ImageWriterSpi.class, provider -> true, true);
+
+ // Validates all supported ImageWriters
+ while (iter.hasNext()) {
+ final WriteAfterAbort writeAfterAbort = new WriteAfterAbort();
+ final ImageWriter writer = iter.next().createWriterInstance();
+ System.out.println("ImageWriter = " + writer);
+ writeAfterAbort.test(writer);
+ }
+ System.out.println("Test passed");
+ }
+
+ // Callbacks
+
+ @Override
+ public void imageComplete(ImageWriter source) {
+ isCompleteCalled = true;
+ }
+
+ @Override
+ public void imageProgress(ImageWriter source, float percentageDone) {
+ isProgressCalled = true;
+ if (percentageDone > 50 && abortFlag) {
+ source.abort();
+ }
+ }
+
+ @Override
+ public void imageStarted(ImageWriter source, int imageIndex) {
+ isStartedCalled = true;
+ }
+
+ @Override
+ public void writeAborted(final ImageWriter source) {
+ isAbortCalled = true;
+ }
+
+ @Override
+ public void thumbnailComplete(ImageWriter source) {
+ }
+
+ @Override
+ public void thumbnailProgress(ImageWriter source, float percentageDone) {
+ }
+
+ @Override
+ public void thumbnailStarted(ImageWriter source, int imageIndex,
+ int thumbnailIndex) {
+ }
+
+ /**
+ * We need to skip writes on abort, because content of the file after abort
+ * is undefined.
+ */
+ private class SkipWriteOnAbortOutputStream extends FileOutputStream {
+
+ SkipWriteOnAbortOutputStream(File file) throws FileNotFoundException {
+ super(file);
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ if (!abortFlag) {
+ super.write(b);
+ }
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ if (!abortFlag) {
+ super.write(b);
+ }
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (!abortFlag) {
+ super.write(b, off, len);
+ }
+ }
+ }
+}
+
diff --git a/test/javax/imageio/stream/ShortStreamTest.java b/test/javax/imageio/stream/ShortStreamTest.java
new file mode 100644
index 0000000..2b133a5
--- /dev/null
+++ b/test/javax/imageio/stream/ShortStreamTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 8074954
+ * @summary Test verifies that an IOException is triggered if input stream
+ * does not contain enough data to read a multi-byte type.
+ *
+ * @run main ShortStreamTest
+ */
+
+import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+public class ShortStreamTest {
+ public static void main(String[] args) throws IOException {
+ TestCase[] tests = createTests();
+
+ for (TestCase t : tests) {
+ t.test();
+ }
+ }
+
+ private static abstract class TestCase {
+ abstract void testRead(ImageInputStream iis) throws IOException;
+
+ public void test() {
+ boolean gotException = false;
+
+ ImageInputStream iis = createShortStream();
+
+ try {
+ testRead(iis);
+ } catch (IOException e) {
+ e.printStackTrace(System.out);
+ gotException = true;
+ }
+
+ if (!gotException) {
+ throw new RuntimeException("Test failed.");
+ }
+ System.out.println("Test PASSED");
+ }
+ }
+
+
+ private static ImageInputStream createShortStream() {
+ try {
+ byte[] integerTestArray = new byte[] { 80 };
+ ByteArrayInputStream bais = new ByteArrayInputStream(integerTestArray);
+
+ return ImageIO.createImageInputStream(bais);
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ private static TestCase[] createTests() {
+ return new TestCase[]{
+ new TestCase() {
+ @Override
+ void testRead(ImageInputStream iis) throws IOException {
+ iis.readInt();
+ }
+ },
+ new TestCase() {
+ @Override
+ void testRead(ImageInputStream iis) throws IOException {
+ iis.readShort();
+ }
+ },
+ new TestCase() {
+ @Override
+ void testRead(ImageInputStream iis) throws IOException {
+ iis.readDouble();
+ }
+ },
+ new TestCase() {
+ @Override
+ void testRead(ImageInputStream iis) throws IOException {
+ iis.readFloat();
+ }
+ },
+ new TestCase() {
+ @Override
+ void testRead(ImageInputStream iis) throws IOException {
+ iis.readLong();
+ }
+ },
+ new TestCase() {
+ @Override
+ void testRead(ImageInputStream iis) throws IOException {
+ iis.readUnsignedInt();
+ }
+ },
+ new TestCase() {
+ @Override
+ void testRead(ImageInputStream iis) throws IOException {
+ iis.readUnsignedShort();
+ }
+ }
+ };
+ }
+}
diff --git a/test/javax/management/monitor/CounterMonitorDeadlockTest.java b/test/javax/management/monitor/CounterMonitorDeadlockTest.java
index adef67a..f241ccf 100644
--- a/test/javax/management/monitor/CounterMonitorDeadlockTest.java
+++ b/test/javax/management/monitor/CounterMonitorDeadlockTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -37,7 +37,6 @@
import java.lang.management.ManagementFactory;
import java.util.concurrent.atomic.AtomicInteger;
-import javax.management.Attribute;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.Notification;
@@ -95,18 +94,16 @@
monitorProxy.setInitThreshold(100);
monitorProxy.setGranularityPeriod(10L); // 10 ms
monitorProxy.setNotify(true);
- monitorProxy.start();
final int initGetCount = observedProxy.getGetCount();
- int getCount = initGetCount;
- for (int i = 0; i < 500; i++) { // 500 * 10 = 5 seconds
- getCount = observedProxy.getGetCount();
- if (getCount != initGetCount)
- break;
- Thread.sleep(10);
- }
- if (getCount <= initGetCount)
- throw new Exception("Test failed: presumable deadlock");
+ monitorProxy.start();
+
+ System.out.println("Checking GetCount, possible deadlock if timeout.");
+ do { // 8038322. Until timeout of testing harness
+ Thread.sleep(200);
+ } while ((observedProxy.getGetCount()) == initGetCount);
+ System.out.println("Done!");
+
// This won't show up as a deadlock in CTRL-\ or in
// ThreadMXBean.findDeadlockedThreads(), because they don't
// see that thread A is waiting for thread B (B.join()), and
@@ -131,10 +128,11 @@
};
mbs.addNotificationListener(monitorName, listener, null, null);
observedProxy.setThing(1000);
- for (int i = 0; i < 500 && notifCount.get() == 0; i++)
- Thread.sleep(10);
- if (notifCount.get() == 0)
- throw new Exception("Test failed: presumable deadlock");
+ System.out.println("Waiting notifCount.get() != 0, possible deadlock if timeout.");
+ do {
+ Thread.sleep(200);
+ } while(notifCount.get() == 0); // 8038322. Until timeout of testing harness
+ System.out.println("Done");
}
}
diff --git a/test/javax/management/remote/mandatory/notif/NotSerializableNotifTest.java b/test/javax/management/remote/mandatory/notif/NotSerializableNotifTest.java
index 24bf863..538658f 100644
--- a/test/javax/management/remote/mandatory/notif/NotSerializableNotifTest.java
+++ b/test/javax/management/remote/mandatory/notif/NotSerializableNotifTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -34,37 +34,31 @@
// java imports
//
import java.net.MalformedURLException;
-import java.util.Map;
-
-// JMX imports
-//
-import javax.management.* ;
-
-import javax.management.remote.*;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerFactory;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
public class NotSerializableNotifTest {
private static final MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer();
private static ObjectName emitter;
- private static int port = 2468;
private static String[] protocols;
private static final int sentNotifs = 10;
- private static double timeoutFactor = 1.0;
- private static final double defaultTimeout = 10;
-
public static void main(String[] args) throws Exception {
System.out.println(">>> Test to send a not serializable notification");
- String timeoutVal = System.getProperty("test.timeout.factor");
- if (timeoutVal != null) {
- timeoutFactor = Double.parseDouble(
- System.getProperty("test.timeout.factor")
- );
- }
-
// IIOP fails on JDK1.4, see 5034318
final String v = System.getProperty("java.version");
float f = Float.parseFloat(v.substring(0, 3));
@@ -77,35 +71,18 @@
emitter = new ObjectName("Default:name=NotificationEmitter");
mbeanServer.registerMBean(new NotificationEmitter(), emitter);
- boolean ok = true;
for (int i = 0; i < protocols.length; i++) {
- try {
- if (!test(protocols[i])) {
- System.out.println(">>> Test failed for " + protocols[i]);
- ok = false;
- } else {
- System.out.println(">>> Test successed for " + protocols[i]);
- }
- } catch (Exception e) {
- System.out.println(">>> Test failed for " + protocols[i]);
- e.printStackTrace(System.out);
- ok = false;
- }
+ test(protocols[i]);
}
- if (ok) {
- System.out.println(">>> Test passed");
- } else {
- System.out.println(">>> TEST FAILED");
- System.exit(1);
- }
+ System.out.println(">>> Test passed");
}
- private static boolean test(String proto) throws Exception {
+ private static void test(String proto) throws Exception {
System.out.println("\n>>> Test for protocol " + proto);
- JMXServiceURL url = new JMXServiceURL(proto, null, port++);
+ JMXServiceURL url = new JMXServiceURL(proto, null, 0);
System.out.println(">>> Create a server: "+url);
@@ -115,7 +92,7 @@
} catch (MalformedURLException e) {
System.out.println("System does not recognize URL: " + url +
"; ignoring");
- return true;
+ return;
}
server.start();
@@ -146,34 +123,17 @@
// waiting ...
synchronized (listener) {
- int top = (int)Math.ceil(timeoutFactor * defaultTimeout);
- for (int i=0; i<top; i++) {
- if (listener.received() < sentNotifs) {
- listener.wait(1000);
- } else {
- break;
- }
+ while (listener.received() < sentNotifs) {
+ listener.wait(); // either pass or test timeout (killed by test harness)
+
}
}
- // check
- boolean ok = true;
-
- if (listener.received() != sentNotifs) {
- System.out.println("Failed: received "+listener.received()+
- " but should be "+sentNotifs);
- ok = false;
- } else {
- System.out.println("The client received all notifications.");
- }
-
// clean
client.removeNotificationListener(emitter, listener);
conn.close();
server.stop();
-
- return ok;
}
//--------------------------
diff --git a/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java b/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java
index 1dd7927..fca338f 100644
--- a/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java
+++ b/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -37,6 +37,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Semaphore;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerFactory;
@@ -56,10 +58,12 @@
public class NotificationAccessControllerTest {
public class NAC implements NotificationAccessController {
- private boolean throwException;
+ private final boolean throwException;
public NAC(boolean throwException) {
this.throwException = throwException;
}
+
+ @Override
public void addNotificationListener(
String connectionId,
ObjectName name,
@@ -73,9 +77,13 @@
if (throwException)
if (name.getCanonicalName().equals("domain:name=1,type=NB")
&&
+ subject != null
+ &&
subject.getPrincipals().contains(new JMXPrincipal("role")))
throw new SecurityException();
}
+
+ @Override
public void removeNotificationListener(
String connectionId,
ObjectName name,
@@ -89,9 +97,13 @@
if (throwException)
if (name.getCanonicalName().equals("domain:name=2,type=NB")
&&
+ subject != null
+ &&
subject.getPrincipals().contains(new JMXPrincipal("role")))
throw new SecurityException();
}
+
+ @Override
public void fetchNotification(
String connectionId,
ObjectName name,
@@ -105,13 +117,17 @@
echo("\tsubject: " +
(subject == null ? null : subject.getPrincipals()));
if (!throwException)
- if (name.getCanonicalName().equals("domain:name=2,type=NB") &&
+ if (name.getCanonicalName().equals("domain:name=2,type=NB")
+ &&
+ subject != null
+ &&
subject.getPrincipals().contains(new JMXPrincipal("role")))
throw new SecurityException();
}
}
public class CustomJMXAuthenticator implements JMXAuthenticator {
+ @Override
public Subject authenticate(Object credentials) {
String role = ((String[]) credentials)[0];
echo("\nCreate principal with name = " + role);
@@ -129,6 +145,7 @@
public static class NB
extends NotificationBroadcasterSupport
implements NBMBean {
+ @Override
public void emitNotification(int seqnum, ObjectName name) {
if (name == null) {
sendNotification(new Notification("nb", this, seqnum));
@@ -139,13 +156,20 @@
}
public class Listener implements NotificationListener {
- public List<Notification> notifs = new ArrayList<Notification>();
+ public final List<Notification> notifs = new CopyOnWriteArrayList<>();
+
+ private final Semaphore s;
+ public Listener(Semaphore s) {
+ this.s = s;
+ }
+ @Override
public void handleNotification(Notification n, Object h) {
echo("handleNotification:");
echo("\tNotification = " + n);
echo("\tNotification.SeqNum = " + n.getSequenceNumber());
echo("\tHandback = " + h);
notifs.add(n);
+ s.release();
}
}
@@ -192,6 +216,17 @@
JMXConnectorServer server = null;
JMXConnector client = null;
+ /*
+ * (!enableChecks)
+ * - List must contain three notifs from sources nb1, nb2 and nb3
+ * (enableChecks && !throwException)
+ * - List must contain one notif from source nb1
+ * (enableChecks && throwException)
+ * - List must contain two notifs from sources nb2 and nb3
+ */
+ final int expected_notifs =
+ (!enableChecks ? 3 : (throwException ? 2 : 1));
+
// Create a new MBeanServer
//
final MBeanServer mbs = MBeanServerFactory.createMBeanServer();
@@ -199,7 +234,7 @@
try {
// Create server environment map
//
- final Map<String,Object> env = new HashMap<String,Object>();
+ final Map<String,Object> env = new HashMap<>();
env.put("jmx.remote.authenticator", new CustomJMXAuthenticator());
if (enableChecks) {
env.put("com.sun.jmx.remote.notification.access.controller",
@@ -222,7 +257,7 @@
// Create server environment map
//
- final Map<String,Object> cenv = new HashMap<String,Object>();
+ final Map<String,Object> cenv = new HashMap<>();
String[] credentials = new String[] { "role" , "password" };
cenv.put("jmx.remote.credentials", credentials);
@@ -246,7 +281,9 @@
// Add notification listener
//
- Listener li = new Listener();
+ Semaphore s = new Semaphore(0);
+
+ Listener li = new Listener(s);
try {
mbsc.addNotificationListener(nb1, li, null, null);
if (enableChecks && throwException) {
@@ -263,6 +300,9 @@
}
mbsc.addNotificationListener(nb2, li, null, null);
+ System.out.println("\n+++ Expecting to receive " + expected_notifs +
+ " notification" + (expected_notifs > 1 ? "s" : "") +
+ " +++");
// Invoke the "sendNotification" method
//
mbsc.invoke(nb1, "emitNotification",
@@ -277,7 +317,7 @@
// Wait for notifications to be emitted
//
- Thread.sleep(2000);
+ s.acquire(expected_notifs);
// Remove notification listener
//
@@ -303,21 +343,7 @@
sources.add(nb1);
sources.add(nb2);
sources.add(nb3);
- if (!enableChecks) {
- // List must contain three notifs from sources nb1, nb2 and nb3
- //
- result = checkNotifs(3, li.notifs, sources);
- }
- if (enableChecks && !throwException) {
- // List must contain one notif from source nb1
- //
- result = checkNotifs(1, li.notifs, sources);
- }
- if (enableChecks && throwException) {
- // List must contain two notifs from sources nb2 and nb3
- //
- result = checkNotifs(2, li.notifs, sources);
- }
+ result = checkNotifs(expected_notifs, li.notifs, sources);
if (result > 0) {
return result;
}
diff --git a/test/javax/management/remote/mandatory/notif/NotificationBufferDeadlockTest.java b/test/javax/management/remote/mandatory/notif/NotificationBufferDeadlockTest.java
index 79b2e97..e050207 100644
--- a/test/javax/management/remote/mandatory/notif/NotificationBufferDeadlockTest.java
+++ b/test/javax/management/remote/mandatory/notif/NotificationBufferDeadlockTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -24,7 +24,8 @@
/*
* @test
* @bug 6239400
- * @summary Tests NotificationBuffer doesn't hold locks when adding listeners.
+ * @summary Tests NotificationBuffer doesn't hold locks when adding listeners,
+ * if test times out then deadlock is suspected.
* @author Eamonn McManus
* @run clean NotificationBufferDeadlockTest
* @run build NotificationBufferDeadlockTest
@@ -38,6 +39,7 @@
import java.util.List;
import java.util.Set;
import java.util.Vector;
+import java.util.concurrent.CountDownLatch;
import javax.management.*;
import javax.management.remote.*;
@@ -173,9 +175,7 @@
for (ObjectName name : names)
mbsc.invoke(name, "send", null, null);
- if (!countListener.waiting(MAX_WAITING_TIME)) {
- return "did not get " + names.size() + " notifs as expected\n";
- }
+ countListener.waiting();
if (!sources.containsAll(names))
return "missing names: " + sources;
@@ -202,13 +202,13 @@
}
};
t.start();
+ System.out.println("DeadlockTest-addNotificationListener waiting for the sending thread to die...");
try {
- t.join(5000L);
+ t.join(); //if times out here then deadlock is suspected
+ System.out.println("DeadlockTest-addNotificationListener OK.");
} catch (Exception e) {
thisFailure = "Join exception: " + e;
}
- if (t.isAlive())
- thisFailure = "Deadlock detected";
}
public void send() {
@@ -244,9 +244,9 @@
}
};
t.start();
- t.join(5000);
- if (t.isAlive())
- failure = "Query deadlock detected";
+ System.out.println("CreateDuringQueryInvocationHandler-createMBeanIfQuery waiting for the creating thread to die...");
+ t.join(); // if times out here then deadlock is suspected
+ System.out.println("CreateDuringQueryInvocationHandler-createMBeanIfQuery OK");
}
}
@@ -264,50 +264,30 @@
private static class MyListener implements NotificationListener {
public MyListener(int waitNB) {
- this.waitNB= waitNB;
+ count = new CountDownLatch(waitNB);
}
public void handleNotification(Notification n, Object h) {
- System.out.println("MyListener got: "+n.getSource()+" "+n.getType());
+ System.out.println("MyListener got: " + n.getSource() + " " + n.getType());
- synchronized(this) {
- if (TESTING_TYPE.equals(n.getType())) {
- sources.add((ObjectName) n.getSource());
-
- if (sources.size() == waitNB) {
- this.notifyAll();
- }
- }
+ if (TESTING_TYPE.equals(n.getType())) {
+ sources.add((ObjectName) n.getSource());
+ count.countDown();
}
}
- public boolean waiting(long timeout) {
- final long startTime = System.currentTimeMillis();
- long toWait = timeout;
-
- synchronized(this) {
- while(sources.size() < waitNB && toWait > 0) {
- try {
- this.wait(toWait);
- } catch (InterruptedException ire) {
- break;
- }
-
- toWait = timeout -
- (System.currentTimeMillis() - startTime);
- }
- }
-
- return sources.size() == waitNB;
+ public void waiting() throws InterruptedException {
+ System.out.println("MyListener-waiting ...");
+ count.await(); // if times out here then deadlock is suspected
+ System.out.println("MyListener-waiting done!");
}
- private final int waitNB;
+ private final CountDownLatch count;
}
static String thisFailure;
static String failure;
static int nextNameIndex;
- static final long MAX_WAITING_TIME = 10000;
private static MyListener countListener;
private static final List<ObjectName> sources = new Vector();
diff --git a/test/javax/management/standardmbean/DeadlockTest.java b/test/javax/management/standardmbean/DeadlockTest.java
index a7d3b89..4d5f72d 100644
--- a/test/javax/management/standardmbean/DeadlockTest.java
+++ b/test/javax/management/standardmbean/DeadlockTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -24,7 +24,7 @@
/*
* @test
* @bug 6331746
- * @summary Deadlock on synchronization problem
+ * @summary Test a deadlock and will be blocked forever if the deadlock is present.
* @author Shanliang JIANG
* @run main DeadlockTest
*/
@@ -55,43 +55,25 @@
BadBoy bb = new BadBoy(dt);
bb.start();
- final long timeout = 2000;
- long stopTime = System.currentTimeMillis() + timeout;
- long timeToWait = timeout;
synchronized(bb) {
- while(!bb.gotLock || timeToWait > 0) {
- bb.wait(timeToWait);
-
- timeToWait = stopTime - System.currentTimeMillis();
+ while(!bb.gotLock) {
+ bb.wait(); // if blocked here, means failing to get lock, impossible.
}
}
- if (!bb.gotLock) {
- throw new RuntimeException("Failed to get lock, impossible!");
- }
-
System.out.println("main: The BadBay is holding the lock forever.");
System.out.println("main: Create a WorkingBoy to see blocking ...");
WorkingBoy wb = new WorkingBoy(dt);
- stopTime = System.currentTimeMillis() + timeout;
- timeToWait = timeout;
-
synchronized(wb) {
wb.start();
- while(!wb.done || timeToWait > 0) {
- wb.wait(timeToWait);
-
- timeToWait = stopTime - System.currentTimeMillis();
+ while(!wb.done) {
+ wb.wait(); // if blocked here, the deadlock happends
}
}
- if (!wb.done) {
- throw new RuntimeException("It is blocked!");
- }
-
System.out.println("main: OK, bye bye.");
}
diff --git a/test/javax/net/ssl/ciphersuites/DisabledAlgorithms.java b/test/javax/net/ssl/ciphersuites/DisabledAlgorithms.java
new file mode 100644
index 0000000..cd6894d
--- /dev/null
+++ b/test/javax/net/ssl/ciphersuites/DisabledAlgorithms.java
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * @test
+ * @bug 8076221
+ * @summary Check if weak cipher suites are disabled
+ * @run main/othervm DisabledAlgorithms default
+ * @run main/othervm DisabledAlgorithms empty
+ */
+public class DisabledAlgorithms {
+
+ private static final String pathToStores =
+ "../../../../sun/security/ssl/etc";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final String passwd = "passphrase";
+
+ private static final String keyFilename =
+ System.getProperty("test.src", "./") + "/" + pathToStores +
+ "/" + keyStoreFile;
+
+ private static final String trustFilename =
+ System.getProperty("test.src", "./") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ // supported RC4 cipher suites
+ // it does not contain KRB5 cipher suites because they need a KDC
+ private static final String[] rc4_ciphersuites = new String[] {
+ "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+ "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
+ "SSL_RSA_WITH_RC4_128_SHA",
+ "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
+ "TLS_ECDH_RSA_WITH_RC4_128_SHA",
+ "SSL_RSA_WITH_RC4_128_MD5",
+ "TLS_ECDH_anon_WITH_RC4_128_SHA",
+ "SSL_DH_anon_WITH_RC4_128_MD5"
+ };
+
+ public static void main(String[] args) throws Exception {
+ if (args.length < 1) {
+ throw new RuntimeException("No parameters specified");
+ }
+
+ System.setProperty("javax.net.ssl.keyStore", keyFilename);
+ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+ System.setProperty("javax.net.ssl.trustStore", trustFilename);
+ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+ switch (args[0]) {
+ case "default":
+ // use default jdk.tls.disabledAlgorithms
+ System.out.println("jdk.tls.disabledAlgorithms = "
+ + Security.getProperty("jdk.tls.disabledAlgorithms"));
+
+ // check if RC4 cipher suites can't be used by default
+ checkFailure(rc4_ciphersuites);
+ break;
+ case "empty":
+ // reset jdk.tls.disabledAlgorithms
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+ System.out.println("jdk.tls.disabledAlgorithms = "
+ + Security.getProperty("jdk.tls.disabledAlgorithms"));
+
+ // check if RC4 cipher suites can be used
+ // if jdk.tls.disabledAlgorithms is empty
+ checkSuccess(rc4_ciphersuites);
+ break;
+ default:
+ throw new RuntimeException("Wrong parameter: " + args[0]);
+ }
+ }
+
+ /*
+ * Checks if that specified cipher suites cannot be used.
+ */
+ private static void checkFailure(String[] ciphersuites) throws Exception {
+ try (SSLServer server = SSLServer.init(ciphersuites)) {
+ startNewThread(server);
+ while (!server.isRunning()) {
+ sleep();
+ }
+
+ int port = server.getPort();
+ for (String ciphersuite : ciphersuites) {
+ try (SSLClient client = SSLClient.init(port, ciphersuite)) {
+ client.connect();
+ throw new RuntimeException("Expected SSLHandshakeException "
+ + "not thrown");
+ } catch (SSLHandshakeException e) {
+ System.out.println("Expected exception on client side: "
+ + e);
+ }
+ }
+
+ server.stop();
+ while (server.isRunning()) {
+ sleep();
+ }
+
+ if (!server.sslError()) {
+ throw new RuntimeException("Expected SSL exception "
+ + "not thrown on server side");
+ }
+ }
+
+ }
+
+ /*
+ * Checks if specified cipher suites can be used.
+ */
+ private static void checkSuccess(String[] ciphersuites) throws Exception {
+ try (SSLServer server = SSLServer.init(ciphersuites)) {
+ startNewThread(server);
+ while (!server.isRunning()) {
+ sleep();
+ }
+
+ int port = server.getPort();
+ for (String ciphersuite : ciphersuites) {
+ try (SSLClient client = SSLClient.init(port, ciphersuite)) {
+ client.connect();
+ String negotiated = client.getNegotiatedCipherSuite();
+ System.out.println("Negotiated cipher suite: "
+ + negotiated);
+ if (!negotiated.equals(ciphersuite)) {
+ throw new RuntimeException("Unexpected cipher suite: "
+ + negotiated);
+ }
+ }
+ }
+
+ server.stop();
+ while (server.isRunning()) {
+ sleep();
+ }
+
+ if (server.error()) {
+ throw new RuntimeException("Unexpected error on server side");
+ }
+ }
+
+ }
+
+ private static Thread startNewThread(SSLServer server) {
+ Thread serverThread = new Thread(server, "SSL server thread");
+ serverThread.setDaemon(true);
+ serverThread.start();
+ return serverThread;
+ }
+
+ private static void sleep() {
+ try {
+ TimeUnit.MILLISECONDS.sleep(50);
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+ }
+
+ static class SSLServer implements Runnable, AutoCloseable {
+
+ private final SSLServerSocket ssocket;
+ private volatile boolean stopped = false;
+ private volatile boolean running = false;
+ private volatile boolean sslError = false;
+ private volatile boolean otherError = false;
+
+ private SSLServer(SSLServerSocket ssocket) {
+ this.ssocket = ssocket;
+ }
+
+ @Override
+ public void run() {
+ System.out.println("Server: started");
+ running = true;
+ while (!stopped) {
+ try (SSLSocket socket = (SSLSocket) ssocket.accept()) {
+ System.out.println("Server: accepted client connection");
+ InputStream in = socket.getInputStream();
+ OutputStream out = socket.getOutputStream();
+ int b = in.read();
+ if (b < 0) {
+ throw new IOException("Unexpected EOF");
+ }
+ System.out.println("Server: send data: " + b);
+ out.write(b);
+ out.flush();
+ socket.getSession().invalidate();
+ } catch (SSLHandshakeException e) {
+ System.out.println("Server: run: " + e);
+ sslError = true;
+ } catch (IOException e) {
+ if (!stopped) {
+ System.out.println("Server: run: " + e);
+ e.printStackTrace();
+ otherError = true;
+ }
+ }
+ }
+
+ System.out.println("Server: finished");
+ running = false;
+ }
+
+ int getPort() {
+ return ssocket.getLocalPort();
+ }
+
+ String[] getEnabledCiperSuites() {
+ return ssocket.getEnabledCipherSuites();
+ }
+
+ boolean isRunning() {
+ return running;
+ }
+
+ boolean sslError() {
+ return sslError;
+ }
+
+ boolean error() {
+ return sslError || otherError;
+ }
+
+ void stop() {
+ stopped = true;
+ if (!ssocket.isClosed()) {
+ try {
+ ssocket.close();
+ } catch (IOException e) {
+ System.out.println("Server: close: " + e);
+ }
+ }
+ }
+
+ @Override
+ public void close() {
+ stop();
+ }
+
+ static SSLServer init(String[] ciphersuites)
+ throws IOException {
+ SSLServerSocketFactory ssf = (SSLServerSocketFactory)
+ SSLServerSocketFactory.getDefault();
+ SSLServerSocket ssocket = (SSLServerSocket)
+ ssf.createServerSocket(0);
+
+ if (ciphersuites != null) {
+ System.out.println("Server: enable cipher suites: "
+ + java.util.Arrays.toString(ciphersuites));
+ ssocket.setEnabledCipherSuites(ciphersuites);
+ }
+
+ return new SSLServer(ssocket);
+ }
+ }
+
+ static class SSLClient implements AutoCloseable {
+
+ private final SSLSocket socket;
+
+ private SSLClient(SSLSocket socket) {
+ this.socket = socket;
+ }
+
+ void connect() throws IOException {
+ System.out.println("Client: connect to server");
+ try (
+ BufferedInputStream bis = new BufferedInputStream(
+ socket.getInputStream());
+ BufferedOutputStream bos = new BufferedOutputStream(
+ socket.getOutputStream())) {
+ bos.write('x');
+ bos.flush();
+
+ int read = bis.read();
+ if (read < 0) {
+ throw new IOException("Client: couldn't read a response");
+ }
+ socket.getSession().invalidate();
+ }
+ }
+
+ String[] getEnabledCiperSuites() {
+ return socket.getEnabledCipherSuites();
+ }
+
+ String getNegotiatedCipherSuite() {
+ return socket.getSession().getCipherSuite();
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (!socket.isClosed()) {
+ try {
+ socket.close();
+ } catch (IOException e) {
+ System.out.println("Client: close: " + e);
+ }
+ }
+ }
+
+ static SSLClient init(int port)
+ throws NoSuchAlgorithmException, IOException {
+ return init(port, null);
+ }
+
+ static SSLClient init(int port, String ciphersuite)
+ throws NoSuchAlgorithmException, IOException {
+ SSLContext context = SSLContext.getDefault();
+ SSLSocketFactory ssf = (SSLSocketFactory)
+ context.getSocketFactory();
+ SSLSocket socket = (SSLSocket) ssf.createSocket("localhost", port);
+
+ if (ciphersuite != null) {
+ System.out.println("Client: enable cipher suite: "
+ + ciphersuite);
+ socket.setEnabledCipherSuites(new String[] { ciphersuite });
+ }
+
+ return new SSLClient(socket);
+ }
+
+ }
+
+
+}
diff --git a/test/javax/print/PrintSEUmlauts/PrintSEUmlauts.java b/test/javax/print/PrintSEUmlauts/PrintSEUmlauts.java
new file mode 100644
index 0000000..5285716
--- /dev/null
+++ b/test/javax/print/PrintSEUmlauts/PrintSEUmlauts.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 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.
+ */
+import java.awt.Graphics;
+import java.awt.GraphicsEnvironment;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import javax.print.DocFlavor;
+import javax.print.DocPrintJob;
+import javax.print.SimpleDoc;
+import javax.print.StreamPrintService;
+import javax.print.StreamPrintServiceFactory;
+import javax.print.attribute.HashDocAttributeSet;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.event.PrintJobAdapter;
+import javax.print.event.PrintJobEvent;
+
+/*
+ * @test
+ * @bug 8067364
+ * @summary Printing to Postscript doesn't support dieresis
+ * @build PrintSEUmlauts
+ * @run main/othervm PrintSEUmlauts
+ */
+public class PrintSEUmlauts implements Printable {
+
+ public static void main(String[] args) throws Exception {
+
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+
+ DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
+ String mime = DocFlavor.BYTE_ARRAY.POSTSCRIPT.getMimeType();
+
+ StreamPrintServiceFactory[] factories =
+ StreamPrintServiceFactory.
+ lookupStreamPrintServiceFactories(flavor, mime);
+ if (factories.length == 0) {
+ System.out.println("No print service found.");
+ return;
+ }
+
+ FileOutputStream output = new FileOutputStream("out.ps");
+ StreamPrintService service = factories[0].getPrintService(output);
+
+ SimpleDoc doc =
+ new SimpleDoc(new PrintSEUmlauts(),
+ DocFlavor.SERVICE_FORMATTED.PRINTABLE,
+ new HashDocAttributeSet());
+ DocPrintJob job = service.createPrintJob();
+ job.addPrintJobListener(new PrintJobAdapter() {
+ @Override
+ public void printJobCompleted(PrintJobEvent pje) {
+ testPrintAndExit();
+ }
+ });
+
+ job.print(doc, new HashPrintRequestAttributeSet());
+ }
+
+ private static final boolean DEBUG = false;
+ private static void testPrintAndExit() {
+ String expected = "<e4> 7.44 100.0 100.0 S";
+ String content = "";
+
+ File file = new File("out.ps");
+ if (!DEBUG) {
+ file.deleteOnExit();
+ }
+
+ try (FileInputStream stream = new FileInputStream(file)) {
+ byte[] data = new byte[(int) file.length()];
+ stream.read(data);
+ content = new String(data, StandardCharsets.ISO_8859_1);
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+
+ if (!content.contains(expected)) {
+ System.err.println("FAIL");
+ if (DEBUG) {
+ System.err.println("printing content");
+ System.err.println(content);
+ }
+ throw new RuntimeException("Expected <e4> to represent 'ä' but not found!");
+ }
+ System.err.println("SUCCESS");
+ }
+
+ public int print(Graphics g, PageFormat pf, int pg) {
+ if (pg > 0) return NO_SUCH_PAGE;
+ g.drawString("ä", 100, 100);
+ return PAGE_EXISTS;
+ }
+}
diff --git a/test/javax/sound/midi/Devices/InitializationHang.java b/test/javax/sound/midi/Devices/InitializationHang.java
new file mode 100644
index 0000000..c8e38d2
--- /dev/null
+++ b/test/javax/sound/midi/Devices/InitializationHang.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.awt.Toolkit;
+
+import javax.sound.midi.MidiSystem;
+
+/**
+ * @test
+ * @bug 8068412
+ * @author Sergey Bylokhov
+ */
+public final class InitializationHang {
+
+ public static void main(final String[] argv) throws Exception {
+ MidiSystem.getReceiver();
+ Toolkit.getDefaultToolkit();
+ }
+}
+
diff --git a/test/javax/swing/AbstractButton/AnimatedIcon/AnimatedIcon.java b/test/javax/swing/AbstractButton/AnimatedIcon/AnimatedIcon.java
new file mode 100644
index 0000000..d8843ab
--- /dev/null
+++ b/test/javax/swing/AbstractButton/AnimatedIcon/AnimatedIcon.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
+
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.SwingUtilities;
+
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
+
+/**
+ * @test
+ * @bug 6573305
+ * @summary Animated icon should animate when the JButton is pressed.
+ * @author Sergey Bylokhov
+ */
+public final class AnimatedIcon {
+
+ public static void main(final String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ final BufferedImage bi = new BufferedImage(1, 1, TYPE_INT_RGB);
+ final ImageIcon icon = new ImageIcon(bi);
+ final JButton button = new JButton(icon);
+ // Default icon is set => imageUpdate should return true for it
+ isAnimated(bi, button);
+ button.getModel().setPressed(true);
+ button.getModel().setArmed(true);
+ isAnimated(bi, button);
+ button.getModel().setPressed(false);
+ button.getModel().setArmed(false);
+ button.getModel().setSelected(true);
+ isAnimated(bi, button);
+ button.getModel().setSelected(false);
+ button.getModel().setRollover(true);
+ button.setRolloverEnabled(true);
+ isAnimated(bi, button);
+ button.getModel().setSelected(true);
+ isAnimated(bi, button);
+ // Default icon is not set => imageUpdate should return true for
+ // other icons if any
+ button.setIcon(null);
+ button.setPressedIcon(icon);
+ button.getModel().setPressed(true);
+ button.getModel().setArmed(true);
+ isAnimated(bi, button);
+ });
+ }
+
+ private static void isAnimated(BufferedImage bi, JButton button) {
+ if (!button.imageUpdate(bi, ImageObserver.SOMEBITS, 0, 0, 1, 1)) {
+ throw new RuntimeException();
+ }
+ }
+}
diff --git a/test/javax/swing/JMenu/8071705/bug8071705.java b/test/javax/swing/JMenu/8071705/bug8071705.java
new file mode 100644
index 0000000..a814772
--- /dev/null
+++ b/test/javax/swing/JMenu/8071705/bug8071705.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8071705
+ * @summary Java application menu misbehaves when running multiple screen stacked vertically
+ * @build bug8071705
+ * @run main/othervm bug8071705
+ */
+
+import java.awt.Dimension;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.KeyEvent;
+import java.util.concurrent.CountDownLatch;
+
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+public class bug8071705 {
+
+ public static void main(String[] args) throws Exception {
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ final boolean [] result = new boolean[1];
+
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ JFrame frame = createGUI();
+ GraphicsDevice[] devices = checkScreens();
+
+ // check if we have more than one and if they are stacked
+ // vertically
+ GraphicsDevice device = checkConfigs(devices);
+ if (device == null) {
+ // just pass the test
+ frame.dispose();
+ result[0] = true;
+ latch.countDown();
+ } else {
+ FrameListener listener =
+ new FrameListener(device, latch, result);
+ frame.addComponentListener(listener);
+ frame.setVisible(true);
+ }
+ }
+ });
+
+ latch.await();
+
+ if (result[0] == false) {
+ throw new RuntimeException("popup menu rendered in wrong position");
+ }
+
+ System.out.println("OK");
+ }
+
+ private static GraphicsDevice[] checkScreens() {
+ GraphicsEnvironment ge =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+ return ge.getScreenDevices();
+ }
+
+ private static JFrame createGUI() {
+ JMenuBar menuBar = new JMenuBar();
+ JMenu menu = new JMenu("Some menu");
+ menuBar.add(menu);
+
+ for (int i = 0; i < 10; i++) {
+ menu.add(new JMenuItem("Some menu #" + i));
+ }
+
+ JFrame frame = new JFrame();
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setMinimumSize(new Dimension(200, 200));
+ frame.setJMenuBar(menuBar);
+ return frame;
+ }
+
+ private static GraphicsDevice checkConfigs(GraphicsDevice[] devices) {
+
+ GraphicsDevice correctDevice = null;
+ if (devices.length < 2) {
+ return correctDevice;
+ }
+
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+ Rectangle screenBounds = new Rectangle(toolkit.getScreenSize());
+ int halfScreen = screenBounds.height/2;
+
+ for(int i = 0; i < devices.length; i++) {
+ if(devices[i].getType() == GraphicsDevice.TYPE_RASTER_SCREEN) {
+ GraphicsConfiguration conf =
+ devices[i].getDefaultConfiguration();
+ Rectangle bounds = conf.getBounds();
+ if (bounds.y >= halfScreen) {
+ // found
+ correctDevice = devices[i];
+ break;
+ }
+ }
+ }
+ return correctDevice;
+ }
+
+ private static class FrameListener extends ComponentAdapter {
+
+ private GraphicsDevice device;
+ private CountDownLatch latch;
+ private boolean [] result;
+ public FrameListener(GraphicsDevice device,
+ CountDownLatch latch,
+ boolean [] result)
+ {
+ this.device = device;
+ this.latch = latch;
+ this.result = result;
+ }
+
+ @Override
+ public void componentShown(ComponentEvent e) {
+ JFrame frame = (JFrame) e.getComponent();
+
+ runActualTest(device, latch, frame, result);
+
+ frame.setVisible(false);
+ frame.dispose();
+ latch.countDown();
+ }
+ }
+
+ private static Rectangle setLocation(JFrame frame, GraphicsDevice device) {
+ GraphicsConfiguration conf = device.getDefaultConfiguration();
+ Rectangle bounds = conf.getBounds();
+
+ // put just below half screen
+ int x = bounds.x + bounds.width/2;
+ int y = bounds.y + bounds.height/2;
+ frame.setLocation(x, y);
+
+ return bounds;
+ }
+
+ private static void runActualTest(GraphicsDevice device,
+ CountDownLatch latch,
+ JFrame frame,
+ boolean [] result)
+ {
+ Rectangle screenBounds = setLocation(frame, device);
+ JMenu menu = frame.getJMenuBar().getMenu(0);
+ menu.doClick();
+
+ Point location = menu.getLocationOnScreen();
+ JPopupMenu pm = menu.getPopupMenu();
+ Dimension pmSize = pm.getSize();
+
+ int yOffset = UIManager.getInt("Menu.submenuPopupOffsetY");
+ int height = location.y + yOffset + pmSize.height + menu.getHeight();
+ int available = screenBounds.y + screenBounds.height - height;
+ if (available > 0) {
+ Point origin = pm.getLocationOnScreen();
+ if (origin.y < location.y) {
+ // growing upward, wrong!
+ result[0] = false;
+ } else {
+ // growing downward, ok!
+ result[0] = true;
+ }
+ } else {
+ // there is no space, growing upward would be ok, so we pass
+ result[0] = true;
+ }
+ }
+}
diff --git a/test/javax/swing/JMenu/8072900/WrongSelectionOnMouseOver.java b/test/javax/swing/JMenu/8072900/WrongSelectionOnMouseOver.java
new file mode 100644
index 0000000..cf02f6f
--- /dev/null
+++ b/test/javax/swing/JMenu/8072900/WrongSelectionOnMouseOver.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+@test
+@bug 8072900
+@summary Mouse events are captured by the wrong menu in OS X
+@author Anton Nashatyrev
+@run main WrongSelectionOnMouseOver
+*/
+
+import javax.swing.*;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static javax.swing.UIManager.getInstalledLookAndFeels;
+
+public class WrongSelectionOnMouseOver implements Runnable {
+
+ CountDownLatch firstMenuSelected = new CountDownLatch(1);
+ CountDownLatch secondMenuMouseEntered = new CountDownLatch(1);
+ CountDownLatch secondMenuSelected = new CountDownLatch(1);
+
+ JMenu m1, m2;
+
+ private UIManager.LookAndFeelInfo laf;
+ JFrame frame1;
+ JFrame frame2;
+
+ public WrongSelectionOnMouseOver(UIManager.LookAndFeelInfo laf) throws Exception {
+ this.laf = laf;
+ }
+
+ private void createUI() throws Exception {
+ System.out.println("Testing UI: " + laf);
+ UIManager.setLookAndFeel(laf.getClassName());
+
+ {
+ frame1 = new JFrame("Frame1");
+ JMenuBar mb = new JMenuBar();
+ m1 = new JMenu("File");
+ JMenuItem i1 = new JMenuItem("Save");
+ JMenuItem i2 = new JMenuItem("Load");
+
+ m1.addMenuListener(new MenuListener() {
+ @Override
+ public void menuSelected(MenuEvent e) {
+ firstMenuSelected.countDown();
+ System.out.println("Menu1: menuSelected");
+ }
+
+ @Override
+ public void menuDeselected(MenuEvent e) {
+ System.out.println("Menu1: menuDeselected");
+ }
+
+ @Override
+ public void menuCanceled(MenuEvent e) {
+ System.out.println("Menu1: menuCanceled");
+ }
+ });
+
+ frame1.setJMenuBar(mb);
+ mb.add(m1);
+ m1.add(i1);
+ m1.add(i2);
+
+ frame1.setLayout(new FlowLayout());
+ frame1.setBounds(200, 200, 200, 200);
+
+ frame1.setVisible(true);
+ }
+
+ {
+ frame2 = new JFrame("Frame2");
+ JMenuBar mb = new JMenuBar();
+ m2 = new JMenu("File");
+ JMenuItem i1 = new JMenuItem("Save");
+ JMenuItem i2 = new JMenuItem("Load");
+
+ m2.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseEntered(MouseEvent e) {
+ secondMenuMouseEntered.countDown();
+ System.out.println("WrongSelectionOnMouseOver.mouseEntered");
+ }
+ });
+
+ m2.addMenuListener(new MenuListener() {
+ @Override
+ public void menuSelected(MenuEvent e) {
+ secondMenuSelected.countDown();
+ System.out.println("Menu2: menuSelected");
+ }
+
+ @Override
+ public void menuDeselected(MenuEvent e) {
+ System.out.println("Menu2: menuDeselected");
+ }
+
+ @Override
+ public void menuCanceled(MenuEvent e) {
+ System.out.println("Menu2: menuCanceled");
+ }
+ });
+
+ frame2.setJMenuBar(mb);
+ mb.add(m2);
+ m2.add(i1);
+ m2.add(i2);
+
+ frame2.setLayout(new FlowLayout());
+ frame2.setBounds(400, 200, 200, 200);
+
+ frame2.setVisible(true);
+ }
+ }
+
+ public void disposeUI() {
+ frame1.dispose();
+ frame2.dispose();
+ }
+
+ @Override
+ public void run() {
+ try {
+ if (frame1 == null) {
+ createUI();
+ } else {
+ disposeUI();
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void test() throws Exception {
+ Robot robot = new Robot();
+ robot.setAutoDelay(100);
+
+ robot.waitForIdle();
+
+ robot.mouseMove((int) m1.getLocationOnScreen().getX() + 5,
+ (int) m1.getLocationOnScreen().getY() + 5);
+ robot.mousePress(MouseEvent.BUTTON1_MASK);
+ robot.mouseRelease(MouseEvent.BUTTON1_MASK);
+
+ if (!firstMenuSelected.await(5, TimeUnit.SECONDS)) {
+ throw new RuntimeException("Menu has not been selected.");
+ };
+
+ robot.mouseMove((int) m2.getLocationOnScreen().getX() + 5,
+ (int) m2.getLocationOnScreen().getY() + 5);
+
+ if (!secondMenuMouseEntered.await(5, TimeUnit.SECONDS)) {
+ throw new RuntimeException("MouseEntered event missed for the second menu");
+ };
+
+ if (secondMenuSelected.await(1, TimeUnit.SECONDS)) {
+ throw new RuntimeException("The second menu has been selected");
+ };
+ }
+
+ public static void main(final String[] args) throws Exception {
+ for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) {
+ WrongSelectionOnMouseOver test = new WrongSelectionOnMouseOver(laf);
+ SwingUtilities.invokeAndWait(test);
+ test.test();
+ SwingUtilities.invokeAndWait(test);
+ }
+ System.out.println("Test passed");
+ }
+}
\ No newline at end of file
diff --git a/test/javax/swing/JMenuBar/MisplacedBorder/MisplacedBorder.java b/test/javax/swing/JMenuBar/MisplacedBorder/MisplacedBorder.java
new file mode 100644
index 0000000..43a7dc3
--- /dev/null
+++ b/test/javax/swing/JMenuBar/MisplacedBorder/MisplacedBorder.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
+import static javax.swing.UIManager.getInstalledLookAndFeels;
+
+/**
+ * @test
+ * @bug 8073795
+ * @summary JMenuBar has incorrect border when the window is on retina display.
+ * @author Sergey Bylokhov
+ * @run main/othervm MisplacedBorder
+ * @run main/othervm -Dswing.metalTheme=steel MisplacedBorder
+ */
+public final class MisplacedBorder implements Runnable {
+
+ public static final int W = 400;
+ public static final int H = 400;
+
+ public static void main(final String[] args) throws Exception {
+ for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) {
+ SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf));
+ SwingUtilities.invokeAndWait(new MisplacedBorder());
+ }
+ System.out.println("Test passed");
+ }
+
+ @Override
+ public void run() {
+ final JMenuBar menubar = new JMenuBar();
+ menubar.add(new JMenu(""));
+ menubar.add(new JMenu(""));
+ final JFrame frame = new JFrame();
+ frame.setUndecorated(true);
+ frame.setJMenuBar(menubar);
+ frame.setSize(W / 3, H / 3);
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+
+ // draw menu bar using standard order.
+ final BufferedImage bi1 = step1(menubar);
+
+ // draw menu border on top of the menu bar, nothing should be changed.
+ final BufferedImage bi2 = step2(menubar);
+ frame.dispose();
+
+ for (int x = 0; x < W; ++x) {
+ for (int y = 0; y < H; ++y) {
+ if (bi1.getRGB(x, y) != bi2.getRGB(x, y)) {
+ try {
+ ImageIO.write(bi1, "png", new File("image1.png"));
+ ImageIO.write(bi2, "png", new File("image2.png"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ throw new RuntimeException("Failed: wrong color");
+ }
+ }
+ }
+ }
+
+ /**
+ * Draws standard JMenuBar.
+ */
+ private BufferedImage step1(final JMenuBar menubar) {
+ final BufferedImage bi1 = new BufferedImage(W, H, TYPE_INT_ARGB_PRE);
+ final Graphics2D g2d = bi1.createGraphics();
+ g2d.scale(2, 2);
+ g2d.setColor(Color.RED);
+ g2d.fillRect(0, 0, W, H);
+ menubar.paintAll(g2d);
+ g2d.dispose();
+ return bi1;
+ }
+
+ /**
+ * Draws standard JMenuBar and border on top of it.
+ */
+ private BufferedImage step2(final JMenuBar menubar) {
+ final BufferedImage bi2 = new BufferedImage(W, H, TYPE_INT_ARGB_PRE);
+ final Graphics2D g2d2 = bi2.createGraphics();
+ g2d2.scale(2, 2);
+ g2d2.setColor(Color.RED);
+ g2d2.fillRect(0, 0, W, H);
+ menubar.paintAll(g2d2);
+ menubar.getBorder().paintBorder(menubar, g2d2, menubar.getX(), menubar
+ .getX(), menubar.getWidth(), menubar.getHeight());
+ g2d2.dispose();
+ return bi2;
+ }
+
+ private static void setLookAndFeel(final UIManager.LookAndFeelInfo laf) {
+ try {
+ UIManager.setLookAndFeel(laf.getClassName());
+ System.out.println("LookAndFeel: " + laf.getClassName());
+ } catch (ClassNotFoundException | InstantiationException |
+ UnsupportedLookAndFeelException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/javax/swing/JRadioButton/8075609/bug8075609.java b/test/javax/swing/JRadioButton/8075609/bug8075609.java
new file mode 100644
index 0000000..9bffc80
--- /dev/null
+++ b/test/javax/swing/JRadioButton/8075609/bug8075609.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+ /*
+ * @test
+ * @library ../../regtesthelpers
+ * @build Util
+ * @bug 8075609
+ * @summary IllegalArgumentException when transferring focus from JRadioButton using tab
+ * @author Vivi An
+ * @run main bug8075609
+ */
+
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import sun.awt.SunToolkit;
+
+public class bug8075609 {
+ private static Robot robot;
+ private static SunToolkit toolkit;
+ private static JTextField textField;
+
+ public static void main(String args[]) throws Throwable {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+
+ robot = new Robot();
+ Thread.sleep(100);
+
+ robot.setAutoDelay(100);
+ toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+ // Radio button group tab key test
+ runTest1();
+ }
+
+ private static void createAndShowGUI() {
+ JFrame mainFrame = new JFrame("Bug 8075609 - 1 test");
+
+ JPanel rootPanel = new JPanel();
+ rootPanel.setLayout(new BorderLayout());
+
+ JPanel formPanel = new JPanel();
+ formPanel.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
+ formPanel.setFocusCycleRoot(true);
+
+ JRadioButton option1 = new JRadioButton("Option 1", true);
+ JRadioButton option2 = new JRadioButton("Option 2");
+
+ ButtonGroup radioButtonGroup = new ButtonGroup();
+ radioButtonGroup.add(option1);
+ radioButtonGroup.add(option2);
+
+ formPanel.add(option1);
+ formPanel.add(option2);
+ textField = new JTextField("Another focusable component");
+ formPanel.add(textField);
+
+ rootPanel.add(formPanel, BorderLayout.CENTER);
+
+ JButton okButton = new JButton("OK");
+ rootPanel.add(okButton, BorderLayout.SOUTH);
+
+ mainFrame.add(rootPanel);
+ mainFrame.pack();
+ mainFrame.setVisible(true);
+ mainFrame.toFront();
+ }
+
+ // Radio button Group as a single component when traversing through tab key
+ private static void runTest1() throws Exception{
+ hitKey(robot, KeyEvent.VK_TAB);
+
+ robot.setAutoDelay(1000 );
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if (textField.hasFocus()) {
+ System.out.println("Radio Button Group Go To Next Component through Tab Key failed");
+ throw new RuntimeException("Focus is not on textField as Expected");
+ }
+ }
+ });
+ }
+
+ private static void hitKey(Robot robot, int keycode) {
+ robot.keyPress(keycode);
+ robot.keyRelease(keycode);
+ toolkit.realSync();
+ }
+}
diff --git a/test/javax/swing/JScrollPane/8033000/bug8033000.java b/test/javax/swing/JScrollPane/8033000/bug8033000.java
new file mode 100644
index 0000000..190390d
--- /dev/null
+++ b/test/javax/swing/JScrollPane/8033000/bug8033000.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+import java.awt.BorderLayout;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.KeyEvent;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import sun.awt.OSInfo;
+
+/**
+ * @test
+ * @bug 8033000
+ * @author Alexander Scherbatiy
+ * @summary No Horizontal Mouse Wheel Support In BasicScrollPaneUI
+ * @run main bug8033000
+ */
+public class bug8033000 {
+
+ private static JScrollPane scrollPane;
+ private static JTextArea textArea;
+ private static Point point;
+ private static final int delta;
+
+ static {
+ delta = OSInfo.getOSType().equals(OSInfo.OSType.MACOSX) ? -30 : 30;
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ Robot robot = new Robot();
+ robot.setAutoDelay(50);
+
+ SwingUtilities.invokeAndWait(bug8033000::createAndShowGUI);
+ robot.waitForIdle();
+
+ SwingUtilities.invokeAndWait(() -> {
+ Point locationOnScreen = scrollPane.getLocationOnScreen();
+ point = new Point(
+ locationOnScreen.x + scrollPane.getWidth() / 2,
+ locationOnScreen.y + scrollPane.getHeight() / 2);
+ });
+
+ robot.mouseMove(point.x, point.y);
+ robot.waitForIdle();
+
+ // vertical scroll bar is enabled
+ initScrollPane(true, false);
+ robot.waitForIdle();
+ robot.mouseWheel(delta);
+ robot.waitForIdle();
+ checkScrollPane(true);
+
+ // vertical scroll bar is enabled + shift
+ initScrollPane(true, false);
+ robot.waitForIdle();
+ robot.keyPress(KeyEvent.VK_SHIFT);
+ robot.mouseWheel(delta);
+ robot.keyRelease(KeyEvent.VK_SHIFT);
+ robot.waitForIdle();
+ checkScrollPane(true);
+
+ // horizontal scroll bar is enabled
+ initScrollPane(false, true);
+ robot.waitForIdle();
+ robot.mouseWheel(delta);
+ robot.waitForIdle();
+ checkScrollPane(false);
+
+ // horizontal scroll bar is enabled + shift
+ initScrollPane(false, true);
+ robot.waitForIdle();
+ robot.keyPress(KeyEvent.VK_SHIFT);
+ robot.mouseWheel(delta);
+ robot.keyRelease(KeyEvent.VK_SHIFT);
+ robot.waitForIdle();
+ checkScrollPane(false);
+
+ // both scroll bars are enabled
+ initScrollPane(true, true);
+ robot.waitForIdle();
+ robot.mouseWheel(delta);
+ robot.waitForIdle();
+ checkScrollPane(true);
+
+ // both scroll bars are enabled + shift
+ initScrollPane(true, true);
+ robot.waitForIdle();
+ robot.keyPress(KeyEvent.VK_SHIFT);
+ robot.mouseWheel(delta);
+ robot.keyRelease(KeyEvent.VK_SHIFT);
+ robot.waitForIdle();
+ checkScrollPane(false);
+ }
+
+ static void initScrollPane(boolean vVisible, boolean hVisible) throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ scrollPane.getVerticalScrollBar().setValue(0);
+ scrollPane.getHorizontalScrollBar().setValue(0);
+
+ textArea.setRows(vVisible ? 100 : 1);
+ textArea.setColumns(hVisible ? 100 : 1);
+ scrollPane.getVerticalScrollBar().setVisible(vVisible);
+ scrollPane.getHorizontalScrollBar().setVisible(hVisible);
+ });
+ }
+
+ static void checkScrollPane(boolean verticalScrolled) throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+
+ if (verticalScrolled) {
+ if (scrollPane.getVerticalScrollBar().getValue() == 0
+ || scrollPane.getHorizontalScrollBar().getValue() != 0) {
+ throw new RuntimeException("Wrong vertical scrolling!");
+ }
+ } else {
+ if (scrollPane.getVerticalScrollBar().getValue() != 0
+ || scrollPane.getHorizontalScrollBar().getValue() == 0) {
+ throw new RuntimeException("Wrong horizontal scrolling!");
+ }
+ }
+ });
+ }
+
+ static void createAndShowGUI() {
+ JFrame frame = new JFrame();
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setSize(300, 300);
+ textArea = new JTextArea("Hello World!");
+ scrollPane = new JScrollPane(textArea);
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.add(scrollPane, BorderLayout.CENTER);
+ frame.getContentPane().add(panel);
+ frame.setVisible(true);
+ }
+}
diff --git a/test/javax/swing/JTree/8072676/TreeClipTest.java b/test/javax/swing/JTree/8072676/TreeClipTest.java
new file mode 100644
index 0000000..9ec0281
--- /dev/null
+++ b/test/javax/swing/JTree/8072676/TreeClipTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+
+/*
+ * @test
+ * @bug 8072676
+ * @summary Checks if the tree painter doesn't expand existing clip
+ * @author Anton Nashatyrev
+ */
+public class TreeClipTest {
+
+ static boolean passed = true;
+
+ static boolean checkImage(BufferedImage img, int clipY) {
+ for (int y = clipY; y < img.getHeight(); y++) {
+ for (int x = 0; x < img.getWidth(); x++) {
+ if ((img.getRGB(x,y) & 0xFFFFFF) != 0xFFFFFF) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ DefaultMutableTreeNode root = new DefaultMutableTreeNode("JTree");
+ DefaultMutableTreeNode parent;
+
+ parent = new DefaultMutableTreeNode("colors");
+ root.add(parent);
+ parent.add(new DefaultMutableTreeNode("blue"));
+ DefaultTreeModel model = new DefaultTreeModel(root);
+ JTree tree = new JTree(model);
+
+ BufferedImage img = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB);
+ for (int clipY = 1; clipY < 50; clipY++) {
+ Graphics2D ig = img.createGraphics();
+ ig.setColor(Color.WHITE);
+ ig.fillRect(0,0,1000, 1000);
+ tree.setSize(200,200);
+ ig.setClip(0,0,1000,clipY);
+ tree.paint(ig);
+ ig.dispose();
+
+ if (!checkImage(img, clipY)) {
+ System.err.println("Failed with clipY=" + clipY);
+ passed = false;
+ try {
+ ImageIO.write(img, "PNG", new File("failedResult.png"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return;
+ }
+ }
+ }
+ });
+
+ if (!passed) {
+ throw new RuntimeException("Test failed.");
+ } else {
+ System.out.println("Passed.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java b/test/javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java
new file mode 100644
index 0000000..59806a3
--- /dev/null
+++ b/test/javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Robot;
+import java.awt.image.BufferedImage;
+import java.io.File;
+
+import javax.imageio.ImageIO;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.SwingUtilities;
+
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+
+/**
+ * @test
+ * @bug 8015085
+ * @summary Shortening via " ... " is broken for Strings containing a combining
+ * diaeresis.
+ * @author Sergey Bylokhov
+ */
+public class TestBadBreak {
+
+ static JFrame frame;
+ static Robot robot;
+ static final String withCombiningDiaeresis = "123p://.aaaaaaaaaaaaaaaaaaaaaa.123/a\u0308" ;
+ static final String withoutCombiningDiaeresis = "123p://.aaaaaaaaaaaaaaaaaaaaaa.123/\u00E4" ;
+
+ public static void main(final String[] args) throws Exception {
+ robot = new Robot();
+ final BufferedImage bi1 = new BufferedImage(200, 90, TYPE_INT_ARGB);
+ final BufferedImage bi2 = new BufferedImage(200, 90, TYPE_INT_ARGB);
+ test(withCombiningDiaeresis, bi1);
+ test(withoutCombiningDiaeresis, bi2);
+ for (int x = 0; x < bi1.getWidth(); ++x) {
+ for (int y = 0; y < bi1.getHeight(); ++y) {
+ if (bi1.getRGB(x, y) != bi2.getRGB(x, y)) {
+ ImageIO.write(bi1, "png", new File("image1.png"));
+ ImageIO.write(bi2, "png", new File("image2.png"));
+ throw new RuntimeException("Wrong color");
+ }
+ }
+ }
+ }
+
+ private static void test(final String text, final BufferedImage i1)
+ throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ frame = new JFrame();
+ final JLabel label = new JLabel(text) {
+ @Override
+ protected void paintComponent(Graphics g) {
+ Graphics2D g2d = i1.createGraphics();
+ super.paintComponent(g2d);
+ g2d.dispose();
+ }
+ };
+ frame.getContentPane().add(label);
+ frame.setBounds(200, 200, 200, 90);
+ }
+ });
+ robot.waitForIdle();
+ SwingUtilities.invokeAndWait(() -> frame.setVisible(true));
+ robot.waitForIdle();
+ SwingUtilities.invokeAndWait(frame::dispose);
+ robot.waitForIdle();
+ }
+}
diff --git a/test/javax/swing/UIDefaults/7180976/Pending.java b/test/javax/swing/UIDefaults/7180976/Pending.java
new file mode 100644
index 0000000..23ece57
--- /dev/null
+++ b/test/javax/swing/UIDefaults/7180976/Pending.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+/**
+ * @test
+ * @bug 7180976
+ * @author Sergey Bylokhov
+ */
+public final class Pending implements Runnable {
+
+ private static volatile boolean passed;
+
+ public static void main(final String[] args) throws Exception {
+ SwingUtilities.invokeLater(new Pending());
+ Thread.sleep(10000);
+ if (!passed) {
+ throw new RuntimeException("Test failed");
+ }
+ }
+
+ @Override
+ public void run() {
+ UIManager.put("foobar", "Pending");
+ UIManager.get("foobar");
+ passed = true;
+ }
+}
\ No newline at end of file
diff --git a/test/javax/swing/plaf/aqua/CustomComboBoxFocusTest.java b/test/javax/swing/plaf/aqua/CustomComboBoxFocusTest.java
new file mode 100644
index 0000000..76e8ab6
--- /dev/null
+++ b/test/javax/swing/plaf/aqua/CustomComboBoxFocusTest.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/* @test
+ @bug 8073001
+ @summary Test verifies that combo box with custom editor renders
+ focus ring around arrow button correctly.
+ @run main CustomComboBoxFocusTest
+*/
+
+import java.awt.AWTException;
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.CountDownLatch;
+import javax.imageio.ImageIO;
+import javax.swing.ComboBoxEditor;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+public class CustomComboBoxFocusTest {
+
+ private static CustomComboBoxFocusTest test = null;
+
+ public static void main(String[] args) {
+
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ test = new CustomComboBoxFocusTest();
+ }
+ });
+ } catch (InterruptedException | InvocationTargetException e ) {
+ throw new RuntimeException("Test failed.", e);
+ }
+
+ SwingUtilities.invokeLater(test.init);
+
+ try {
+ System.out.println("Wait for screenshots...");
+ test.testDone.await();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Test failed.", e);
+ }
+ System.out.println("Compare screenshots...");
+ if (!test.match()) {
+ throw new RuntimeException("Test failed.");
+ }
+ System.out.println("Test passed.");
+ }
+
+ private final JComboBox<String> ref = new JComboBox<String>() {
+ public String toString() {
+ return "reference";
+ }
+ };
+
+ private final JComboBox<String> custom = new JComboBox<String>() {
+ public String toString() {
+ return "custom";
+ }
+ };
+
+ private final JFrame frame;
+
+ private CountDownLatch testDone = new CountDownLatch(1);
+
+ private Robot robot;
+
+ public CustomComboBoxFocusTest() {
+ frame = new JFrame(System.getProperty("java.version"));
+
+ try {
+ robot = new Robot(frame.getGraphicsConfiguration().getDevice());
+
+ } catch (AWTException e) {
+ throw new RuntimeException("Test failed.", e);
+ }
+ }
+
+ private boolean match() {
+ final BufferedImage a = captureRef.img;
+ final BufferedImage b = captureCustom.img;
+
+ final int w = Math.min(a.getWidth(), b.getWidth());
+ final int h = Math.min(a.getHeight(), b.getHeight());
+
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < w; x++) {
+ if (a.getRGB(x, y) != b.getRGB(x, y)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private JComboBox<String> getReference() {
+ return ref;
+ }
+
+ private JComboBox<String> getCustom() {
+ return custom;
+ }
+
+ private JFrame getFrame() {
+ return frame;
+ }
+
+ private static abstract class Step implements Runnable {
+ final public void run() {
+ doStep();
+
+ final Step next = nextStep();
+
+ if (next != null) {
+ SwingUtilities.invokeLater(next);
+ }
+ }
+
+ public abstract void doStep();
+
+ public abstract Step nextStep();
+ }
+
+ private final Step init = new Step() {
+ public void doStep() {
+ final JFrame f = getFrame();
+
+ final JPanel p = new JPanel(new GridLayout(4, 1, 20, 20));
+
+ JComboBox<String> r = getReference();
+ r.setEditable(true);
+ r.addItem("One");
+
+ JComboBox<String> c = getCustom();
+ c.setEditable(true);
+ c.addItem("One");
+ final ComboBoxEditor e = new ComboBoxEditor() {
+ private JTextField text = new JTextField();
+
+ @Override
+ public Component getEditorComponent() {
+ return this.text;
+ }
+
+ @Override
+ public void setItem(Object o) {
+ text.setText(o == null ? "" : o.toString());
+ }
+
+ @Override
+ public Object getItem() {
+ return text.getText();
+ }
+
+ @Override
+ public void selectAll() {
+ text.selectAll();
+ }
+
+ @Override
+ public void addActionListener(ActionListener actionListener) {
+ text.addActionListener(actionListener);
+ }
+
+ @Override
+ public void removeActionListener(ActionListener actionListener) {
+ text.removeActionListener(actionListener);
+ }
+ };
+ c.setEditor(e);
+
+ p.add(new JLabel("Reference"));
+ p.add(r);
+ p.add(c);
+ p.add(new JLabel("Custom"));
+
+ f.add(p);
+
+ f.pack();
+ f.setVisible(true);
+ }
+
+ public Step nextStep() {
+ return focusRef;
+ }
+ };
+
+ private class FocusStep extends Step {
+ private final JComboBox<String> target;
+ private final Step focusHandler;
+ private final Step next;
+
+ public FocusStep(JComboBox<String> t, Step h, Step n) {
+ target = t;
+ focusHandler = h;
+ next = n;
+ }
+
+ public void doStep() {
+ System.out.println("Request focus on " + target);
+ final Component c = target.getEditor().getEditorComponent();
+
+ c.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ SwingUtilities.invokeLater(focusHandler);
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+
+ }
+ });
+
+ c.requestFocus();
+
+ }
+
+ public Step nextStep() {
+ return next;
+ }
+ }
+
+
+ private class CaptureStep extends Step {
+ private final JComboBox<String> target;
+ private BufferedImage img;
+ private String fname;
+ private final Step next;
+
+ private final int timeout = 2000;
+
+ public CaptureStep(JComboBox<String> t, String name, Step n) {
+ target = t;
+ next = n;
+ fname = name;
+ }
+
+ public void doStep() {
+ try {
+ Thread.sleep(timeout);
+ } catch (InterruptedException e) {
+ }
+ System.out.println("Capture sceeenshot of " + target);
+
+ Rectangle bounds = target.getBounds();
+ Point p = target.getLocationOnScreen();
+ System.out.println("Target bounds: " + bounds);
+ System.out.println("Target location: " + p);
+
+ bounds.x = p.x;
+ bounds.y = p.y;
+
+ img = robot.createScreenCapture(bounds);
+
+ try {
+ ImageIO.write(img, "PNG", new File(fname + ".png"));
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+
+ }
+
+ public Step nextStep() {
+ return next;
+ }
+ }
+
+ private final Step done = new Step() {
+ public void doStep() {
+ JFrame f = getFrame();
+ if (f != null) {
+ f.dispose();
+ }
+ System.out.println("Done");
+
+ testDone.countDown();
+ }
+
+ public Step nextStep() {
+ return null;
+ }
+ };
+
+ private final CaptureStep captureCustom = new CaptureStep(getCustom(), "cb_custom", done);
+
+ private final FocusStep focusCustom = new FocusStep(getCustom(), captureCustom, null);
+
+ private final CaptureStep captureRef = new CaptureStep(getReference(), "cb_ref", focusCustom);
+
+ private final FocusStep focusRef = new FocusStep(getReference(), captureRef, null);
+}
diff --git a/test/javax/swing/plaf/gtk/crash/RenderBadPictureCrash.java b/test/javax/swing/plaf/gtk/crash/RenderBadPictureCrash.java
new file mode 100644
index 0000000..0ef1699
--- /dev/null
+++ b/test/javax/swing/plaf/gtk/crash/RenderBadPictureCrash.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+ @test
+ @bug 8056151
+ @summary Switching to GTK L&F on-the-fly leads to X Window System error RenderBadPicture
+ @run main/othervm -Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel -Dsun.java2d.xrender=T RenderBadPictureCrash
+ */
+
+import java.awt.Color;
+import java.lang.reflect.InvocationTargetException;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import javax.swing.UIManager;
+
+public class RenderBadPictureCrash {
+
+ public static void main(String[] args) throws InterruptedException, InvocationTargetException {
+ SwingUtilities.invokeAndWait(() -> {
+ JFrame f = new JFrame();
+ f.setUndecorated(true);
+ f.setBackground(new Color(0, 0, 0, 0));
+ f.setSize(200, 300);
+ f.setVisible(true);
+
+ try {
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
+ } catch (Exception e) {
+ System.err.println(e);
+ System.err.println("Could not set GTKLookAndFeel, skipping this test");
+ } finally {
+ f.dispose();
+ }
+ });
+ }
+
+}
diff --git a/test/javax/swing/plaf/nimbus/8041642/bug8041642.java b/test/javax/swing/plaf/nimbus/8041642/bug8041642.java
new file mode 100644
index 0000000..4ed00df
--- /dev/null
+++ b/test/javax/swing/plaf/nimbus/8041642/bug8041642.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/* @test
+ @bug 8041642
+ @summary Incorrect paint of JProgressBar in Nimbus LF
+ @author Semyon Sadetsky
+*/
+
+import javax.swing.*;
+import java.awt.*;
+
+public class bug8041642 {
+
+ private static JFrame frame;
+ private static Point point;
+ private static JProgressBar bar;
+
+ public static void main(String[] args) throws Exception {
+ for (UIManager.LookAndFeelInfo info : UIManager
+ .getInstalledLookAndFeels()) {
+ if ("Nimbus".equals(info.getName())) {
+ try {
+ UIManager.setLookAndFeel(info.getClassName());
+ } catch (Exception ex) {
+ }
+ break;
+ }
+ }
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame = new JFrame();
+ frame.setUndecorated(true);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setup(frame);
+ }
+ });
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ point = bar.getLocationOnScreen();
+ }
+ });
+ final Robot robot = new Robot();
+ Color color = robot.getPixelColor(point.x + 1, point.y + 7);
+ System.out.println(color);
+ if (color.getGreen() < 150 || color.getBlue() > 30 ||
+ color.getRed() > 200) {
+ throw new RuntimeException("Bar padding color should be green");
+ }
+
+ } finally {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ //frame.dispose();
+ }
+ });
+ }
+
+ System.out.println("ok");
+ }
+
+ static void setup(JFrame frame) {
+ bar = new JProgressBar();
+ bar.setBackground(Color.WHITE);
+ bar.setValue(2);
+ frame.getContentPane().add(bar, BorderLayout.NORTH);
+ frame.getContentPane().setBackground(Color.GREEN);
+ frame.setSize(200, 150);
+ frame.setLocation(100, 100);
+ frame.setVisible(true);
+ }
+}
diff --git a/test/javax/swing/text/html/parser/8074956/bug8074956.java b/test/javax/swing/text/html/parser/8074956/bug8074956.java
new file mode 100644
index 0000000..160e6dc
--- /dev/null
+++ b/test/javax/swing/text/html/parser/8074956/bug8074956.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import javax.swing.text.html.parser.ContentModel;
+import javax.swing.text.html.parser.DTD;
+import javax.swing.text.html.parser.Element;
+
+/*
+ * @test
+ * @bug 8074956
+ * @author Alexey Ivanov
+ * @summary Tests correct handling of additional HTML elements in ContentModel
+ * @run main bug8074956
+ */
+public class bug8074956 {
+ public static void main(String[] args) throws Exception {
+ final DTD html32 = DTD.getDTD("html32");
+ ContentModel contentModel = new ContentModel('&', new ContentModel());
+
+ Element elem1 = html32.getElement("html-element");
+ contentModel.first(elem1);
+
+ Element elem2 = html32.getElement("test-element");
+ // Shouldn't throw ArrayIndexOutOfBoundsException
+ contentModel.first(elem2);
+ }
+}
diff --git a/test/javax/xml/jaxp/transform/8062518/DocumentExtFunc.java b/test/javax/xml/jaxp/transform/8062518/DocumentExtFunc.java
new file mode 100644
index 0000000..e811aed
--- /dev/null
+++ b/test/javax/xml/jaxp/transform/8062518/DocumentExtFunc.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class DocumentExtFunc {
+
+ public static String test(NodeList list) {
+ Node node = list.item(0);
+ return "["+node.getNodeName() + ":" + node.getNodeValue()+"]";
+ }
+}
diff --git a/test/javax/xml/jaxp/transform/8062518/XSLTFunctionsTest.java b/test/javax/xml/jaxp/transform/8062518/XSLTFunctionsTest.java
new file mode 100644
index 0000000..b60a7be
--- /dev/null
+++ b/test/javax/xml/jaxp/transform/8062518/XSLTFunctionsTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/* @test
+ * @bug 8062518
+ * @summary This class contains tests for XSLT functions
+ * @compile DocumentExtFunc.java
+ * @run testng/othervm XSLTFunctionsTest
+ */
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+
+public class XSLTFunctionsTest {
+
+ /**
+ * bug 8062518
+ * Verifies that a reference to the DTM created by XSLT document function is
+ * actually read from the DTM by an extension function.
+ * @param xml Content of xml file to process
+ * @param xsl stylesheet content that loads external document {@code externalDoc}
+ * with XSLT 'document' function and then reads it with
+ * DocumentExtFunc.test() function
+ * @param externalDoc Content of the external xml document
+ * @param expectedResult Expected transformation result
+ **/
+ @Test(dataProvider = "document")
+ public void testDocument(final String xml, final String xsl,
+ final String externalDoc, final String expectedResult) throws Exception {
+ // Prepare sources for transormation
+ Source src = new StreamSource(new StringReader(xml));
+ Source xslsrc = new StreamSource(new StringReader(xsl));
+
+ // Create factory and transformer
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer t = tf.newTransformer( xslsrc );
+ t.setErrorListener(tf.getErrorListener());
+
+ // Set URI Resolver to return the newly constructed xml
+ // stream source object from xml test string
+ t.setURIResolver(new URIResolver() {
+ @Override
+ public Source resolve(String href, String base)
+ throws TransformerException {
+ if (href.contains("externalDoc")) {
+ return new StreamSource(new StringReader(externalDoc));
+ } else {
+ return new StreamSource(new StringReader(xml));
+ }
+ }
+ });
+
+ // Prepare output stream
+ StringWriter xmlResultString = new StringWriter();
+ StreamResult xmlResultStream = new StreamResult(xmlResultString);
+
+ //Transform the xml
+ t.transform(src, xmlResultStream);
+
+ // If the document can't be accessed and the bug is in place then
+ // reported exception will be thrown during transformation
+ System.out.println("Transformation result:"+xmlResultString.toString().trim());
+
+ // Check the result - it should contain two (node name, node values) entries -
+ // one for original document, another for a document created with
+ // call to 'document' function
+ assertEquals(xmlResultString.toString().trim(), expectedResult);
+ }
+
+ @DataProvider(name = "document")
+ public static Object[][] documentTestData() {
+ return new Object[][] {
+ {documentTestXml, documentTestXsl, documentTestExternalDoc, documentTesteExpectedResult},
+ };
+ }
+
+ static final String documentTestXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Test>Doc</Test>";
+
+ static final String documentTestExternalDoc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Test>External Doc</Test>";
+
+ static final String documentTestXsl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<xsl:transform version=\"1.0\""
+ + " xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" "
+ + " xmlns:cfunc=\"http://xml.apache.org/xalan/java/\">"
+ + "<xsl:template match=\"/\">"
+ + "<xsl:element name=\"root\">"
+ + "<xsl:variable name=\"other_doc\" select=\"document('externalDoc')\"/>"
+ + "<!-- Source -->"
+ + "<xsl:value-of select=\"cfunc:DocumentExtFunc.test(/Test)\"/>"
+ + "<!-- document() -->"
+ + "<xsl:value-of select=\"cfunc:DocumentExtFunc.test($other_doc/Test)\"/>"
+ + "</xsl:element></xsl:template></xsl:transform>";
+
+ static final String documentTesteExpectedResult = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<root>[Test:Doc][Test:External Doc]</root>";
+}
diff --git a/test/lib/testlibrary/jdk/testlibrary/LockFreeLogManager.java b/test/lib/testlibrary/jdk/testlibrary/LockFreeLogManager.java
new file mode 100644
index 0000000..f895018
--- /dev/null
+++ b/test/lib/testlibrary/jdk/testlibrary/LockFreeLogManager.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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 jdk.testlibrary;
+
+import java.util.Collection;
+import java.util.Formatter;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+/**
+ * A log manager designed specifically to allow collecting ordered log messages
+ * in a multi-threaded environment without involving any kind of locking.
+ * <p>
+ * It is particularly useful in situations when one needs to assert various
+ * details about the tested thread state or the locks it hold while also wanting
+ * to produce diagnostic log messages.
+ * <p>
+ * The log manager does not provide any guarantees about the completness of the
+ * logs written from different threads - it is up to the caller to make sure
+ * {@code toString()} method is called only when all the activity has ceased
+ * and the per-thread logs contain all the necessary data.
+ *
+ * @author Jaroslav Bachorik
+ **/
+public class LockFreeLogManager {
+ private final AtomicInteger logCntr = new AtomicInteger(0);
+ private final Collection<Map<Integer, String>> allRecords = new ConcurrentLinkedQueue<>();
+ private final ThreadLocal<Map<Integer, String>> records = new ThreadLocal<Map<Integer, String>>() {
+ @Override
+ protected Map<Integer, String> initialValue() {
+ Map<Integer, String> m = new ConcurrentHashMap<>();
+ allRecords.add(m);
+ return m;
+ }
+
+ };
+
+ /**
+ * Log a message
+ * @param format Message format
+ * @param params Message parameters
+ */
+ public void log(String format, Object ... params) {
+ int id = logCntr.getAndIncrement();
+ try (Formatter formatter = new Formatter()) {
+ records.get().put(id, formatter.format(format, params).toString());
+ }
+ }
+
+ /**
+ * Will generate an aggregated log of chronologically ordered messages.
+ * <p>
+ * Make sure that you call this method only when all the related threads
+ * have finished; otherwise you might get incomplete data.
+ *
+ * @return An aggregated log of chronologically ordered messages
+ */
+ @Override
+ public String toString() {
+ return allRecords.stream()
+ .flatMap(m->m.entrySet().stream())
+ .sorted((l, r)->l.getKey().compareTo(r.getKey()))
+ .map(e->e.getValue())
+ .collect(Collectors.joining());
+ }
+}
diff --git a/test/lib/testlibrary/jdk/testlibrary/OSInfo.java b/test/lib/testlibrary/jdk/testlibrary/OSInfo.java
new file mode 100644
index 0000000..c32df1b
--- /dev/null
+++ b/test/lib/testlibrary/jdk/testlibrary/OSInfo.java
@@ -0,0 +1,191 @@
+/*
+ * 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
+ * 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 jdk.testlibrary;
+
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.Map;
+
+import static jdk.testlibrary.OSInfo.OSType.*;
+
+/**
+ * @author Pavel Porvatov
+ * copied to testlibrary by yan
+ */
+public class OSInfo {
+ public static enum OSType {
+ WINDOWS,
+ LINUX,
+ SOLARIS,
+ MACOSX,
+ UNKNOWN
+ }
+
+ /*
+ The map windowsVersionMap must contain all windows version constants except WINDOWS_UNKNOWN,
+ and so the method getWindowsVersion() will return the constant for known OS.
+ It allows compare objects by "==" instead of "equals".
+ */
+ public static final WindowsVersion WINDOWS_UNKNOWN = new WindowsVersion(-1, -1);
+ public static final WindowsVersion WINDOWS_95 = new WindowsVersion(4, 0);
+ public static final WindowsVersion WINDOWS_98 = new WindowsVersion(4, 10);
+ public static final WindowsVersion WINDOWS_ME = new WindowsVersion(4, 90);
+ public static final WindowsVersion WINDOWS_2000 = new WindowsVersion(5, 0);
+ public static final WindowsVersion WINDOWS_XP = new WindowsVersion(5, 1);
+ public static final WindowsVersion WINDOWS_2003 = new WindowsVersion(5, 2);
+ public static final WindowsVersion WINDOWS_VISTA = new WindowsVersion(6, 0);
+
+ private static final String OS_NAME = "os.name";
+ private static final String OS_VERSION = "os.version";
+
+ private final static Map<String, WindowsVersion> windowsVersionMap = new HashMap<String, OSInfo.WindowsVersion>();
+
+ static {
+ windowsVersionMap.put(WINDOWS_95.toString(), WINDOWS_95);
+ windowsVersionMap.put(WINDOWS_98.toString(), WINDOWS_98);
+ windowsVersionMap.put(WINDOWS_ME.toString(), WINDOWS_ME);
+ windowsVersionMap.put(WINDOWS_2000.toString(), WINDOWS_2000);
+ windowsVersionMap.put(WINDOWS_XP.toString(), WINDOWS_XP);
+ windowsVersionMap.put(WINDOWS_2003.toString(), WINDOWS_2003);
+ windowsVersionMap.put(WINDOWS_VISTA.toString(), WINDOWS_VISTA);
+ }
+
+ private static final PrivilegedAction<OSType> osTypeAction = new PrivilegedAction<OSType>() {
+ public OSType run() {
+ return getOSType();
+ }
+ };
+
+ private OSInfo() {
+ // Don't allow to create instances
+ }
+
+ /**
+ * Returns type of operating system.
+ */
+ public static OSType getOSType() throws SecurityException {
+ String osName = System.getProperty(OS_NAME);
+
+ if (osName != null) {
+ if (osName.contains("Windows")) {
+ return WINDOWS;
+ }
+
+ if (osName.contains("Linux")) {
+ return LINUX;
+ }
+
+ if (osName.contains("Solaris") || osName.contains("SunOS")) {
+ return SOLARIS;
+ }
+
+ if (osName.contains("OS X")) {
+ return MACOSX;
+ }
+
+ // determine another OS here
+ }
+
+ return UNKNOWN;
+ }
+
+ public static PrivilegedAction<OSType> getOSTypeAction() {
+ return osTypeAction;
+ }
+
+ public static WindowsVersion getWindowsVersion() throws SecurityException {
+ String osVersion = System.getProperty(OS_VERSION);
+
+ if (osVersion == null) {
+ return WINDOWS_UNKNOWN;
+ }
+
+ synchronized (windowsVersionMap) {
+ WindowsVersion result = windowsVersionMap.get(osVersion);
+
+ if (result == null) {
+ // Try parse version and put object into windowsVersionMap
+ String[] arr = osVersion.split("\\.");
+
+ if (arr.length == 2) {
+ try {
+ result = new WindowsVersion(Integer.parseInt(arr[0]), Integer.parseInt(arr[1]));
+ } catch (NumberFormatException e) {
+ return WINDOWS_UNKNOWN;
+ }
+ } else {
+ return WINDOWS_UNKNOWN;
+ }
+
+ windowsVersionMap.put(osVersion, result);
+ }
+
+ return result;
+ }
+ }
+
+ public static class WindowsVersion implements Comparable<WindowsVersion> {
+ private final int major;
+
+ private final int minor;
+
+ private WindowsVersion(int major, int minor) {
+ this.major = major;
+ this.minor = minor;
+ }
+
+ public int getMajor() {
+ return major;
+ }
+
+ public int getMinor() {
+ return minor;
+ }
+
+ public int compareTo(WindowsVersion o) {
+ int result = major - o.getMajor();
+
+ if (result == 0) {
+ result = minor - o.getMinor();
+ }
+
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ return obj instanceof WindowsVersion && compareTo((WindowsVersion) obj) == 0;
+ }
+
+ public int hashCode() {
+ return 31 * major + minor;
+ }
+
+ public String toString() {
+ return major + "." + minor;
+ }
+ }
+}
+
diff --git a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
index d4cbd27..d39c0ab 100644
--- a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
+++ b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -24,6 +24,8 @@
package jdk.testlibrary;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -394,4 +396,23 @@
public int getExitValue() {
return exitValue;
}
+
+ /**
+ * Get the contents of the output buffer (stdout and stderr) as list of strings.
+ * Output will be split by system property 'line.separator'.
+ *
+ * @return Contents of the output buffer as list of strings
+ */
+ public List<String> asLines() {
+ return asLines(getOutput());
+ }
+
+ private List<String> asLines(String buffer) {
+ List<String> l = new ArrayList<>();
+ String[] a = buffer.split(Utils.NEW_LINE);
+ for (String string : a) {
+ l.add(string);
+ }
+ return l;
+ }
}
diff --git a/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java b/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
index c949e0f..a5b956f 100644
--- a/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
+++ b/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -31,6 +31,7 @@
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.Map;
@@ -41,6 +42,7 @@
import java.util.concurrent.TimeoutException;
import java.util.function.Predicate;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
import sun.management.VMManagement;
@@ -374,4 +376,40 @@
}
return cmd.toString().trim();
}
+
+ /**
+ * Executes a process, waits for it to finish, prints the process output
+ * to stdout, and returns the process output.
+ *
+ * The process will have exited before this method returns.
+ *
+ * @param cmds The command line to execute.
+ * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+ */
+ public static OutputAnalyzer executeCommand(String... cmds)
+ throws Throwable {
+ String cmdLine = Arrays.stream(cmds).collect(Collectors.joining(" "));
+ System.out.println("Command line: [" + cmdLine + "]");
+ OutputAnalyzer analyzer = ProcessTools.executeProcess(cmds);
+ System.out.println(analyzer.getOutput());
+ return analyzer;
+ }
+
+ /**
+ * Executes a process, waits for it to finish, prints the process output
+ * to stdout and returns the process output.
+ *
+ * The process will have exited before this method returns.
+ *
+ * @param pb The ProcessBuilder to execute.
+ * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+ */
+ public static OutputAnalyzer executeCommand(ProcessBuilder pb)
+ throws Throwable {
+ String cmdLine = pb.command().stream().collect(Collectors.joining(" "));
+ System.out.println("Command line: [" + cmdLine + "]");
+ OutputAnalyzer analyzer = ProcessTools.executeProcess(pb);
+ System.out.println(analyzer.getOutput());
+ return analyzer;
+ }
}
diff --git a/test/sun/nio/cs/CheckHistoricalNames.java b/test/sun/nio/cs/CheckHistoricalNames.java
index 39e1ecd..0b1ee60 100644
--- a/test/sun/nio/cs/CheckHistoricalNames.java
+++ b/test/sun/nio/cs/CheckHistoricalNames.java
@@ -196,6 +196,7 @@
checkMappedName("IBM1122", "Cp1122");
checkMappedName("IBM1123", "Cp1123");
checkMappedName("IBM1124", "Cp1124");
+ checkMappedName("IBM1166", "Cp1166");
checkMappedName("IBM01140", "Cp1140");
checkMappedName("IBM01141", "Cp1141");
checkMappedName("IBM01142", "Cp1142");
diff --git a/test/sun/security/krb5/auto/SSL.java b/test/sun/security/krb5/auto/SSL.java
index aab2622..c72fc16 100644
--- a/test/sun/security/krb5/auto/SSL.java
+++ b/test/sun/security/krb5/auto/SSL.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -39,11 +39,10 @@
* @run main/othervm SSL TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5
*/
import java.io.*;
-import java.net.InetAddress;
-import java.security.AccessControlException;
import java.security.Permission;
import javax.net.ssl.*;
import java.security.Principal;
+import java.security.Security;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
@@ -82,6 +81,9 @@
}
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
krb5Cipher = args[0];
diff --git a/test/sun/security/pkcs11/Provider/ConfigShortPath.java b/test/sun/security/pkcs11/Provider/ConfigShortPath.java
index 030e420..a4d29e9 100644
--- a/test/sun/security/pkcs11/Provider/ConfigShortPath.java
+++ b/test/sun/security/pkcs11/Provider/ConfigShortPath.java
@@ -22,8 +22,8 @@
*/
/**
* @test
- * @bug 6581254 6986789 7196009
- * @summary Allow '~', '+' and quoted paths in config file
+ * @bug 6581254 6986789 7196009 8062170
+ * @summary Allow '~', '+', and quoted paths in config file
* @author Valerie Peng
*/
@@ -34,7 +34,7 @@
public class ConfigShortPath {
private static final String[] configNames = {
- "csp.cfg", "cspPlus.cfg", "cspQuotedPath.cfg"
+ "csp.cfg", "cspPlus.cfg", "cspSpace.cfg", "cspQuotedPath.cfg"
};
public static void main(String[] args) throws Exception {
diff --git a/test/sun/security/pkcs11/Provider/cspSpace.cfg b/test/sun/security/pkcs11/Provider/cspSpace.cfg
new file mode 100644
index 0000000..da55f9d
--- /dev/null
+++ b/test/sun/security/pkcs11/Provider/cspSpace.cfg
@@ -0,0 +1,5 @@
+showInfo = false
+name = test
+library = C:\pki DLL\x64\acpkcs211.dll
+
+
diff --git a/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java b/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java
index 8581872..92eb0f9 100644
--- a/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java
+++ b/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -27,6 +27,7 @@
* @summary Verify that the RSA KeyPairGenerator works
* @author Andreas Sterbenz
* @library ..
+ * @run main/othervm TestKeyPairGenerator
*/
import java.io.*;
diff --git a/test/sun/security/pkcs12/StoreSecretKeyTest.java b/test/sun/security/pkcs12/StoreSecretKeyTest.java
index 84c2889..97bc375 100644
--- a/test/sun/security/pkcs12/StoreSecretKeyTest.java
+++ b/test/sun/security/pkcs12/StoreSecretKeyTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,12 +23,14 @@
/*
* @test
- * @bug 8005408
+ * @bug 8005408 8079129
* @summary KeyStore API enhancements
*/
import java.io.*;
import java.security.*;
+import java.security.cert.*;
+import java.security.cert.Certificate;
import java.util.*;
import javax.crypto.*;
import javax.crypto.spec.*;
@@ -39,7 +41,9 @@
private final static String DIR = System.getProperty("test.src", ".");
private static final char[] PASSWORD = "passphrase".toCharArray();
private static final String KEYSTORE = "keystore.p12";
- private static final String ALIAS = "my secret key";
+ private static final String CERT = DIR + "/trusted.pem";
+ private static final String ALIAS = "my trusted cert";
+ private static final String ALIAS2 = "my secret key";
public static void main(String[] args) throws Exception {
@@ -56,8 +60,13 @@
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(null, null);
- // Set entry
+ // Set trusted certificate entry
+ Certificate cert = loadCertificate(CERT);
keystore.setEntry(ALIAS,
+ new KeyStore.TrustedCertificateEntry(cert), null);
+
+ // Set secret key entry
+ keystore.setEntry(ALIAS2,
new KeyStore.SecretKeyEntry(generateSecretKey("AES", 128)),
new KeyStore.PasswordProtection(PASSWORD));
@@ -73,7 +82,7 @@
" entries");
}
- KeyStore.Entry entry = keystore.getEntry(ALIAS,
+ KeyStore.Entry entry = keystore.getEntry(ALIAS2,
new KeyStore.PasswordProtection(PASSWORD));
System.out.println("Retrieved entry: " + entry);
@@ -101,4 +110,14 @@
generator.init(size);
return generator.generateKey();
}
+
+ private static Certificate loadCertificate(String certFile)
+ throws Exception {
+ X509Certificate cert = null;
+ try (FileInputStream certStream = new FileInputStream(certFile)) {
+ CertificateFactory factory =
+ CertificateFactory.getInstance("X.509");
+ return factory.generateCertificate(certStream);
+ }
+ }
}
diff --git a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/CipherSuiteOrder.java b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/CipherSuiteOrder.java
index 75e7436..75697dc 100644
--- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/CipherSuiteOrder.java
+++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/CipherSuiteOrder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -34,7 +34,7 @@
*/
import java.io.*;
-import java.net.*;
+import java.security.Security;
import javax.net.ssl.*;
public class CipherSuiteOrder {
@@ -196,6 +196,10 @@
volatile Exception clientException = null;
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
String keyFilename =
System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + keyStoreFile;
diff --git a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/LengthCheckTest.java b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/LengthCheckTest.java
new file mode 100644
index 0000000..38122d7
--- /dev/null
+++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/LengthCheckTest.java
@@ -0,0 +1,814 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044860
+ * @summary Vectors and fixed length fields should be verified
+ * for allowed sizes.
+ * @run main/othervm LengthCheckTest
+ */
+
+/**
+ * A SSLEngine usage example which simplifies the presentation
+ * by removing the I/O and multi-threading concerns.
+ *
+ * The test creates two SSLEngines, simulating a client and server.
+ * The "transport" layer consists two byte buffers: think of them
+ * as directly connected pipes.
+ *
+ * Note, this is a *very* simple example: real code will be much more
+ * involved. For example, different threading and I/O models could be
+ * used, transport mechanisms could close unexpectedly, and so on.
+ *
+ * When this application runs, notice that several messages
+ * (wrap/unwrap) pass before any application data is consumed or
+ * produced. (For more information, please see the SSL/TLS
+ * specifications.) There may several steps for a successful handshake,
+ * so it's typical to see the following series of operations:
+ *
+ * client server message
+ * ====== ====== =======
+ * wrap() ... ClientHello
+ * ... unwrap() ClientHello
+ * ... wrap() ServerHello/Certificate
+ * unwrap() ... ServerHello/Certificate
+ * wrap() ... ClientKeyExchange
+ * wrap() ... ChangeCipherSpec
+ * wrap() ... Finished
+ * ... unwrap() ClientKeyExchange
+ * ... unwrap() ChangeCipherSpec
+ * ... unwrap() Finished
+ * ... wrap() ChangeCipherSpec
+ * ... wrap() Finished
+ * unwrap() ... ChangeCipherSpec
+ * unwrap() ... Finished
+ */
+
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.security.*;
+import java.nio.*;
+import java.util.List;
+import java.util.ArrayList;
+import sun.security.ssl.ProtocolVersion;
+
+public class LengthCheckTest {
+
+ /*
+ * Enables logging of the SSLEngine operations.
+ */
+ private static final boolean logging = true;
+
+ /*
+ * Enables the JSSE system debugging system property:
+ *
+ * -Djavax.net.debug=all
+ *
+ * This gives a lot of low-level information about operations underway,
+ * including specific handshake messages, and might be best examined
+ * after gaining some familiarity with this application.
+ */
+ private static final boolean debug = false;
+ private static final boolean dumpBufs = true;
+
+ private final SSLContext sslc;
+
+ private SSLEngine clientEngine; // client Engine
+ private ByteBuffer clientOut; // write side of clientEngine
+ private ByteBuffer clientIn; // read side of clientEngine
+
+ private SSLEngine serverEngine; // server Engine
+ private ByteBuffer serverOut; // write side of serverEngine
+ private ByteBuffer serverIn; // read side of serverEngine
+
+ private HandshakeTest handshakeTest;
+
+ /*
+ * For data transport, this example uses local ByteBuffers. This
+ * isn't really useful, but the purpose of this example is to show
+ * SSLEngine concepts, not how to do network transport.
+ */
+ private ByteBuffer cTOs; // "reliable" transport client->server
+ private ByteBuffer sTOc; // "reliable" transport server->client
+
+ /*
+ * The following is to set up the keystores.
+ */
+ private static final String pathToStores = "/../../../../../../../etc";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final String passwd = "passphrase";
+
+ private static final String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ private static final String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ // Define a few basic TLS record and message types we might need
+ private static final int TLS_RECTYPE_CCS = 0x14;
+ private static final int TLS_RECTYPE_ALERT = 0x15;
+ private static final int TLS_RECTYPE_HANDSHAKE = 0x16;
+ private static final int TLS_RECTYPE_APPDATA = 0x17;
+
+ private static final int TLS_HS_HELLO_REQUEST = 0x00;
+ private static final int TLS_HS_CLIENT_HELLO = 0x01;
+ private static final int TLS_HS_SERVER_HELLO = 0x02;
+ private static final int TLS_HS_CERTIFICATE = 0x0B;
+ private static final int TLS_HS_SERVER_KEY_EXCHG = 0x0C;
+ private static final int TLS_HS_CERT_REQUEST = 0x0D;
+ private static final int TLS_HS_SERVER_HELLO_DONE = 0x0E;
+ private static final int TLS_HS_CERT_VERIFY = 0x0F;
+ private static final int TLS_HS_CLIENT_KEY_EXCHG = 0x10;
+ private static final int TLS_HS_FINISHED = 0x14;
+
+ // We're not going to define all the alert types in TLS, just
+ // the ones we think we'll need to reference by name.
+ private static final int TLS_ALERT_LVL_WARNING = 0x01;
+ private static final int TLS_ALERT_LVL_FATAL = 0x02;
+
+ private static final int TLS_ALERT_UNEXPECTED_MSG = 0x0A;
+ private static final int TLS_ALERT_HANDSHAKE_FAILURE = 0x28;
+ private static final int TLS_ALERT_INTERNAL_ERROR = 0x50;
+
+ public interface HandshakeTest {
+ void execTest() throws Exception;
+ }
+
+ public final HandshakeTest servSendLongID = new HandshakeTest() {
+ @Override
+ public void execTest() throws Exception {
+ boolean gotException = false;
+ SSLEngineResult clientResult; // results from client's last op
+ SSLEngineResult serverResult; // results from server's last op
+
+ log("\n==== Test: Client receives 64-byte session ID ====");
+
+ // Send Client Hello
+ clientResult = clientEngine.wrap(clientOut, cTOs);
+ log("client wrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ cTOs.flip();
+ dumpByteBuffer("CLIENT-TO-SERVER", cTOs);
+
+ // Server consumes Client Hello
+ serverResult = serverEngine.unwrap(cTOs, serverIn);
+ log("server unwrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ cTOs.compact();
+
+ // Server generates ServerHello/Cert/Done record
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ sTOc.flip();
+
+ // Intercept the ServerHello messages and instead send
+ // one that has a 64-byte session ID.
+ if (isTlsMessage(sTOc, TLS_RECTYPE_HANDSHAKE,
+ TLS_HS_SERVER_HELLO)) {
+ ArrayList<ByteBuffer> recList = splitRecord(sTOc);
+
+ // Use the original ServerHello as a template to craft one
+ // with a longer-than-allowed session ID.
+ ByteBuffer servHelloBuf =
+ createEvilServerHello(recList.get(0), 64);
+
+ recList.set(0, servHelloBuf);
+
+ // Now send each ByteBuffer (each being a complete
+ // TLS record) into the client-side unwrap.
+ for (ByteBuffer bBuf : recList) {
+ dumpByteBuffer("SERVER-TO-CLIENT", bBuf);
+ try {
+ clientResult = clientEngine.unwrap(bBuf, clientIn);
+ } catch (SSLProtocolException e) {
+ log("Received expected SSLProtocolException: " + e);
+ gotException = true;
+ }
+ log("client unwrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ }
+ } else {
+ dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
+ log("client unwrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ }
+ sTOc.compact();
+
+ // The Client should now send a TLS Alert
+ clientResult = clientEngine.wrap(clientOut, cTOs);
+ log("client wrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ cTOs.flip();
+ dumpByteBuffer("CLIENT-TO-SERVER", cTOs);
+
+ // At this point we can verify that both an exception
+ // was thrown and the proper action (a TLS alert) was
+ // sent back to the server.
+ if (gotException == false ||
+ !isTlsMessage(cTOs, TLS_RECTYPE_ALERT, TLS_ALERT_LVL_FATAL,
+ TLS_ALERT_INTERNAL_ERROR)) {
+ throw new SSLException(
+ "Client failed to throw Alert:fatal:internal_error");
+ }
+ }
+ };
+
+ public final HandshakeTest clientSendLongID = new HandshakeTest() {
+ @Override
+ public void execTest() throws Exception {
+ boolean gotException = false;
+ SSLEngineResult clientResult; // results from client's last op
+ SSLEngineResult serverResult; // results from server's last op
+
+ log("\n==== Test: Server receives 64-byte session ID ====");
+
+ // Send Client Hello
+ ByteBuffer evilClientHello = createEvilClientHello(64);
+ dumpByteBuffer("CLIENT-TO-SERVER", evilClientHello);
+
+ try {
+ // Server consumes Client Hello
+ serverResult = serverEngine.unwrap(evilClientHello, serverIn);
+ log("server unwrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ evilClientHello.compact();
+
+ // Under normal circumstances this should be a ServerHello
+ // But should throw an exception instead due to the invalid
+ // session ID.
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ sTOc.flip();
+ dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
+ } catch (SSLProtocolException ssle) {
+ log("Received expected SSLProtocolException: " + ssle);
+ gotException = true;
+ }
+
+ // We expect to see the server generate an alert here
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ sTOc.flip();
+ dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
+
+ // At this point we can verify that both an exception
+ // was thrown and the proper action (a TLS alert) was
+ // sent back to the client.
+ if (gotException == false ||
+ !isTlsMessage(sTOc, TLS_RECTYPE_ALERT, TLS_ALERT_LVL_FATAL,
+ TLS_ALERT_INTERNAL_ERROR)) {
+ throw new SSLException(
+ "Server failed to throw Alert:fatal:internal_error");
+ }
+ }
+ };
+
+
+ /*
+ * Main entry point for this test.
+ */
+ public static void main(String args[]) throws Exception {
+ List<LengthCheckTest> ccsTests = new ArrayList<>();
+
+ if (debug) {
+ System.setProperty("javax.net.debug", "ssl");
+ }
+
+ ccsTests.add(new LengthCheckTest("ServSendLongID"));
+ ccsTests.add(new LengthCheckTest("ClientSendLongID"));
+
+ for (LengthCheckTest test : ccsTests) {
+ test.runTest();
+ }
+
+ System.out.println("Test Passed.");
+ }
+
+ /*
+ * Create an initialized SSLContext to use for these tests.
+ */
+ public LengthCheckTest(String testName) throws Exception {
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ KeyStore ts = KeyStore.getInstance("JKS");
+
+ char[] passphrase = "passphrase".toCharArray();
+
+ ks.load(new FileInputStream(keyFilename), passphrase);
+ ts.load(new FileInputStream(trustFilename), passphrase);
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ts);
+
+ SSLContext sslCtx = SSLContext.getInstance("TLS");
+
+ sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+ sslc = sslCtx;
+
+ switch (testName) {
+ case "ServSendLongID":
+ handshakeTest = servSendLongID;
+ break;
+ case "ClientSendLongID":
+ handshakeTest = clientSendLongID;
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown test name: " +
+ testName);
+ }
+ }
+
+ /*
+ * Run the test.
+ *
+ * Sit in a tight loop, both engines calling wrap/unwrap regardless
+ * of whether data is available or not. We do this until both engines
+ * report back they are closed.
+ *
+ * The main loop handles all of the I/O phases of the SSLEngine's
+ * lifetime:
+ *
+ * initial handshaking
+ * application data transfer
+ * engine closing
+ *
+ * One could easily separate these phases into separate
+ * sections of code.
+ */
+ private void runTest() throws Exception {
+ boolean dataDone = false;
+
+ createSSLEngines();
+ createBuffers();
+
+ handshakeTest.execTest();
+ }
+
+ /*
+ * Using the SSLContext created during object creation,
+ * create/configure the SSLEngines we'll use for this test.
+ */
+ private void createSSLEngines() throws Exception {
+ /*
+ * Configure the serverEngine to act as a server in the SSL/TLS
+ * handshake. Also, require SSL client authentication.
+ */
+ serverEngine = sslc.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+ serverEngine.setNeedClientAuth(false);
+
+ /*
+ * Similar to above, but using client mode instead.
+ */
+ clientEngine = sslc.createSSLEngine("client", 80);
+ clientEngine.setUseClientMode(true);
+
+ // In order to make a test that will be backwards compatible
+ // going back to JDK 5, force the handshake to be TLS 1.0 and
+ // use one of the older cipher suites.
+ clientEngine.setEnabledProtocols(new String[]{"TLSv1"});
+ clientEngine.setEnabledCipherSuites(
+ new String[]{"TLS_RSA_WITH_AES_128_CBC_SHA"});
+ }
+
+ /*
+ * Create and size the buffers appropriately.
+ */
+ private void createBuffers() {
+
+ /*
+ * We'll assume the buffer sizes are the same
+ * between client and server.
+ */
+ SSLSession session = clientEngine.getSession();
+ int appBufferMax = session.getApplicationBufferSize();
+ int netBufferMax = session.getPacketBufferSize();
+
+ /*
+ * We'll make the input buffers a bit bigger than the max needed
+ * size, so that unwrap()s following a successful data transfer
+ * won't generate BUFFER_OVERFLOWS.
+ *
+ * We'll use a mix of direct and indirect ByteBuffers for
+ * tutorial purposes only. In reality, only use direct
+ * ByteBuffers when they give a clear performance enhancement.
+ */
+ clientIn = ByteBuffer.allocate(appBufferMax + 50);
+ serverIn = ByteBuffer.allocate(appBufferMax + 50);
+
+ cTOs = ByteBuffer.allocateDirect(netBufferMax);
+ sTOc = ByteBuffer.allocateDirect(netBufferMax);
+
+ clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
+ serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes());
+ }
+
+ /*
+ * If the result indicates that we have outstanding tasks to do,
+ * go ahead and run them in this thread.
+ */
+ private static void runDelegatedTasks(SSLEngineResult result,
+ SSLEngine engine) throws Exception {
+
+ if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ log("\trunning delegated task...");
+ runnable.run();
+ }
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ log("\tnew HandshakeStatus: " + hsStatus);
+ }
+ }
+
+ private static boolean isEngineClosed(SSLEngine engine) {
+ return (engine.isOutboundDone() && engine.isInboundDone());
+ }
+
+ /*
+ * Simple check to make sure everything came across as expected.
+ */
+ private static void checkTransfer(ByteBuffer a, ByteBuffer b)
+ throws Exception {
+ a.flip();
+ b.flip();
+
+ if (!a.equals(b)) {
+ throw new Exception("Data didn't transfer cleanly");
+ } else {
+ log("\tData transferred cleanly");
+ }
+
+ a.position(a.limit());
+ b.position(b.limit());
+ a.limit(a.capacity());
+ b.limit(b.capacity());
+ }
+
+ /*
+ * Logging code
+ */
+ private static boolean resultOnce = true;
+
+ private static void log(String str, SSLEngineResult result) {
+ if (!logging) {
+ return;
+ }
+ if (resultOnce) {
+ resultOnce = false;
+ System.out.println("The format of the SSLEngineResult is: \n" +
+ "\t\"getStatus() / getHandshakeStatus()\" +\n" +
+ "\t\"bytesConsumed() / bytesProduced()\"\n");
+ }
+ HandshakeStatus hsStatus = result.getHandshakeStatus();
+ log(str +
+ result.getStatus() + "/" + hsStatus + ", " +
+ result.bytesConsumed() + "/" + result.bytesProduced() +
+ " bytes");
+ if (hsStatus == HandshakeStatus.FINISHED) {
+ log("\t...ready for application data");
+ }
+ }
+
+ private static void log(String str) {
+ if (logging) {
+ System.out.println(str);
+ }
+ }
+
+ /**
+ * Split a record consisting of multiple TLS handshake messages
+ * into individual TLS records, each one in a ByteBuffer of its own.
+ *
+ * @param tlsRecord A ByteBuffer containing the tls record data.
+ * The position of the buffer should be at the first byte
+ * in the TLS record data.
+ *
+ * @return An ArrayList consisting of one or more ByteBuffers. Each
+ * ByteBuffer will contain a single TLS record with one message.
+ * That message will be taken from the input record. The order
+ * of the messages in the ArrayList will be the same as they
+ * were in the input record.
+ */
+ private ArrayList<ByteBuffer> splitRecord(ByteBuffer tlsRecord) {
+ SSLSession session = clientEngine.getSession();
+ int netBufferMax = session.getPacketBufferSize();
+ ArrayList<ByteBuffer> recordList = new ArrayList<>();
+
+ if (tlsRecord.hasRemaining()) {
+ int type = Byte.toUnsignedInt(tlsRecord.get());
+ byte ver_major = tlsRecord.get();
+ byte ver_minor = tlsRecord.get();
+ int recLen = Short.toUnsignedInt(tlsRecord.getShort());
+ byte[] newMsgData = null;
+ while (tlsRecord.hasRemaining()) {
+ ByteBuffer newRecord = ByteBuffer.allocateDirect(netBufferMax);
+ switch (type) {
+ case TLS_RECTYPE_CCS:
+ case TLS_RECTYPE_ALERT:
+ case TLS_RECTYPE_APPDATA:
+ // None of our tests have multiple non-handshake
+ // messages coalesced into a single record.
+ break;
+ case TLS_RECTYPE_HANDSHAKE:
+ newMsgData = getHandshakeMessage(tlsRecord);
+ break;
+ }
+
+ // Put a new TLS record on the destination ByteBuffer
+ newRecord.put((byte)type);
+ newRecord.put(ver_major);
+ newRecord.put(ver_minor);
+ newRecord.putShort((short)newMsgData.length);
+
+ // Now add the message content itself and attach to the
+ // returned ArrayList
+ newRecord.put(newMsgData);
+ newRecord.flip();
+ recordList.add(newRecord);
+ }
+ }
+
+ return recordList;
+ }
+
+ private static ByteBuffer createEvilClientHello(int sessIdLen) {
+ ByteBuffer newRecord = ByteBuffer.allocateDirect(4096);
+
+ // Lengths will initially be place holders until we determine the
+ // finished length of the ByteBuffer. Then we'll go back and scribble
+ // in the correct lengths.
+
+ newRecord.put((byte)TLS_RECTYPE_HANDSHAKE); // Record type
+ newRecord.putShort((short)0x0301); // Protocol (TLS 1.0)
+ newRecord.putShort((short)0); // Length place holder
+
+ newRecord.putInt(TLS_HS_CLIENT_HELLO << 24); // HS type and length
+ newRecord.putShort((short)0x0301);
+ newRecord.putInt((int)(System.currentTimeMillis() / 1000));
+ SecureRandom sr = new SecureRandom();
+ byte[] randBuf = new byte[28];
+ sr.nextBytes(randBuf);
+ newRecord.put(randBuf); // Client Random
+ newRecord.put((byte)sessIdLen); // Session ID length
+ if (sessIdLen > 0) {
+ byte[] sessId = new byte[sessIdLen];
+ sr.nextBytes(sessId);
+ newRecord.put(sessId); // Session ID
+ }
+ newRecord.putShort((short)2); // 2 bytes of ciphers
+ newRecord.putShort((short)0x002F); // TLS_RSA_AES_CBC_SHA
+ newRecord.putShort((short)0x0100); // only null compression
+ newRecord.putShort((short)5); // 5 bytes of extensions
+ newRecord.putShort((short)0xFF01); // Renegotiation info
+ newRecord.putShort((short)1);
+ newRecord.put((byte)0); // No reneg info exts
+
+ // Go back and fill in the correct length values for the record
+ // and handshake message headers.
+ int recordLength = newRecord.position();
+ newRecord.putShort(3, (short)(recordLength - 5));
+ int newTypeAndLen = (newRecord.getInt(5) & 0xFF000000) |
+ ((recordLength - 9) & 0x00FFFFFF);
+ newRecord.putInt(5, newTypeAndLen);
+
+ newRecord.flip();
+ return newRecord;
+ }
+
+ private static ByteBuffer createEvilServerHello(ByteBuffer origHello,
+ int newSessIdLen) {
+ if (newSessIdLen < 0 || newSessIdLen > Byte.MAX_VALUE) {
+ throw new RuntimeException("Length must be 0 <= X <= 127");
+ }
+
+ ByteBuffer newRecord = ByteBuffer.allocateDirect(4096);
+ // Copy the bytes from the old hello to the new up to the session ID
+ // field. We will go back later and fill in a new length field in
+ // the record header. This includes the record header (5 bytes), the
+ // Handshake message header (4 bytes), protocol version (2 bytes),
+ // and the random (32 bytes).
+ ByteBuffer scratchBuffer = origHello.slice();
+ scratchBuffer.limit(43);
+ newRecord.put(scratchBuffer);
+
+ // Advance the position in the originial hello buffer past the
+ // session ID.
+ origHello.position(43);
+ int origIDLen = Byte.toUnsignedInt(origHello.get());
+ if (origIDLen > 0) {
+ // Skip over the session ID
+ origHello.position(origHello.position() + origIDLen);
+ }
+
+ // Now add our own sessionID to the new record
+ SecureRandom sr = new SecureRandom();
+ byte[] sessId = new byte[newSessIdLen];
+ sr.nextBytes(sessId);
+ newRecord.put((byte)newSessIdLen);
+ newRecord.put(sessId);
+
+ // Create another slice in the original buffer, based on the position
+ // past the session ID. Copy the remaining bytes into the new
+ // hello buffer. Then go back and fix up the length
+ newRecord.put(origHello.slice());
+
+ // Go back and fill in the correct length values for the record
+ // and handshake message headers.
+ int recordLength = newRecord.position();
+ newRecord.putShort(3, (short)(recordLength - 5));
+ int newTypeAndLen = (newRecord.getInt(5) & 0xFF000000) |
+ ((recordLength - 9) & 0x00FFFFFF);
+ newRecord.putInt(5, newTypeAndLen);
+
+ newRecord.flip();
+ return newRecord;
+ }
+
+ /**
+ * Look at an incoming TLS record and see if it is the desired
+ * record type, and where appropriate the correct subtype.
+ *
+ * @param srcRecord The input TLS record to be evaluated. This
+ * method will only look at the leading message if multiple
+ * TLS handshake messages are coalesced into a single record.
+ * @param reqRecType The requested TLS record type
+ * @param recParams Zero or more integer sub type fields. For CCS
+ * and ApplicationData, no params are used. For handshake records,
+ * one value corresponding to the HandshakeType is required.
+ * For Alerts, two values corresponding to AlertLevel and
+ * AlertDescription are necessary.
+ *
+ * @return true if the proper handshake message is the first one
+ * in the input record, false otherwise.
+ */
+ private boolean isTlsMessage(ByteBuffer srcRecord, int reqRecType,
+ int... recParams) {
+ boolean foundMsg = false;
+
+ if (srcRecord.hasRemaining()) {
+ srcRecord.mark();
+
+ // Grab the fields from the TLS Record
+ int recordType = Byte.toUnsignedInt(srcRecord.get());
+ byte ver_major = srcRecord.get();
+ byte ver_minor = srcRecord.get();
+ int recLen = Short.toUnsignedInt(srcRecord.getShort());
+
+ if (recordType == reqRecType) {
+ // For any zero-length recParams, making sure the requested
+ // type is sufficient.
+ if (recParams.length == 0) {
+ foundMsg = true;
+ } else {
+ switch (recordType) {
+ case TLS_RECTYPE_CCS:
+ case TLS_RECTYPE_APPDATA:
+ // We really shouldn't find ourselves here, but
+ // if someone asked for these types and had more
+ // recParams we can ignore them.
+ foundMsg = true;
+ break;
+ case TLS_RECTYPE_ALERT:
+ // Needs two params, AlertLevel and AlertDescription
+ if (recParams.length != 2) {
+ throw new RuntimeException(
+ "Test for Alert requires level and desc.");
+ } else {
+ int level = Byte.toUnsignedInt(srcRecord.get());
+ int desc = Byte.toUnsignedInt(srcRecord.get());
+ if (level == recParams[0] &&
+ desc == recParams[1]) {
+ foundMsg = true;
+ }
+ }
+ break;
+ case TLS_RECTYPE_HANDSHAKE:
+ // Needs one parameter, HandshakeType
+ if (recParams.length != 1) {
+ throw new RuntimeException(
+ "Test for Handshake requires only HS type");
+ } else {
+ // Go into the first handhshake message in the
+ // record and grab the handshake message header.
+ // All we need to do is parse out the leading
+ // byte.
+ int msgHdr = srcRecord.getInt();
+ int msgType = (msgHdr >> 24) & 0x000000FF;
+ if (msgType == recParams[0]) {
+ foundMsg = true;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ srcRecord.reset();
+ }
+
+ return foundMsg;
+ }
+
+ private byte[] getHandshakeMessage(ByteBuffer srcRecord) {
+ // At the start of this routine, the position should be lined up
+ // at the first byte of a handshake message. Mark this location
+ // so we can return to it after reading the type and length.
+ srcRecord.mark();
+ int msgHdr = srcRecord.getInt();
+ int type = (msgHdr >> 24) & 0x000000FF;
+ int length = msgHdr & 0x00FFFFFF;
+
+ // Create a byte array that has enough space for the handshake
+ // message header and body.
+ byte[] data = new byte[length + 4];
+ srcRecord.reset();
+ srcRecord.get(data, 0, length + 4);
+
+ return (data);
+ }
+
+ /**
+ * Hex-dumps a ByteBuffer to stdout.
+ */
+ private static void dumpByteBuffer(String header, ByteBuffer bBuf) {
+ if (dumpBufs == false) {
+ return;
+ }
+
+ int bufLen = bBuf.remaining();
+ if (bufLen > 0) {
+ bBuf.mark();
+
+ // We expect the position of the buffer to be at the
+ // beginning of a TLS record. Get the type, version and length.
+ int type = Byte.toUnsignedInt(bBuf.get());
+ int ver_major = Byte.toUnsignedInt(bBuf.get());
+ int ver_minor = Byte.toUnsignedInt(bBuf.get());
+ int recLen = Short.toUnsignedInt(bBuf.getShort());
+ ProtocolVersion pv = ProtocolVersion.valueOf(ver_major, ver_minor);
+
+ log("===== " + header + " (" + tlsRecType(type) + " / " +
+ pv + " / " + bufLen + " bytes) =====");
+ bBuf.reset();
+ for (int i = 0; i < bufLen; i++) {
+ if (i != 0 && i % 16 == 0) {
+ System.out.print("\n");
+ }
+ System.out.format("%02X ", bBuf.get(i));
+ }
+ log("\n===============================================");
+ bBuf.reset();
+ }
+ }
+
+ private static String tlsRecType(int type) {
+ switch (type) {
+ case 20:
+ return "Change Cipher Spec";
+ case 21:
+ return "Alert";
+ case 22:
+ return "Handshake";
+ case 23:
+ return "Application Data";
+ default:
+ return ("Unknown (" + type + ")");
+ }
+ }
+}
diff --git a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java
index 4156c4a..98288f4 100644
--- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java
+++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java
@@ -103,10 +103,10 @@
import java.security.Security;
import java.security.KeyStore;
import java.security.KeyFactory;
+import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.*;
import java.security.interfaces.*;
import java.util.Base64;
diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java
index dfdefa9..7b8c5e9 100644
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java
+++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -622,6 +622,9 @@
}
public static void main(String args[]) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
CheckStatus cs;
diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.java
index 9873611..9b43669 100644
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.java
+++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.java
@@ -33,6 +33,8 @@
* The code could certainly be tightened up a lot.
*
* @author Brad Wetmore
+ *
+ * @run main/othervm ConnectionTest
*/
import javax.net.ssl.*;
@@ -672,6 +674,10 @@
}
public static void main(String args[]) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
ConnectionTest ct = new ConnectionTest();
ct.test();
}
diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java
index a7a9f44..528e327 100644
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java
+++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java
@@ -180,6 +180,9 @@
}
public static void main(String args[]) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
LargeBufs test;
diff --git a/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java b/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java
index 41ae7bb..8c92a2b 100644
--- a/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java
+++ b/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java
@@ -35,7 +35,7 @@
*/
import java.io.*;
-import java.net.*;
+import java.security.Security;
import javax.net.ssl.*;
import java.util.Arrays;
@@ -195,6 +195,10 @@
volatile Exception clientException = null;
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
// parse the arguments
parseArguments(args);
diff --git a/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericStreamCipher.java b/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericStreamCipher.java
index 0bb929a..b378f12 100644
--- a/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericStreamCipher.java
+++ b/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericStreamCipher.java
@@ -36,7 +36,7 @@
*/
import java.io.*;
-import java.net.*;
+import java.security.Security;
import javax.net.ssl.*;
public class GenericStreamCipher {
@@ -164,6 +164,10 @@
volatile Exception clientException = null;
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
String keyFilename =
System.getProperty("test.src", ".") + "/" + pathToStores +
"/" + keyStoreFile;
diff --git a/test/sun/security/tools/keytool/ExportPrivateKeyNoPwd.java b/test/sun/security/tools/keytool/ExportPrivateKeyNoPwd.java
new file mode 100644
index 0000000..799bf45
--- /dev/null
+++ b/test/sun/security/tools/keytool/ExportPrivateKeyNoPwd.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+import java.security.*;
+
+/*
+ * Export a private key from the named keychain entry without supplying a
+ * password. See JDK-8062264.
+ *
+ * NOTE: Keychain access controls must already have been lowered to permit
+ * the target entry to be accessed.
+ */
+public class ExportPrivateKeyNoPwd {
+
+ public static final void main(String[] args) throws Exception {
+
+ if (args.length != 1) {
+ throw new Exception(
+ "ExportPrivateKeyNoPwd: must supply name of a keystore entry");
+ }
+ String alias = args[0];
+
+ KeyStore ks = KeyStore.getInstance("KeychainStore");
+ System.out.println("ExportPrivateKeyNoPwd: loading keychains...");
+ ks.load(null, null);
+
+ System.out.println("ExportPrivateKeyNoPwd: exporting key...");
+ Key key = ks.getKey(alias, null);
+ if (key instanceof PrivateKey) {
+ System.out.println("ExportPrivateKeyNoPwd: exported " +
+ key.getAlgorithm() + " private key from '" + alias + "'");
+ } else {
+ throw new Exception("Error exporting private key from keychain");
+ }
+ }
+}
+
diff --git a/test/sun/security/tools/keytool/ListKeychainStore.sh b/test/sun/security/tools/keytool/ListKeychainStore.sh
index b6e486c..17e1b5a 100644
--- a/test/sun/security/tools/keytool/ListKeychainStore.sh
+++ b/test/sun/security/tools/keytool/ListKeychainStore.sh
@@ -22,7 +22,7 @@
#
# @test
-# @bug 7133495 8041740
+# @bug 7133495 8041740 8062264
# @summary [macosx] KeyChain KeyStore implementation retrieves only one private key entry
if [ "${TESTJAVA}" = "" ] ; then
@@ -30,6 +30,9 @@
TESTJAVA=`dirname $JAVAC_CMD`/..
fi
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
if [ "${TESTCLASSES}" = "" ] ; then
TESTCLASSES=`pwd`
fi
@@ -59,10 +62,6 @@
COUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l`
echo "Found $COUNT private key entries in the Keychain keystores"
-if [ $COUNT -gt 1 ]; then
- exit 0
-fi
-
# Create a temporary PKCS12 keystore containing 3 public/private keypairs
RESULT=`$CLEANUP_P12`
@@ -107,8 +106,9 @@
echo "Unlocked the temporary keychain"
# Import the keypairs from the PKCS12 keystore into the keychain
+# (The '-A' option is used to lower the temporary keychain's access controls)
-security import $TEMPORARY_P12 -k $TEMPORARY_KC -f pkcs12 -P $PWD
+security import $TEMPORARY_P12 -k $TEMPORARY_KC -f pkcs12 -P $PWD -A
if [ $? -ne 0 ]; then
echo "Error: cannot import keypairs from PKCS12 keystore into the keychain"
RESULT=`$CLEANUP_P12`
@@ -128,26 +128,39 @@
# Recount the number of private key entries in the Keychain keystores
-COUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l`
-echo "Found $COUNT private key entries in the Keychain keystore"
-if [ $COUNT -lt 3 ]; then
- echo "Error: expected >2 private key entries in the Keychain keystores"
+RECOUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l`
+echo "Found $RECOUNT private key entries in the Keychain keystore"
+if [ $RECOUNT -lt `expr $COUNT + 3` ]; then
+ echo "Error: expected >$COUNT private key entries in the Keychain keystores"
RESULT=`$CLEANUP_P12`
RESULT=`$CLEANUP_KC`
exit 5
fi
+# Export a private key from the keychain (without supplying a password)
+# Access controls have already been lowered (see 'security import ... -A' above)
+
+${TESTJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . ${TESTSRC}/ExportPrivateKeyNoPwd.java || exit 6
+echo | ${TESTJAVA}/bin/java ${TESTVMOPTS} ExportPrivateKeyNoPwd x
+if [ $? -ne 0 ]; then
+ echo "Error exporting private key from the temporary keychain"
+ RESULT=`$CLEANUP_P12`
+ RESULT=`$CLEANUP_KC`
+ exit 6
+fi
+echo "Exported a private key from the temporary keychain"
+
RESULT=`$CLEANUP_P12`
if [ $? -ne 0 ]; then
echo "Error: cannot remove the temporary PKCS12 keystore"
- exit 6
+ exit 7
fi
echo "Removed the temporary PKCS12 keystore"
RESULT=`$CLEANUP_KC`
if [ $? -ne 0 ]; then
echo "Error: cannot remove the temporary keychain"
- exit 7
+ exit 8
fi
echo "Removed the temporary keychain"
diff --git a/test/sun/text/resources/Format/Bug8074791.java b/test/sun/text/resources/Format/Bug8074791.java
new file mode 100644
index 0000000..138158c
--- /dev/null
+++ b/test/sun/text/resources/Format/Bug8074791.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8074791
+ * @summary Make sure that Finnish month names are correct in formatted text.
+ */
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import static java.text.DateFormat.*;
+import static java.util.Calendar.JANUARY;
+
+public class Bug8074791 {
+ private static Locale FINNISH = new Locale("fi");
+ private static String JAN_FORMAT = "tammikuuta";
+ private static String JAN_STANDALONE = "tammikuu";
+
+ public static void main(String[] arg) {
+ int errors = 0;
+
+ DateFormat df = DateFormat.getDateInstance(LONG, FINNISH);
+ Date jan20 = new GregorianCalendar(2015, JANUARY, 20).getTime();
+ String str = df.format(jan20).toString();
+ // Extract the month name (locale data dependent)
+ String month = str.replaceAll(".+\\s([a-z]+)\\s\\d+$", "$1");
+ if (!month.equals(JAN_FORMAT)) {
+ errors++;
+ System.err.println("wrong format month name: got '" + month
+ + "', expected '" + JAN_FORMAT + "'");
+ }
+
+ SimpleDateFormat sdf = new SimpleDateFormat("LLLL", FINNISH); // stand-alone month name
+ month = sdf.format(jan20);
+ if (!month.equals(JAN_STANDALONE)) {
+ errors++;
+ System.err.println("wrong stand-alone month name: got '" + month
+ + "', expected '" + JAN_STANDALONE + "'");
+ }
+
+ if (errors > 0) {
+ throw new RuntimeException();
+ }
+ }
+}
diff --git a/test/sun/text/resources/LocaleData b/test/sun/text/resources/LocaleData
index f6439c2..0568d33 100644
--- a/test/sun/text/resources/LocaleData
+++ b/test/sun/text/resources/LocaleData
@@ -8276,3 +8276,12 @@
FormatData/zh/MonthNarrows/10=11
FormatData/zh/MonthNarrows/11=12
FormatData/zh/MonthNarrows/12=
+
+# bug #8074791
+FormatData/fi/DatePatterns/0=d. MMMM yyyy
+FormatData/fi/DatePatterns/1=d. MMMM yyyy
+FormatData/fi/DatePatterns/2=d.M.yyyy
+FormatData/fi/DatePatterns/3=d.M.yyyy
+
+# bug #8075173
+FormatData/de/standalone.MonthAbbreviations/2=M\u00e4r
diff --git a/test/sun/text/resources/LocaleDataTest.java b/test/sun/text/resources/LocaleDataTest.java
index 6ac5dc5..1558c2d 100644
--- a/test/sun/text/resources/LocaleDataTest.java
+++ b/test/sun/text/resources/LocaleDataTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -36,7 +36,7 @@
* 6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203 7101495
* 7003124 7085757 7028073 7171028 7189611 8000983 7195759 8004489 8006509
* 7114053 7074882 7040556 8013836 8021121 6192407 6931564 8027695 7090826
- * 8017142 8037343 8055222 8042126
+ * 8017142 8037343 8055222 8042126 8074791 8075173
* @summary Verify locale data
*
*/
diff --git a/test/sun/util/calendar/zi/Rule.java b/test/sun/util/calendar/zi/Rule.java
index ee4df5b..a30f2c0 100644
--- a/test/sun/util/calendar/zi/Rule.java
+++ b/test/sun/util/calendar/zi/Rule.java
@@ -126,6 +126,14 @@
});
rules.clear();
for (int i = 0; i < n; i++) {
+ if (i != 0 && recs[i -1].getSave() == recs[i].getSave()) {
+ // we have two recs back to back with same saving for the same year.
+ if (recs[i].isLastRule()) {
+ continue;
+ } else if (recs[i - 1].isLastRule()) {
+ rules.remove(rules.size() - 1);
+ }
+ }
rules.add(recs[i]);
}
return rules;