< prev index next >

src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp

Print this page




  23  * questions.
  24  */
  25 
  26 /*
  27  * A class to manage JNI calls into AccessBridge.java
  28  */
  29 
  30 #include "AccessBridgeJavaEntryPoints.h"
  31 #include "AccessBridgeDebug.h"
  32 
  33 
  34 
  35 /**
  36  * Initialize the AccessBridgeJavaEntryPoints class
  37  *
  38  */
  39 AccessBridgeJavaEntryPoints::AccessBridgeJavaEntryPoints(JNIEnv *jniEnvironment,
  40                                                          jobject bridgeObject) {
  41     jniEnv = jniEnvironment;
  42     accessBridgeObject = (jobject)bridgeObject;
  43     PrintDebugString("AccessBridgeJavaEntryPoints(%p, %p) called", jniEnv, accessBridgeObject);
  44 }
  45 
  46 
  47 /**
  48  * Destructor
  49  *
  50  */
  51 AccessBridgeJavaEntryPoints::~AccessBridgeJavaEntryPoints() {
  52 }
  53 
  54 // -----------------------------------
  55 
  56 #define FIND_CLASS(classRef, className) \
  57     localClassRef = jniEnv->FindClass(className); \
  58     if (localClassRef == (jclass) 0) { \
  59         PrintDebugString("  Error! FindClass(%s) failed!", className); \
  60         PrintDebugString("    -> jniEnv = %p", jniEnv); \
  61         return FALSE; \
  62     } \
  63     classRef = (jclass) jniEnv->NewGlobalRef(localClassRef); \
  64     jniEnv->DeleteLocalRef(localClassRef); \
  65     if (classRef == (jclass) 0) { \
  66         PrintDebugString("  Error! FindClass(%s) failed!", className); \
  67         PrintDebugString("    ->  (ran out of RAM)"); \
  68         return FALSE; \
  69     }
  70 
  71 
  72 #define FIND_METHOD(methodID, classRef, methodString, methodSignature); \
  73     methodID = jniEnv->GetMethodID(classRef, methodString,  methodSignature); \
  74     if (methodID == (jmethodID) 0) { \
  75         PrintDebugString("  Error! GetMethodID(%s) failed!", methodString); \
  76         PrintDebugString("    -> jniEnv = %p; classRef = %p", jniEnv, classRef); \
  77         return FALSE; \
  78     }
  79 
  80 #define EXCEPTION_CHECK(situationDescription, returnVal)                                        \
  81     if (exception = jniEnv->ExceptionOccurred()) {                                              \
  82         PrintDebugString("\r\n *** Exception occured while doing: %s; returning %d", situationDescription, returnVal);   \
  83         jniEnv->ExceptionDescribe();                                                            \
  84         jniEnv->ExceptionClear();                                                               \
  85         return (returnVal);                                                                     \
  86     }
  87 
  88 #define EXCEPTION_CHECK_VOID(situationDescription)                                              \
  89     if (exception = jniEnv->ExceptionOccurred()) {                                              \
  90         PrintDebugString("\r\n *** Exception occured while doing: %s", situationDescription);   \
  91         jniEnv->ExceptionDescribe();                                                            \
  92         jniEnv->ExceptionClear();                                                               \
  93         return;                                                                                 \
  94     }
  95 
  96 /**
  97  * Make all of the getClass() & getMethod() calls
  98  *
  99  */
 100 BOOL
 101 AccessBridgeJavaEntryPoints::BuildJavaEntryPoints() {
 102     jclass localClassRef;
 103 
 104     PrintDebugString("Calling BuildJavaEntryPoints():");
 105 
 106     FIND_CLASS(bridgeClass, "com/sun/java/accessibility/internal/AccessBridge");
 107 
 108     // ------- general methods
 109 
 110     // GetMethodID(decrementReference)
 111     FIND_METHOD(decrementReferenceMethod, bridgeClass,
 112                 "decrementReference",
 113                 "(Ljava/lang/Object;)V");
 114 
 115     // GetMethodID(getJavaVersionPropertyMethod)
 116     FIND_METHOD(getJavaVersionPropertyMethod, bridgeClass,
 117                 "getJavaVersionProperty",
 118                 "()Ljava/lang/String;");
 119 
 120     // ------- Window methods
 121 
 122     // GetMethodID(isJavaWindow)
 123     FIND_METHOD(isJavaWindowMethod, bridgeClass,
 124                 "isJavaWindow",


 863 //
 864 // Solution:
 865 // Cast the JOBJECT64 to a jobject.  For a 64 bit compile this is basically
 866 // a noop, i.e. JOBJECT64 is a 64 bit jlong and a jobject is a 64 bit reference.
 867 // For a 32 bit compile the cast drops the high order 32 bits, i.e. JOBJECT64
 868 // is a 64 bit jlong and jobject is a 32 bit reference.  For a Legacy build
 869 // JOBJECT64 is a jobject so this is also basically a noop.  The casts are
 870 // done in the methods in JavaAccessBridge::processPackage.
 871 
 872 // -----------------------------------
 873 
 874 /**
 875  * isJavaWindow - returns whether the HWND is a Java window or not
 876  *
 877  */
 878 BOOL
 879 AccessBridgeJavaEntryPoints::isJavaWindow(jint window) {
 880     jthrowable exception;
 881     BOOL returnVal;
 882 
 883     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::isJavaWindow(%X):", window);
 884 
 885     if (isJavaWindowMethod != (jmethodID) 0) {
 886         returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, isJavaWindowMethod, window);
 887         EXCEPTION_CHECK("Getting isJavaWindow - call to CallBooleanMethod()", FALSE);
 888         return returnVal;
 889     } else {
 890         PrintDebugString("\r\n  Error! either jniEnv == 0 or isJavaWindowMethod == 0");
 891         return FALSE;
 892     }
 893 }
 894 
 895 // -----------------------------------
 896 
 897 /**
 898  * isSameObject - returns whether two object reference refer to the same object
 899  *
 900  */
 901 BOOL
 902 AccessBridgeJavaEntryPoints::isSameObject(jobject obj1, jobject obj2) {
 903     jthrowable exception;
 904     BOOL returnVal;
 905 
 906     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::isSameObject(%p %p):", obj1, obj2);
 907 
 908     returnVal = (BOOL) jniEnv->IsSameObject((jobject)obj1, (jobject)obj2);
 909     EXCEPTION_CHECK("Calling IsSameObject", FALSE);
 910 
 911     PrintDebugString("\r\n  isSameObject returning %d", returnVal);
 912     return returnVal;
 913 }
 914 
 915 // -----------------------------------
 916 
 917 /**
 918  * getAccessibleContextFromHWND - returns the AccessibleContext, if any, for an HWND
 919  *
 920  */
 921 jobject
 922 AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(jint window) {
 923     jobject returnedAccessibleContext;
 924     jobject globalRef;
 925     jthrowable exception;
 926 
 927     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(%X):", window);
 928 
 929     if (getAccessibleContextFromHWNDMethod != (jmethodID) 0) {
 930         returnedAccessibleContext =
 931             (jobject)jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleContextFromHWNDMethod,
 932                                               window);
 933         EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0);
 934         globalRef = (jobject)jniEnv->NewGlobalRef((jobject)returnedAccessibleContext);
 935         EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0);
 936         return globalRef;
 937     } else {
 938         PrintDebugString("\r\n  Error! either jniEnv == 0 or getAccessibleContextFromHWNDMethod == 0");
 939         return (jobject) 0;
 940     }
 941 }
 942 
 943 // -----------------------------------
 944 
 945 /**
 946  * getHWNDFromAccessibleContext - returns the HWND for an AccessibleContext, if any
 947  *      returns (HWND)0 on error.
 948  */
 949 HWND
 950 AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(jobject accessibleContext) {
 951     jthrowable exception;
 952     HWND rHWND;
 953 
 954     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(%X):",
 955                      accessibleContext);
 956 
 957     if (getHWNDFromAccessibleContextMethod != (jmethodID) 0) {
 958         rHWND = (HWND)jniEnv->CallIntMethod(accessBridgeObject, getHWNDFromAccessibleContextMethod,
 959                                             accessibleContext);
 960         EXCEPTION_CHECK("Getting HWNDFromAccessibleContext - call to CallIntMethod()", (HWND)0);
 961         PrintDebugString("\r\n    rHWND = %X", rHWND);
 962         return rHWND;
 963     } else {
 964         PrintDebugString("\r\n  Error! either jniEnv == 0 or getHWNDFromAccessibleContextMethod == 0");
 965         return (HWND)0;
 966     }
 967 }
 968 
 969 
 970 /* ====== Utility methods ===== */
 971 
 972 /**
 973  * Sets a text field to the specified string.  Returns whether successful;
 974  */
 975 BOOL
 976 AccessBridgeJavaEntryPoints::setTextContents(const jobject accessibleContext, const wchar_t *text) {
 977     jthrowable exception;
 978     BOOL result = FALSE;
 979 
 980     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::setTextContents(%p, %ls):",
 981                      accessibleContext, text);
 982 
 983     if (setTextContentsMethod != (jmethodID) 0) {
 984 
 985         // create a Java String for the text
 986         jstring textString = jniEnv->NewString(text, (jsize)wcslen(text));
 987         if (textString == 0) {
 988             PrintDebugString("\r    NewString failed");
 989             return FALSE;
 990         }
 991 
 992         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
 993                                                  setTextContentsMethod,
 994                                                  accessibleContext, textString);
 995         EXCEPTION_CHECK("setTextContents - call to CallBooleanMethod()", FALSE);
 996         PrintDebugString("\r\n    result = %d", result);
 997         return result;
 998     } else {
 999         PrintDebugString("\r\n  Error! either jniEnv == 0 or setTextContentsMethod == 0");
1000         return result;
1001     }
1002 }
1003 
1004 /**
1005  * Returns the Accessible Context of a Page Tab object that is the
1006  * ancestor of a given object.  If the object is a Page Tab object
1007  * or a Page Tab ancestor object was found, returns the object
1008  * AccessibleContext.
1009  * If there is no ancestor object that has an Accessible Role of Page Tab,
1010  * returns (AccessibleContext)0.
1011  */
1012 jobject
1013 AccessBridgeJavaEntryPoints::getParentWithRole(const jobject accessibleContext, const wchar_t *role) {
1014     jthrowable exception;
1015     jobject rAccessibleContext;
1016 
1017     PrintDebugString("In AccessBridgeJavaEntryPoints::getParentWithRole(%p):",
1018                      accessibleContext);
1019 
1020     if (getParentWithRoleMethod != (jmethodID) 0) {
1021         // create a Java String for the role
1022         jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role));
1023         if (roleName == 0) {
1024             PrintDebugString("    NewString failed");
1025             return FALSE;
1026         }
1027 
1028         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1029                                                       getParentWithRoleMethod,
1030                                                       accessibleContext, roleName);
1031         EXCEPTION_CHECK("Getting ParentWithRole - call to CallObjectMethod()", (AccessibleContext)0);
1032         PrintDebugString("    rAccessibleContext = %p", rAccessibleContext);
1033         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1034         EXCEPTION_CHECK("Getting ParentWithRole - call to NewGlobalRef()", FALSE);
1035         PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
1036                          rAccessibleContext, globalRef);
1037         return globalRef;
1038     } else {
1039         PrintDebugString("\r\n  Error! either jniEnv == 0 or getParentWithRoleMethod == 0");
1040         return 0;
1041     }
1042 }
1043 
1044 /**
1045  * Returns the Accessible Context for the top level object in
1046  * a Java Window.  This is same Accessible Context that is obtained
1047  * from GetAccessibleContextFromHWND for that window.  Returns
1048  * (AccessibleContext)0 on error.
1049  */
1050 jobject
1051 AccessBridgeJavaEntryPoints::getTopLevelObject(const jobject accessibleContext) {
1052     jthrowable exception;
1053     jobject rAccessibleContext;
1054 
1055     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getTopLevelObject(%p):",
1056                      accessibleContext);
1057 
1058     if (getTopLevelObjectMethod != (jmethodID) 0) {
1059         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1060                                                       getTopLevelObjectMethod,
1061                                                       accessibleContext);
1062         EXCEPTION_CHECK("Getting TopLevelObject - call to CallObjectMethod()", FALSE);
1063         PrintDebugString("\r\n    rAccessibleContext = %p", rAccessibleContext);
1064         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1065         EXCEPTION_CHECK("Getting TopLevelObject - call to NewGlobalRef()", FALSE);
1066         PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
1067                          rAccessibleContext, globalRef);
1068         return globalRef;
1069     } else {
1070         PrintDebugString("\r\n  Error! either jniEnv == 0 or getTopLevelObjectMethod == 0");
1071         return 0;
1072     }
1073 }
1074 
1075 /**
1076  * If there is an Ancestor object that has an Accessible Role of
1077  * Internal Frame, returns the Accessible Context of the Internal
1078  * Frame object.  Otherwise, returns the top level object for that
1079  * Java Window.  Returns (AccessibleContext)0 on error.
1080  */
1081 jobject
1082 AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(const jobject accessibleContext, const wchar_t *role) {
1083     jthrowable exception;
1084     jobject rAccessibleContext;
1085 
1086     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(%p):",
1087                      accessibleContext);
1088 
1089     if (getParentWithRoleElseRootMethod != (jmethodID) 0) {
1090 
1091         // create a Java String for the role
1092         jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role));
1093         if (roleName == 0) {
1094             PrintDebugString("\r    NewString failed");
1095             return FALSE;
1096         }
1097 
1098         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1099                                                       getParentWithRoleElseRootMethod,
1100                                                       accessibleContext, roleName);
1101         EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to CallObjectMethod()", (AccessibleContext)0);
1102         PrintDebugString("    rAccessibleContext = %p", rAccessibleContext);
1103         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1104         EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to NewGlobalRef()", FALSE);
1105         PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
1106                          rAccessibleContext, globalRef);
1107         return globalRef;
1108     } else {
1109         PrintDebugString("\r\n  Error! either jniEnv == 0 or getParentWithRoleElseRootMethod == 0");
1110         return 0;
1111     }
1112 }
1113 
1114 /**
1115  * Returns how deep in the object hierarchy a given object is.
1116  * The top most object in the object hierarchy has an object depth of 0.
1117  * Returns -1 on error.
1118  */
1119 jint
1120 AccessBridgeJavaEntryPoints::getObjectDepth(const jobject accessibleContext) {
1121     jthrowable exception;
1122     jint rResult;
1123 
1124     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getObjectDepth(%p):",
1125                      accessibleContext);
1126 
1127     if (getObjectDepthMethod != (jmethodID) 0) {
1128         rResult = jniEnv->CallIntMethod(accessBridgeObject,
1129                                         getObjectDepthMethod,
1130                                         accessibleContext);
1131         EXCEPTION_CHECK("Getting ObjectDepth - call to CallIntMethod()", -1);
1132         PrintDebugString("\r\n    rResult = %d", rResult);
1133         return rResult;
1134     } else {
1135         PrintDebugString("\r\n  Error! either jniEnv == 0 or getObjectDepthMethod == 0");
1136         return -1;
1137     }
1138 }
1139 
1140 
1141 
1142 /**
1143  * Returns the Accessible Context of the current ActiveDescendent of an object.
1144  * Returns 0 on error.
1145  */
1146 jobject
1147 AccessBridgeJavaEntryPoints::getActiveDescendent(const jobject accessibleContext) {
1148     jthrowable exception;
1149     jobject rAccessibleContext;
1150 
1151     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getActiveDescendent(%p):",
1152                      accessibleContext);
1153 
1154     if (getActiveDescendentMethod != (jmethodID) 0) {
1155         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1156                                                       getActiveDescendentMethod,
1157                                                       accessibleContext);
1158         EXCEPTION_CHECK("Getting ActiveDescendent - call to CallObjectMethod()", (AccessibleContext)0);
1159         PrintDebugString("\r\n    rAccessibleContext = %p", rAccessibleContext);
1160         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1161         EXCEPTION_CHECK("Getting ActiveDescendant - call to NewGlobalRef()", FALSE);
1162         PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
1163                          rAccessibleContext, globalRef);
1164         return globalRef;
1165     } else {
1166         PrintDebugString("\r\n  Error! either jniEnv == 0 or getActiveDescendentMethod == 0");
1167         return (AccessibleContext)0;
1168     }
1169 }
1170 
1171 /**
1172  * Additional methods for Teton
1173  */
1174 
1175 /**
1176  * Returns an AccessibleName for a component using an algorithm optimized
1177  * for the JAWS screen reader by Ben Key (Freedom Scientific).  This method
1178  * is only intended for JAWS. All other uses are entirely optional.
1179  *
1180  * Bug ID 4916682 - Implement JAWS AccessibleName policy
1181  */
1182 BOOL
1183 AccessBridgeJavaEntryPoints::getVirtualAccessibleName (
1184     IN const jobject object,
1185     OUT wchar_t * name,
1186     IN const int nameSize)
1187 {
1188     /*
1189       +
1190       Parameter validation
1191       +
1192     */
1193     if ((name == 0) || (nameSize == 0))
1194     {
1195         return FALSE;
1196     }
1197     ::memset (name, 0, nameSize * sizeof (wchar_t));
1198     if (0 == object)
1199     {
1200         return FALSE;
1201     }
1202 
1203     jstring js = NULL;
1204     const wchar_t * stringBytes = NULL;
1205     jthrowable exception = NULL;
1206     jsize length = 0;
1207     PrintDebugString("\r\n  getVirtualAccessibleName called.");
1208     if (getVirtualAccessibleNameFromContextMethod != (jmethodID) 0)
1209     {
1210         js = (jstring) jniEnv->CallObjectMethod (
1211             accessBridgeObject,
1212             getVirtualAccessibleNameFromContextMethod,
1213             object);
1214         EXCEPTION_CHECK("Getting AccessibleName - call to CallObjectMethod()", FALSE);
1215         if (js != (jstring) 0)
1216         {
1217             stringBytes = (const wchar_t *) jniEnv->GetStringChars (js, 0);
1218             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE);
1219             wcsncpy(name, stringBytes, nameSize - 1);
1220             length = jniEnv->GetStringLength(js);
1221             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE);
1222             jniEnv->ReleaseStringChars(js, stringBytes);
1223             EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE);
1224             jniEnv->CallVoidMethod (
1225                 accessBridgeObject,
1226                 decrementReferenceMethod, js);
1227             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
1228             wPrintDebugString(L"  Accessible Name = %ls", name);
1229             jniEnv->DeleteLocalRef(js);
1230             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
1231         }
1232         else
1233         {
1234             PrintDebugString("  Accessible Name is null.");
1235         }
1236     }
1237     else
1238     {
1239         PrintDebugString("\r\n  Error! either jniEnv == 0 or getVirtualAccessibleNameFromContextMethod == 0");
1240         return FALSE;
1241     }
1242     if ( 0 != name [0] )
1243     {
1244         return TRUE;
1245     }
1246     return FALSE;
1247 }
1248 
1249 
1250 /**
1251  * Request focus for a component. Returns whether successful;
1252  *
1253  * Bug ID 4944757 - requestFocus method needed
1254  */
1255 BOOL
1256 AccessBridgeJavaEntryPoints::requestFocus(const jobject accessibleContext) {
1257 
1258     jthrowable exception;
1259     BOOL result = FALSE;
1260 
1261     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::requestFocus(%p):",
1262                      accessibleContext);
1263 
1264     if (requestFocusMethod != (jmethodID) 0) {
1265         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
1266                                                  requestFocusMethod,
1267                                                  accessibleContext);
1268         EXCEPTION_CHECK("requestFocus - call to CallBooleanMethod()", FALSE);
1269         PrintDebugString("\r\n    result = %d", result);
1270         return result;
1271     } else {
1272         PrintDebugString("\r\n  Error! either jniEnv == 0 or requestFocusMethod == 0");
1273         return result;
1274     }
1275 }
1276 
1277 /**
1278  * Selects text between two indices.  Selection includes the text at the start index
1279  * and the text at the end index. Returns whether successful;
1280  *
1281  * Bug ID 4944758 - selectTextRange method needed
1282  */
1283 BOOL
1284 AccessBridgeJavaEntryPoints::selectTextRange(const jobject accessibleContext, int startIndex, int endIndex) {
1285 
1286     jthrowable exception;
1287     BOOL result = FALSE;
1288 
1289     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::selectTextRange(%p start = %d end = %d):",
1290                      accessibleContext, startIndex, endIndex);
1291 
1292     if (selectTextRangeMethod != (jmethodID) 0) {
1293         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
1294                                                  selectTextRangeMethod,
1295                                                  accessibleContext,
1296                                                  startIndex, endIndex);
1297         EXCEPTION_CHECK("selectTextRange - call to CallBooleanMethod()", FALSE);
1298         PrintDebugString("\r\n    result = %d", result);
1299         return result;
1300     } else {
1301         PrintDebugString("\r\n  Error! either jniEnv == 0 or selectTextRangeMethod == 0");
1302         return result;
1303     }
1304 }
1305 
1306 /*
1307  * Returns whether two text attributes are the same.
1308  */
1309 static BOOL CompareAccessibleTextAttributesInfo(AccessibleTextAttributesInfo *one,
1310                                                 AccessibleTextAttributesInfo *two) {
1311     return(one->bold == two->bold
1312            && one->italic == two->italic
1313            && one->underline == two->underline
1314            && one->strikethrough == two->strikethrough
1315            && one->superscript == two->superscript
1316            && one->subscript == two->subscript
1317            && one->fontSize == two->fontSize
1318            && one->alignment == two->alignment
1319            && one->bidiLevel == two->bidiLevel
1320            && one->firstLineIndent == two->firstLineIndent
1321            && one->leftIndent == two->leftIndent


1338  * parameter len the number of characters with the attributes returned. In most
1339  * situations this will be all the characters, and if not the calling program
1340  * can easily get the attributes for the next characters with different
1341  * attributes
1342  *
1343  * Bug ID 4944761 - getTextAttributes between two indices method needed
1344  */
1345 
1346 /* NEW FASTER CODE!!*/
1347 BOOL
1348 AccessBridgeJavaEntryPoints::getTextAttributesInRange(const jobject accessibleContext,
1349                                                       int startIndex, int endIndex,
1350                                                       AccessibleTextAttributesInfo *attributes, short *len) {
1351 
1352     jstring js;
1353     const wchar_t *stringBytes;
1354     jthrowable exception;
1355     jsize length;
1356     BOOL result = FALSE;
1357 
1358     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getTextAttributesInRange(%p start = %d end = %d):",
1359                      accessibleContext, startIndex, endIndex);
1360 
1361     *len = 0;
1362     result = getAccessibleTextAttributes((jobject)accessibleContext, startIndex, attributes);
1363     if (result != TRUE) {
1364         return FALSE;
1365     }
1366     (*len)++;
1367 
1368     for (jint i = startIndex+1; i <= endIndex; i++) {
1369 
1370         AccessibleTextAttributesInfo test_attributes = *attributes;
1371         // Get the full test_attributes string at i
1372         if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) {
1373             PrintDebugString(" Getting full test_attributes string from Context...");
1374             js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1375                                                     getAccessibleAttributesAtIndexFromContextMethod,
1376                                                     accessibleContext, i);
1377             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE);
1378             PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
1379             if (js != (jstring) 0) {
1380                 stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1381                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE);
1382                 wcsncpy(test_attributes.fullAttributesString, stringBytes, (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t)));
1383                 length = jniEnv->GetStringLength(js);
1384                 test_attributes.fullAttributesString[length < (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t)) ?
1385                                                      length : (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0;
1386                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE);
1387                 jniEnv->ReleaseStringChars(js, stringBytes);
1388                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE);
1389                 jniEnv->CallVoidMethod(accessBridgeObject,
1390                                        decrementReferenceMethod, js);
1391                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE);
1392                 wPrintDebugString(L"  Accessible Text attributes = %ls", test_attributes.fullAttributesString);
1393                 jniEnv->DeleteLocalRef(js);
1394                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
1395             } else {
1396                 PrintDebugString("  Accessible Text attributes is null.");
1397                 test_attributes.fullAttributesString[0] = (wchar_t) 0;
1398                 return FALSE;
1399             }
1400         } else {
1401             PrintDebugString("  Error! either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0");
1402             return FALSE;
1403         }
1404 
1405         if(wcscmp(attributes->fullAttributesString,test_attributes.fullAttributesString))
1406             break;
1407         if (result != TRUE) {
1408             return FALSE;
1409         }
1410         (*len)++;
1411     }
1412     return TRUE;
1413 }
1414 
1415 /*
1416  * Returns the number of visible children of a component
1417  *
1418  * Bug ID 4944762- getVisibleChildren for list-like components needed
1419  */
1420 int
1421 AccessBridgeJavaEntryPoints::getVisibleChildrenCount(const jobject accessibleContext) {
1422 
1423     jthrowable exception;
1424     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getVisibleChildrenCount(%p)",
1425                      accessibleContext);
1426 
1427     // get the visible children count
1428     int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod,
1429                                             accessibleContext);
1430     EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE);
1431     PrintDebugString("  ##### visible children count = %d", numChildren);
1432 
1433     return numChildren;
1434 }
1435 
1436 
1437 /*
1438  * This method is used to iterate through the visible children of a component.  It
1439  * returns visible children information for a component starting at nStartIndex.
1440  * No more than MAX_VISIBLE_CHILDREN VisibleChildrenInfo objects will
1441  * be returned for each call to this method. Returns FALSE on error.
1442  *
1443  * Bug ID 4944762- getVisibleChildren for list-like components needed
1444  */
1445 BOOL AccessBridgeJavaEntryPoints::getVisibleChildren(const jobject accessibleContext,
1446                                                      const int nStartIndex,
1447                                                      /* OUT */ VisibleChildrenInfo *visibleChildrenInfo) {
1448 
1449     jthrowable exception;
1450 
1451     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getVisibleChildren(%p, startIndex = %d)",
1452                      accessibleContext, nStartIndex);
1453 
1454     // get the visible children count
1455     int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod,
1456                                             accessibleContext);
1457     EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE);
1458     PrintDebugString("  ##### visible children count = %d", numChildren);
1459 
1460     if (nStartIndex >= numChildren) {
1461         return FALSE;
1462     }
1463 
1464     // get the visible children
1465     int bufIndex = 0;
1466     for (int i = nStartIndex; (i < numChildren) && (i < nStartIndex + MAX_VISIBLE_CHILDREN); i++) {
1467         PrintDebugString("  getting visible child %d ...", i);
1468 
1469         // get the visible child at index i
1470         jobject ac = jniEnv->CallObjectMethod(accessBridgeObject, getVisibleChildMethod,
1471                                               accessibleContext, i);
1472         EXCEPTION_CHECK("##### getVisibleChildMethod - call to CallObjectMethod()", FALSE);
1473         jobject globalRef = jniEnv->NewGlobalRef(ac);
1474         EXCEPTION_CHECK("##### getVisibleChildMethod - call to NewGlobalRef()", FALSE);
1475         visibleChildrenInfo->children[bufIndex] = (JOBJECT64)globalRef;
1476         PrintDebugString("  ##### visible child = %p", globalRef);
1477 
1478         bufIndex++;
1479     }
1480     visibleChildrenInfo->returnedChildrenCount = bufIndex;
1481 
1482     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getVisibleChildren succeeded");
1483     return TRUE;
1484 }
1485 
1486 /**
1487  * Set the caret to a text position. Returns whether successful;
1488  *
1489  * Bug ID 4944770 - setCaretPosition method needed
1490  */
1491 BOOL
1492 AccessBridgeJavaEntryPoints::setCaretPosition(const jobject accessibleContext, int position) {
1493 
1494     jthrowable exception;
1495     BOOL result = FALSE;
1496 
1497     PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::setCaretPostion(%p position = %d):",
1498                      accessibleContext, position);
1499 
1500     if (setCaretPositionMethod != (jmethodID) 0) {
1501         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
1502                                                  setCaretPositionMethod,
1503                                                  accessibleContext, position);
1504         EXCEPTION_CHECK("setCaretPostion - call to CallBooleanMethod()", FALSE);
1505         PrintDebugString("\r\n    result = %d", result);
1506         return result;
1507     } else {
1508         PrintDebugString("\r\n  Error! either jniEnv == 0 or setCaretPositionMethod == 0");
1509         return result;
1510     }
1511 }
1512 
1513 
1514 // -----------------------------------
1515 
1516 /**
1517  * getVersionInfo - returns the version string of the java.version property
1518  *                  and the AccessBridge.java version
1519  *
1520  */
1521 BOOL
1522 AccessBridgeJavaEntryPoints::getVersionInfo(AccessBridgeVersionInfo *info) {
1523     jstring js;
1524     const wchar_t *stringBytes;
1525     jthrowable exception;
1526     jsize length;
1527 
1528     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getVersionInfo():");
1529 
1530     if (getJavaVersionPropertyMethod != (jmethodID) 0) {
1531         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1532                                                 getJavaVersionPropertyMethod);
1533         EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallObjectMethod()", FALSE);
1534         PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
1535         if (js != (jstring) 0) {
1536             length = jniEnv->GetStringLength(js);
1537             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1538             if (stringBytes == NULL) {
1539                 if (!jniEnv->ExceptionCheck()) {
1540                     PrintDebugString("\r\n *** Exception when getting JavaVersionProperty - call to GetStringChars");
1541                     jniEnv->ExceptionDescribe();
1542                     jniEnv->ExceptionClear();
1543                 }
1544                 return FALSE;
1545             }
1546             wcsncpy(info->bridgeJavaDLLVersion,
1547                     stringBytes,
1548                     sizeof(info->bridgeJavaDLLVersion)  / sizeof(wchar_t));
1549             info->bridgeJavaDLLVersion[length < (sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t)) ?
1550                             length : (sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1551             wcsncpy(info->VMversion,
1552                     stringBytes,
1553                     sizeof(info->VMversion)  / sizeof(wchar_t));
1554             info->VMversion[length < (sizeof(info->VMversion) / sizeof(wchar_t)) ?
1555                             length : (sizeof(info->VMversion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1556             wcsncpy(info->bridgeJavaClassVersion,
1557                     stringBytes,
1558                     sizeof(info->bridgeJavaClassVersion)  / sizeof(wchar_t));
1559             info->bridgeJavaClassVersion[length < (sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t)) ?
1560                                          length : (sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1561             wcsncpy(info->bridgeWinDLLVersion,
1562                     stringBytes,
1563                     sizeof(info->bridgeWinDLLVersion)  / sizeof(wchar_t));
1564             info->bridgeWinDLLVersion[length < (sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t)) ?
1565                                          length : (sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1566             jniEnv->ReleaseStringChars(js, stringBytes);
1567             EXCEPTION_CHECK("Getting JavaVersionProperty - call to ReleaseStringChars()", FALSE);
1568             jniEnv->CallVoidMethod(accessBridgeObject,
1569                                    decrementReferenceMethod, js);
1570             EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallVoidMethod()", FALSE);
1571             wPrintDebugString(L"  Java version = %ls", info->VMversion);
1572             jniEnv->DeleteLocalRef(js);
1573             EXCEPTION_CHECK("Getting JavaVersionProperty - call to DeleteLocalRef()", FALSE);
1574         } else {
1575             PrintDebugString("  Java version is null.");
1576             info->VMversion[0] = (wchar_t) 0;
1577             return FALSE;
1578         }
1579     } else {
1580         PrintDebugString("  Error! either env == 0 or getJavaVersionPropertyMethod == 0");
1581         return FALSE;
1582     }
1583 
1584     return TRUE;
1585 }
1586 
1587 
1588 /*
1589  * Verifies the Java VM still exists and obj is an
1590  * instance of AccessibleText
1591  */
1592 BOOL AccessBridgeJavaEntryPoints::verifyAccessibleText(jobject obj) {
1593     JavaVM *vm;
1594     BOOL retval;
1595     jthrowable exception;
1596 
1597     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::verifyAccessibleText");
1598 
1599     if (jniEnv->GetJavaVM(&vm) != 0) {
1600         PrintDebugString("  Error! No Java VM");
1601         return FALSE;
1602     }
1603 
1604     if (obj == (jobject)0) {
1605         PrintDebugString("  Error! Null jobject");
1606         return FALSE;
1607     }
1608 
1609     // Copied from getAccessibleContextInfo
1610     if (getAccessibleTextFromContextMethod != (jmethodID) 0) {
1611         jobject returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
1612                                                            getAccessibleTextFromContextMethod,
1613                                                            (jobject)obj);
1614         EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE);
1615         PrintDebugString("  AccessibleText = %p", returnedJobject);
1616         retval = returnedJobject != (jobject) 0;
1617         jniEnv->DeleteLocalRef(returnedJobject);
1618         EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE);
1619     } else {
1620         PrintDebugString("  Error! either env == 0 or getAccessibleTextFromContextMethod == 0");
1621         return FALSE;
1622     }
1623     if (retval == FALSE) {
1624         PrintDebugString("  Error! jobject is not an AccessibleText");
1625     }
1626     return retval;
1627 }
1628 
1629 
1630 /********** AccessibleContext routines ***********************************/
1631 
1632 /**
1633  * getAccessibleContextAt - performs the Java method call:
1634  *   Accessible AccessBridge.getAccessibleContextAt(x, y)
1635  *
1636  * Note: this call explicitly goes through the AccessBridge,
1637  * so that it can keep a reference the returned jobject for the JavaVM.
1638  * You must explicity call INTreleaseJavaObject() when you are through using
1639  * the Accessible returned, to let the AccessBridge know it can release the
1640  * object, so that the can then garbage collect it.
1641  *
1642  */
1643 jobject
1644 AccessBridgeJavaEntryPoints::getAccessibleContextAt(jint x, jint y, jobject accessibleContext) {
1645     jobject returnedAccessibleContext;
1646     jobject globalRef;
1647     jthrowable exception;
1648 
1649     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleContextAt(%d, %d, %p):",
1650                      x, y, accessibleContext);
1651 
1652     if (getAccessibleContextAtMethod != (jmethodID) 0) {
1653         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1654                                                              getAccessibleContextAtMethod,
1655                                                              x, y, accessibleContext);
1656         EXCEPTION_CHECK("Getting AccessibleContextAt - call to CallObjectMethod()", FALSE);
1657         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
1658         EXCEPTION_CHECK("Getting AccessibleContextAt - call to NewGlobalRef()", FALSE);
1659         PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
1660                          returnedAccessibleContext, globalRef);
1661         return globalRef;
1662     } else {
1663         PrintDebugString("  Error! either env == 0 or getAccessibleContextAtMethod == 0");
1664         return (jobject) 0;
1665     }
1666 }
1667 
1668 /**
1669  * getAccessibleWithFocus - performs the Java method calls:
1670  *   Accessible Translator.getAccessible(SwingEventMonitor.getComponentWithFocus();
1671  *
1672  * Note: this call explicitly goes through the AccessBridge,
1673  * so that the AccessBridge can hide expected changes in how this functions
1674  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1675  * of this functionality may be built into the platform
1676  *
1677  */
1678 jobject
1679 AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus() {
1680     jobject returnedAccessibleContext;
1681     jobject globalRef;
1682     jthrowable exception;
1683 
1684     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus()");
1685 
1686     if (getAccessibleContextWithFocusMethod != (jmethodID) 0) {
1687         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1688                                                              getAccessibleContextWithFocusMethod);
1689         EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to CallObjectMethod()", FALSE);
1690         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
1691         EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to NewGlobalRef()", FALSE);
1692         PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
1693                          returnedAccessibleContext, globalRef);
1694         return globalRef;
1695     } else {
1696         PrintDebugString("  Error! either jniEnv == 0 or getAccessibleContextWithFocusMethod == 0");
1697         return (jobject) 0;
1698     }
1699 }
1700 
1701 /**
1702  * getAccessibleContextInfo - fills a struct with a bunch of information
1703  * contained in the Java Accessibility API
1704  *
1705  * Note: if the AccessibleContext parameter is bogus, this call will blow up
1706  *
1707  * Note: this call explicitly goes through the AccessBridge,
1708  * so that it can keep a reference the returned jobject for the JavaVM.
1709  * You must explicity call releaseJavaObject() when you are through using
1710  * the AccessibleContext returned, to let the AccessBridge know it can release the
1711  * object, so that the JavaVM can then garbage collect it.
1712  */
1713 BOOL
1714 AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, AccessibleContextInfo *info) {
1715     jstring js;
1716     const wchar_t *stringBytes;
1717     jobject returnedJobject;
1718     jthrowable exception;
1719     jsize length;
1720 
1721     PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleContextInfo(%p):", accessibleContext);
1722 
1723     ZeroMemory(info, sizeof(AccessibleContextInfo));
1724 
1725     if (accessibleContext == (jobject) 0) {
1726         PrintDebugString(" passed in AccessibleContext == null! (oops)");
1727         return (FALSE);
1728     }
1729 
1730     // Get the Accessible Name
1731     if (getAccessibleNameFromContextMethod != (jmethodID) 0) {
1732         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1733                                                 getAccessibleNameFromContextMethod,
1734                                                 accessibleContext);
1735         EXCEPTION_CHECK("Getting AccessibleName - call to CallObjectMethod()", FALSE);
1736         if (js != (jstring) 0) {
1737             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1738             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE);
1739             wcsncpy(info->name, stringBytes, (sizeof(info->name) / sizeof(wchar_t)));
1740             length = jniEnv->GetStringLength(js);
1741             info->name[length < (sizeof(info->name) / sizeof(wchar_t)) ?
1742                        length : (sizeof(info->name) / sizeof(wchar_t))-2] = (wchar_t) 0;
1743             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE);
1744             jniEnv->ReleaseStringChars(js, stringBytes);
1745             EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE);
1746             jniEnv->CallVoidMethod(accessBridgeObject,
1747                                    decrementReferenceMethod, js);
1748             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
1749             wPrintDebugString(L"  Accessible Name = %ls", info->name);
1750             jniEnv->DeleteLocalRef(js);
1751             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
1752         } else {
1753             PrintDebugString("  Accessible Name is null.");
1754             info->name[0] = (wchar_t) 0;
1755         }
1756     } else {
1757         PrintDebugString("  Error! either env == 0 or getAccessibleNameFromContextMethod == 0");
1758         return FALSE;
1759     }
1760 
1761 
1762     // Get the Accessible Description
1763     if (getAccessibleDescriptionFromContextMethod != (jmethodID) 0) {
1764         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1765                                                 getAccessibleDescriptionFromContextMethod,
1766                                                 accessibleContext);
1767         EXCEPTION_CHECK("Getting AccessibleDescription - call to CallObjectMethod()", FALSE);
1768         if (js != (jstring) 0) {
1769             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1770             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE);
1771             wcsncpy(info->description, stringBytes, (sizeof(info->description) / sizeof(wchar_t)));
1772             length = jniEnv->GetStringLength(js);
1773             info->description[length < (sizeof(info->description) / sizeof(wchar_t)) ?
1774                               length : (sizeof(info->description) / sizeof(wchar_t))-2] = (wchar_t) 0;
1775             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE);
1776             jniEnv->ReleaseStringChars(js, stringBytes);
1777             EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE);
1778             jniEnv->CallVoidMethod(accessBridgeObject,
1779                                    decrementReferenceMethod, js);
1780             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
1781             wPrintDebugString(L"  Accessible Description = %ls", info->description);
1782             jniEnv->DeleteLocalRef(js);
1783             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
1784         } else {
1785             PrintDebugString("  Accessible Description is null.");
1786             info->description[0] = (wchar_t) 0;
1787         }
1788     } else {
1789         PrintDebugString("  Error! either env == 0 or getAccessibleDescriptionFromContextMethod == 0");
1790         return FALSE;
1791     }
1792 
1793 
1794     // Get the Accessible Role String
1795     if (getAccessibleRoleStringFromContextMethod != (jmethodID) 0) {
1796         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1797                                                 getAccessibleRoleStringFromContextMethod,
1798                                                 accessibleContext);
1799         EXCEPTION_CHECK("Getting AccessibleRole - call to CallObjectMethod()", FALSE);
1800         if (js != (jstring) 0) {
1801             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1802             EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringChars()", FALSE);
1803             wcsncpy(info->role, stringBytes, (sizeof(info->role) / sizeof(wchar_t)));
1804             length = jniEnv->GetStringLength(js);
1805             info->role[length < (sizeof(info->role) / sizeof(wchar_t)) ?
1806                        length : (sizeof(info->role) / sizeof(wchar_t))-2] = (wchar_t) 0;
1807             EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringLength()", FALSE);
1808             jniEnv->ReleaseStringChars(js, stringBytes);
1809             EXCEPTION_CHECK("Getting AccessibleRole - call to ReleaseStringChars()", FALSE);
1810             jniEnv->CallVoidMethod(accessBridgeObject,
1811                                    decrementReferenceMethod, js);
1812             EXCEPTION_CHECK("Getting AccessibleRole - call to CallVoidMethod()", FALSE);
1813             wPrintDebugString(L"  Accessible Role = %ls", info->role);
1814             jniEnv->DeleteLocalRef(js);
1815             EXCEPTION_CHECK("Getting AccessibleRole - call to DeleteLocalRef()", FALSE);
1816         } else {
1817             PrintDebugString("  Accessible Role is null.");
1818             info->role[0] = (wchar_t) 0;
1819         }
1820     } else {
1821         PrintDebugString("  Error! either env == 0 or getAccessibleRoleStringFromContextMethod == 0");
1822         return FALSE;
1823     }
1824 
1825 
1826     // Get the Accessible Role String in the en_US locale
1827     if (getAccessibleRoleStringFromContext_en_USMethod != (jmethodID) 0) {
1828         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1829                                                 getAccessibleRoleStringFromContext_en_USMethod,
1830                                                 accessibleContext);
1831         EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallObjectMethod()", FALSE);
1832         if (js != (jstring) 0) {
1833             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1834             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringChars()", FALSE);
1835             wcsncpy(info->role_en_US, stringBytes, (sizeof(info->role_en_US) / sizeof(wchar_t)));
1836             length = jniEnv->GetStringLength(js);
1837             info->role_en_US[length < (sizeof(info->role_en_US) / sizeof(wchar_t)) ?
1838                              length : (sizeof(info->role_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0;
1839             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringLength()", FALSE);
1840             jniEnv->ReleaseStringChars(js, stringBytes);
1841             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to ReleaseStringChars()", FALSE);
1842             jniEnv->CallVoidMethod(accessBridgeObject,
1843                                    decrementReferenceMethod, js);
1844             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallVoidMethod()", FALSE);
1845             wPrintDebugString(L"  Accessible Role en_US = %ls", info->role_en_US);
1846             jniEnv->DeleteLocalRef(js);
1847             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to DeleteLocalRef()", FALSE);
1848         } else {
1849             PrintDebugString("  Accessible Role en_US is null.");
1850             info->role[0] = (wchar_t) 0;
1851         }
1852     } else {
1853         PrintDebugString("  Error! either env == 0 or getAccessibleRoleStringFromContext_en_USMethod == 0");
1854         return FALSE;
1855     }
1856 
1857     // Get the Accessible States String
1858     if (getAccessibleStatesStringFromContextMethod != (jmethodID) 0) {
1859         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1860                                                 getAccessibleStatesStringFromContextMethod,
1861                                                 accessibleContext);
1862         EXCEPTION_CHECK("Getting AccessibleState - call to CallObjectMethod()", FALSE);
1863         if (js != (jstring) 0) {
1864             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1865             EXCEPTION_CHECK("Getting AccessibleState - call to GetStringChars()", FALSE);
1866             wcsncpy(info->states, stringBytes, (sizeof(info->states) / sizeof(wchar_t)));
1867             length = jniEnv->GetStringLength(js);
1868             info->states[length < (sizeof(info->states) / sizeof(wchar_t)) ?
1869                          length : (sizeof(info->states) / sizeof(wchar_t))-2] = (wchar_t) 0;
1870             EXCEPTION_CHECK("Getting AccessibleState - call to GetStringLength()", FALSE);
1871             jniEnv->ReleaseStringChars(js, stringBytes);
1872             EXCEPTION_CHECK("Getting AccessibleState - call to ReleaseStringChars()", FALSE);
1873             jniEnv->CallVoidMethod(accessBridgeObject,
1874                                    decrementReferenceMethod, js);
1875             EXCEPTION_CHECK("Getting AccessibleState - call to CallVoidMethod()", FALSE);
1876             wPrintDebugString(L"  Accessible States = %ls", info->states);
1877             jniEnv->DeleteLocalRef(js);
1878             EXCEPTION_CHECK("Getting AccessibleState - call to DeleteLocalRef()", FALSE);
1879         } else {
1880             PrintDebugString("  Accessible States is null.");
1881             info->states[0] = (wchar_t) 0;
1882         }
1883     } else {
1884         PrintDebugString("  Error! either env == 0 or getAccessibleStatesStringFromContextMethod == 0");
1885         return FALSE;
1886     }
1887 
1888     // Get the Accessible States String in the en_US locale
1889     if (getAccessibleStatesStringFromContext_en_USMethod != (jmethodID) 0) {
1890         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1891                                                 getAccessibleStatesStringFromContext_en_USMethod,
1892                                                 accessibleContext);
1893         EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallObjectMethod()", FALSE);
1894         if (js != (jstring) 0) {
1895             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1896             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringChars()", FALSE);
1897             wcsncpy(info->states_en_US, stringBytes, (sizeof(info->states_en_US) / sizeof(wchar_t)));
1898             length = jniEnv->GetStringLength(js);
1899             info->states_en_US[length < (sizeof(info->states_en_US) / sizeof(wchar_t)) ?
1900                                length : (sizeof(info->states_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0;
1901             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringLength()", FALSE);
1902             jniEnv->ReleaseStringChars(js, stringBytes);
1903             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to ReleaseStringChars()", FALSE);
1904             jniEnv->CallVoidMethod(accessBridgeObject,
1905                                    decrementReferenceMethod, js);
1906             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallVoidMethod()", FALSE);
1907             wPrintDebugString(L"  Accessible States en_US = %ls", info->states_en_US);
1908             jniEnv->DeleteLocalRef(js);
1909             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to DeleteLocalRef()", FALSE);
1910         } else {
1911             PrintDebugString("  Accessible States en_US is null.");
1912             info->states[0] = (wchar_t) 0;
1913         }
1914     } else {
1915         PrintDebugString("  Error! either env == 0 or getAccessibleStatesStringFromContext_en_USMethod == 0");
1916         return FALSE;
1917     }
1918 
1919 
1920     // Get the index in Parent
1921     if (getAccessibleIndexInParentFromContextMethod != (jmethodID) 0) {
1922         info->indexInParent = jniEnv->CallIntMethod(accessBridgeObject,
1923                                                     getAccessibleIndexInParentFromContextMethod,
1924                                                     accessibleContext);
1925         EXCEPTION_CHECK("Getting AccessibleIndexInParent - call to CallIntMethod()", FALSE);
1926         PrintDebugString("  Index in Parent = %d", info->indexInParent);
1927     } else {
1928         PrintDebugString("  Error! either env == 0 or getAccessibleIndexInParentFromContextMethod == 0");
1929         return FALSE;
1930     }
1931 
1932 
1933     PrintDebugString("*** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %p ***",
1934                      jniEnv, accessBridgeObject, accessibleContext);
1935 
1936     // Get the children count
1937     if (getAccessibleChildrenCountFromContextMethod != (jmethodID) 0) {
1938         info->childrenCount = jniEnv->CallIntMethod(accessBridgeObject,
1939                                                     getAccessibleChildrenCountFromContextMethod,
1940                                                     accessibleContext);
1941         EXCEPTION_CHECK("Getting AccessibleChildrenCount - call to CallIntMethod()", FALSE);
1942         PrintDebugString("  Children count = %d", info->childrenCount);
1943     } else {
1944         PrintDebugString("  Error! either env == 0 or getAccessibleChildrenCountFromContextMethod == 0");
1945         return FALSE;
1946     }
1947 
1948     PrintDebugString("*** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %X ***",
1949                      jniEnv, accessBridgeObject, accessibleContext);
1950 
1951 
1952     // Get the x coord
1953     if (getAccessibleXcoordFromContextMethod != (jmethodID) 0) {
1954         info->x = jniEnv->CallIntMethod(accessBridgeObject,
1955                                         getAccessibleXcoordFromContextMethod,
1956                                         accessibleContext);
1957         EXCEPTION_CHECK("Getting AccessibleXcoord - call to CallIntMethod()", FALSE);
1958         PrintDebugString("  X coord = %d", info->x);
1959     } else {
1960         PrintDebugString("  Error! either env == 0 or getAccessibleXcoordFromContextMethod == 0");
1961         return FALSE;
1962     }
1963 
1964     PrintDebugString("*** jniEnv: %X; accessBridgeObject: %X; AccessibleContext: %p ***",
1965                      jniEnv, accessBridgeObject, accessibleContext);
1966 
1967 
1968     // Get the y coord
1969     if (getAccessibleYcoordFromContextMethod != (jmethodID) 0) {
1970         info->y = jniEnv->CallIntMethod(accessBridgeObject,
1971                                         getAccessibleYcoordFromContextMethod,
1972                                         accessibleContext);
1973         EXCEPTION_CHECK("Getting AccessibleYcoord - call to CallIntMethod()", FALSE);
1974         PrintDebugString("  Y coord = %d", info->y);
1975     } else {
1976         PrintDebugString("  Error! either env == 0 or getAccessibleYcoordFromContextMethod == 0");
1977         return FALSE;
1978     }
1979 
1980     // Get the width
1981     if (getAccessibleWidthFromContextMethod != (jmethodID) 0) {
1982         info->width = jniEnv->CallIntMethod(accessBridgeObject,
1983                                             getAccessibleWidthFromContextMethod,
1984                                             accessibleContext);
1985         EXCEPTION_CHECK("Getting AccessibleWidth - call to CallIntMethod()", FALSE);
1986         PrintDebugString("  Width = %d", info->width);
1987     } else {
1988         PrintDebugString("  Error! either env == 0 or getAccessibleWidthFromContextMethod == 0");
1989         return FALSE;
1990     }
1991 
1992     // Get the height
1993     if (getAccessibleHeightFromContextMethod != (jmethodID) 0) {
1994         info->height = jniEnv->CallIntMethod(accessBridgeObject,
1995                                              getAccessibleHeightFromContextMethod,
1996                                              accessibleContext);
1997         EXCEPTION_CHECK("Getting AccessibleHeight - call to CallIntMethod()", FALSE);
1998         PrintDebugString("  Height = %d", info->height);
1999     } else {
2000         PrintDebugString("  Error! either env == 0 or getAccessibleHeightFromContextMethod == 0");
2001         return FALSE;
2002     }
2003 
2004     // Get the AccessibleComponent
2005     if (getAccessibleComponentFromContextMethod != (jmethodID) 0) {
2006         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2007                                                    getAccessibleComponentFromContextMethod,
2008                                                    accessibleContext);
2009         EXCEPTION_CHECK("Getting AccessibleComponent - call to CallObjectMethod()", FALSE);
2010         PrintDebugString("  AccessibleComponent = %p", returnedJobject);
2011         info->accessibleComponent = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2012         jniEnv->DeleteLocalRef(returnedJobject);
2013         EXCEPTION_CHECK("Getting AccessibleComponent - call to DeleteLocalRef()", FALSE);
2014     } else {
2015         PrintDebugString("  Error! either env == 0 or getAccessibleComponentFromContextMethod == 0");
2016         return FALSE;
2017     }
2018 
2019     // Get the AccessibleAction
2020     if (getAccessibleActionFromContextMethod != (jmethodID) 0) {
2021         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2022                                                    getAccessibleActionFromContextMethod,
2023                                                    accessibleContext);
2024         EXCEPTION_CHECK("Getting AccessibleAction - call to CallObjectMethod()", FALSE);
2025         PrintDebugString("  AccessibleAction = %p", returnedJobject);
2026         info->accessibleAction = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2027         jniEnv->DeleteLocalRef(returnedJobject);
2028         EXCEPTION_CHECK("Getting AccessibleAction - call to DeleteLocalRef()", FALSE);
2029     } else {
2030         PrintDebugString("  Error! either env == 0 or getAccessibleActionFromContextMethod == 0");
2031         return FALSE;
2032     }
2033 
2034     // Get the AccessibleSelection
2035     if (getAccessibleSelectionFromContextMethod != (jmethodID) 0) {
2036         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2037                                                    getAccessibleSelectionFromContextMethod,
2038                                                    accessibleContext);
2039         EXCEPTION_CHECK("Getting AccessibleSelection - call to CallObjectMethod()", FALSE);
2040         PrintDebugString("  AccessibleSelection = %p", returnedJobject);
2041         info->accessibleSelection = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2042         jniEnv->DeleteLocalRef(returnedJobject);
2043         EXCEPTION_CHECK("Getting AccessibleSelection - call to DeleteLocalRef()", FALSE);
2044     } else {
2045         PrintDebugString("  Error! either env == 0 or getAccessibleSelectionFromContextMethod == 0");
2046         return FALSE;
2047     }
2048 
2049     // Get the AccessibleTable
2050     if (getAccessibleTableFromContextMethod != (jmethodID) 0) {
2051         PrintDebugString("##### Calling getAccessibleTableFromContextMethod ...");
2052         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2053                                                    getAccessibleTableFromContextMethod,
2054                                                    accessibleContext);
2055         PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod");
2056         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2057         PrintDebugString("  ##### AccessibleTable = %p", returnedJobject);
2058         if (returnedJobject != (jobject) 0) {
2059             info->accessibleInterfaces |= cAccessibleTableInterface;
2060         }
2061         jniEnv->DeleteLocalRef(returnedJobject);
2062         EXCEPTION_CHECK("##### Getting AccessibleTable - call to DeleteLocalRef()", FALSE);
2063 
2064         /*
2065           returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2066           getAccessibleTableFromContextMethod,
2067           AccessibleContext);
2068           PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod");
2069           EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2070           PrintDebugString("  ##### AccessibleTable = %X", returnedJobject);
2071           info->accessibleTable = returnedJobject;
2072         */
2073 
2074     } else {
2075         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableFromContextMethod == 0");
2076         return FALSE;
2077     }
2078 
2079     // Get the AccessibleText
2080     if (getAccessibleTextFromContextMethod != (jmethodID) 0) {
2081         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2082                                                    getAccessibleTextFromContextMethod,
2083                                                    accessibleContext);
2084         EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE);
2085         PrintDebugString("  AccessibleText = %p", returnedJobject);
2086         info->accessibleText = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2087         jniEnv->DeleteLocalRef(returnedJobject);
2088         EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE);
2089     } else {
2090         PrintDebugString("  Error! either env == 0 or getAccessibleTextFromContextMethod == 0");
2091         return FALSE;
2092     }
2093 
2094     // Get the AccessibleValue
2095     if (getAccessibleValueFromContextMethod != (jmethodID) 0) {
2096         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2097                                                    getAccessibleValueFromContextMethod,
2098                                                    accessibleContext);
2099         EXCEPTION_CHECK("Getting AccessibleValue - call to CallObjectMethod()", FALSE);
2100         PrintDebugString("  AccessibleValue = %p", returnedJobject);
2101         if (returnedJobject != (jobject) 0) {
2102             info->accessibleInterfaces |= cAccessibleValueInterface;
2103         }
2104         jniEnv->DeleteLocalRef(returnedJobject);
2105         EXCEPTION_CHECK("Getting AccessibleValue - call to DeleteLocalRef()", FALSE);
2106     } else {
2107         PrintDebugString("  Error! either env == 0 or getAccessibleValueFromContextMethod == 0");
2108         return FALSE;
2109     }
2110 
2111     // FIX
2112     // get the AccessibleHypertext
2113     if (getAccessibleHypertextMethod != (jmethodID) 0 &&
2114         getAccessibleHyperlinkCountMethod != (jmethodID) 0 &&
2115         getAccessibleHyperlinkMethod != (jmethodID) 0 &&
2116         getAccessibleHyperlinkTextMethod != (jmethodID) 0 &&
2117         getAccessibleHyperlinkStartIndexMethod != (jmethodID) 0 &&
2118         getAccessibleHyperlinkEndIndexMethod != (jmethodID) 0) {
2119         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2120                                                    getAccessibleHypertextMethod,
2121                                                    accessibleContext);
2122         EXCEPTION_CHECK("Getting AccessibleHypertext - call to CallObjectMethod()", FALSE);
2123         PrintDebugString("  AccessibleHypertext = %p",
2124                          returnedJobject);
2125         if (returnedJobject != (jobject) 0) {
2126             info->accessibleInterfaces |= cAccessibleHypertextInterface;
2127         }
2128         jniEnv->DeleteLocalRef(returnedJobject);
2129         EXCEPTION_CHECK("Getting AccessibleHypertext - call to DeleteLocalRef()", FALSE);
2130     }
2131 
2132     // set new accessibleInterfaces flags from old BOOL values
2133     if(info->accessibleComponent)
2134         info->accessibleInterfaces |= cAccessibleComponentInterface;
2135     if(info->accessibleAction)
2136         info->accessibleInterfaces |= cAccessibleActionInterface;
2137     if(info->accessibleSelection)
2138         info->accessibleInterfaces |= cAccessibleSelectionInterface;
2139     if(info->accessibleText)
2140         info->accessibleInterfaces |= cAccessibleTextInterface;
2141     // FIX END
2142 
2143     return TRUE;
2144 }
2145 
2146 /**
2147  * getAccessibleChildFromContext - performs the Java method call:
2148  *   AccessibleContext AccessBridge.getAccessibleChildContext(AccessibleContext)
2149  *
2150  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2151  *
2152  * Note: this call explicitly goes through the AccessBridge,
2153  * so that it can keep a reference the returned jobject for the JavaVM.
2154  * You must explicity call releaseJavaObject() when you are through using
2155  * the AccessibleContext returned, to let the AccessBridge know it can release the
2156  * object, so that the JavaVM can then garbage collect it.
2157  */
2158 jobject
2159 AccessBridgeJavaEntryPoints::getAccessibleChildFromContext(jobject accessibleContext, jint childIndex) {
2160     jobject returnedAccessibleContext;
2161     jobject globalRef;
2162     jthrowable exception;
2163 
2164     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleChildContext(%p, %d):",
2165                      accessibleContext, childIndex);
2166 
2167     if (getAccessibleChildFromContextMethod != (jmethodID) 0) {
2168         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
2169                                                              getAccessibleChildFromContextMethod,
2170                                                              accessibleContext, childIndex);
2171         EXCEPTION_CHECK("Getting AccessibleChild - call to CallObjectMethod()", FALSE);
2172         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2173         EXCEPTION_CHECK("Getting AccessibleChild - call to NewGlobalRef()", FALSE);
2174         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2175         EXCEPTION_CHECK("Getting AccessibleChild - call to DeleteLocalRef()", FALSE);
2176         PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
2177                          returnedAccessibleContext, globalRef);
2178         return globalRef;
2179     } else {
2180         PrintDebugString("  Error! either env == 0 or getAccessibleChildContextMethod == 0");
2181         return (jobject) 0;
2182     }
2183 }
2184 
2185 /**
2186  * getAccessibleParentFromContext - returns the AccessibleContext parent
2187  *
2188  */
2189 jobject
2190 AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(jobject accessibleContext)
2191 {
2192     jobject returnedAccessibleContext;
2193     jobject globalRef;
2194     jthrowable exception;
2195 
2196     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(%p):", accessibleContext);
2197 
2198     if (getAccessibleParentFromContextMethod != (jmethodID) 0) {
2199         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
2200                                                              getAccessibleParentFromContextMethod,
2201                                                              accessibleContext);
2202         EXCEPTION_CHECK("Getting AccessibleParent - call to CallObjectMethod()", FALSE);
2203         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2204         EXCEPTION_CHECK("Getting AccessibleParent - call to NewGlobalRef()", FALSE);
2205         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2206         EXCEPTION_CHECK("Getting AccessibleParent - call to DeleteLocalRef()", FALSE);
2207         PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
2208                          returnedAccessibleContext, globalRef);
2209         return globalRef;
2210     } else {
2211         PrintDebugString("  Error! either env == 0 or getAccessibleParentFromContextMethod == 0");
2212         return (jobject) 0;
2213     }
2214 }
2215 
2216 
2217 /********** AccessibleTable routines **********************************/
2218 
2219 BOOL
2220 AccessBridgeJavaEntryPoints::getAccessibleTableInfo(jobject accessibleContext,
2221                                                     AccessibleTableInfo *tableInfo) {
2222 
2223     jthrowable exception;
2224 
2225     PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo(%p):",
2226                      accessibleContext);
2227 
2228     // get the table row count
2229     if (getAccessibleTableRowCountMethod != (jmethodID) 0) {
2230         tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject,
2231                                                     getAccessibleTableRowCountMethod,
2232                                                     accessibleContext);
2233         EXCEPTION_CHECK("##### Getting AccessibleTableRowCount - call to CallIntMethod()", FALSE);
2234         PrintDebugString("  ##### table row count = %d", tableInfo->rowCount);
2235     } else {
2236         PrintDebugString("  ##### Error! either env == 0 or getAccessibleRowCountMethod == 0");
2237         return FALSE;
2238     }
2239 
2240     // get the table column count
2241     if (getAccessibleTableColumnCountMethod != (jmethodID) 0) {
2242         tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject,
2243                                                        getAccessibleTableColumnCountMethod,
2244                                                        accessibleContext);
2245         EXCEPTION_CHECK("Getting AccessibleTableColumnCount - call to CallIntMethod()", FALSE);
2246         PrintDebugString("  ##### table column count = %d", tableInfo->columnCount);
2247     } else {
2248         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableColumnCountMethod == 0");
2249         return FALSE;
2250     }
2251 
2252     // get the AccessibleTable
2253     if (getAccessibleTableFromContextMethod != (jmethodID) 0) {
2254         PrintDebugString("##### Calling getAccessibleTableFromContextMethod ...");
2255         jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject,
2256                                                     getAccessibleTableFromContextMethod,
2257                                                     accessibleContext);
2258         PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod");
2259         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2260         jobject globalRef = jniEnv->NewGlobalRef(accTable);
2261         EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE);
2262         tableInfo->accessibleTable = (JOBJECT64)globalRef;
2263         PrintDebugString("  ##### accessibleTable = %p", globalRef);
2264     } else {
2265         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableFromContextMethod == 0");
2266         return FALSE;
2267     }
2268 
2269     // cache the AccessibleContext
2270     if (getContextFromAccessibleTableMethod != (jmethodID) 0) {
2271         PrintDebugString("##### Calling getContextFromAccessibleTable Method ...");
2272         jobject ac = jniEnv->CallObjectMethod(accessBridgeObject,
2273                                               getContextFromAccessibleTableMethod,
2274                                               accessibleContext);
2275         PrintDebugString("##### ... Returned from getContextFromAccessibleTable Method");
2276         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2277         jobject globalRef = jniEnv->NewGlobalRef(ac);
2278         EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE);
2279         tableInfo->accessibleContext = (JOBJECT64)globalRef;
2280         PrintDebugString("  ##### accessibleContext = %p", globalRef);
2281     } else {
2282         PrintDebugString("  ##### Error! either env == 0 or getContextFromAccessibleTable Method == 0");
2283         return FALSE;
2284     }
2285 
2286     // FIX - set unused elements
2287     tableInfo->caption = NULL;
2288     tableInfo->summary = NULL;
2289 
2290     PrintDebugString("##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo succeeded");
2291     return TRUE;
2292 }
2293 
2294 BOOL
2295 AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(jobject accessibleTable, jint row, jint column,
2296                                                         AccessibleTableCellInfo *tableCellInfo) {
2297 
2298     jthrowable exception;
2299 
2300     PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(%p): row=%d, column=%d",
2301                      accessibleTable, row, column);
2302 
2303     // FIX
2304     ZeroMemory(tableCellInfo, sizeof(AccessibleTableCellInfo));
2305     tableCellInfo->row = row;
2306     tableCellInfo->column = column;
2307     // FIX END
2308 
2309     // get the table cell index
2310     if (getAccessibleTableCellIndexMethod != (jmethodID) 0) {
2311         tableCellInfo->index = jniEnv->CallIntMethod(accessBridgeObject,
2312                                                      getAccessibleTableCellIndexMethod,
2313                                                      accessibleTable, row, column);
2314         EXCEPTION_CHECK("##### Getting AccessibleTableCellIndex - call to CallIntMethod()", FALSE);
2315         PrintDebugString("  ##### table cell index = %d", tableCellInfo->index);
2316     } else {
2317         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableCellIndexMethod == 0");
2318         return FALSE;
2319     }
2320 
2321     // get the table cell row extent
2322     if (getAccessibleTableCellRowExtentMethod != (jmethodID) 0) {
2323         tableCellInfo->rowExtent = jniEnv->CallIntMethod(accessBridgeObject,
2324                                                          getAccessibleTableCellRowExtentMethod,
2325                                                          accessibleTable, row, column);
2326         EXCEPTION_CHECK("##### Getting AccessibleTableCellRowExtentCount - call to CallIntMethod()", FALSE);
2327         PrintDebugString("  ##### table cell row extent = %d", tableCellInfo->rowExtent);
2328     } else {
2329         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableCellRowExtentMethod == 0");
2330         return FALSE;
2331     }
2332 
2333     // get the table cell column extent
2334     if (getAccessibleTableCellColumnExtentMethod != (jmethodID) 0) {
2335         tableCellInfo->columnExtent = jniEnv->CallIntMethod(accessBridgeObject,
2336                                                             getAccessibleTableCellColumnExtentMethod,
2337                                                             accessibleTable, row, column);
2338         EXCEPTION_CHECK("##### Getting AccessibleTableCellColumnExtentCount - call to CallIntMethod()", FALSE);
2339         PrintDebugString("  ##### table cell column extent = %d", tableCellInfo->columnExtent);
2340     } else {
2341         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableCellColumnExtentMethod == 0");
2342         return FALSE;
2343     }
2344 
2345     // get whether the table cell is selected
2346     if (isAccessibleTableCellSelectedMethod != (jmethodID) 0) {
2347         tableCellInfo->isSelected = jniEnv->CallBooleanMethod(accessBridgeObject,
2348                                                               isAccessibleTableCellSelectedMethod,
2349                                                               accessibleTable, row, column);
2350         EXCEPTION_CHECK("##### Getting isAccessibleTableCellSelected - call to CallBooleanMethod()", FALSE);
2351         PrintDebugString("  ##### table cell isSelected = %d", tableCellInfo->isSelected);
2352     } else {
2353         PrintDebugString("  ##### Error! either env == 0 or isAccessibleTableCellSelectedMethod == 0");
2354         return FALSE;
2355     }
2356 
2357     // get the table cell AccessibleContext
2358     if (getAccessibleTableCellAccessibleContextMethod != (jmethodID) 0) {
2359         jobject tableCellAC = jniEnv->CallObjectMethod(accessBridgeObject,
2360                                                        getAccessibleTableCellAccessibleContextMethod,
2361                                                        accessibleTable, row, column);
2362         EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to CallObjectMethod()", FALSE);
2363         jobject globalRef = jniEnv->NewGlobalRef(tableCellAC);
2364         EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to NewGlobalRef()", FALSE);
2365         tableCellInfo->accessibleContext = (JOBJECT64)globalRef;
2366         PrintDebugString("  ##### table cell AccessibleContext = %p", globalRef);
2367     } else {
2368         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableCellAccessibleContextMethod == 0");
2369         return FALSE;
2370     }
2371 
2372     PrintDebugString("  ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo succeeded");
2373     return TRUE;
2374 }
2375 
2376 BOOL
2377 AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(jobject acParent, AccessibleTableInfo *tableInfo) {
2378 
2379     jthrowable exception;
2380 
2381     PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(%p):",
2382                      acParent);
2383 
2384     // get the header row count
2385     if (getAccessibleTableRowHeaderRowCountMethod != (jmethodID) 0) {
2386         tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject,
2387                                                     getAccessibleTableRowHeaderRowCountMethod,
2388                                                     acParent);
2389         EXCEPTION_CHECK("##### Getting AccessibleTableRowHeaderRowCount - call to CallIntMethod()", FALSE);
2390         PrintDebugString("  ##### table row count = %d", tableInfo->rowCount);
2391     } else {
2392         PrintDebugString("  ##### Error! either env == 0 or getAccessibleRowHeaderRowCountMethod == 0");
2393         return FALSE;
2394     }
2395 
2396     // get the header column count
2397     if (getAccessibleTableRowHeaderColumnCountMethod != (jmethodID) 0) {
2398         tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject,
2399                                                        getAccessibleTableRowHeaderColumnCountMethod,
2400                                                        acParent);
2401         EXCEPTION_CHECK("Getting AccessibleTableRowHeaderColumnCount - call to CallIntMethod()", FALSE);
2402         PrintDebugString("  ##### table column count = %d", tableInfo->columnCount);
2403     } else {
2404         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableRowHeaderColumnCountMethod == 0");
2405         return FALSE;
2406     }
2407 
2408     // get the header AccessibleTable
2409     if (getAccessibleTableRowHeaderMethod != (jmethodID) 0) {
2410         jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject,
2411                                                     getAccessibleTableRowHeaderMethod,
2412                                                     acParent);
2413         EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to CallObjectMethod()", FALSE);
2414         jobject globalRef = jniEnv->NewGlobalRef(accTable);
2415         EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to NewGlobalRef()", FALSE);
2416         tableInfo->accessibleTable = (JOBJECT64)globalRef;
2417         PrintDebugString("  ##### row header AccessibleTable = %p", globalRef);
2418     } else {
2419         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableRowHeaderMethod == 0");
2420         return FALSE;
2421     }
2422 
2423     // FIX - set unused elements
2424     tableInfo->caption = NULL;
2425     tableInfo->summary = NULL;
2426     tableInfo->accessibleContext = NULL;
2427 
2428     PrintDebugString("  ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader succeeded");
2429     return TRUE;
2430 }
2431 
2432 BOOL
2433 AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(jobject acParent, AccessibleTableInfo *tableInfo) {
2434     jthrowable exception;
2435 
2436     PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(%p):",
2437                      acParent);
2438 
2439     // get the header row count
2440     if (getAccessibleTableColumnHeaderRowCountMethod != (jmethodID) 0) {
2441         tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject,
2442                                                     getAccessibleTableColumnHeaderRowCountMethod,
2443                                                     acParent);
2444         EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeaderRowCount - call to CallIntMethod()", FALSE);
2445         PrintDebugString("  ##### table row count = %d", tableInfo->rowCount);
2446     } else {
2447         PrintDebugString("  ##### Error! either env == 0 or getAccessibleColumnHeaderRowCountMethod == 0");
2448         return FALSE;
2449     }
2450 
2451     // get the header column count
2452     if (getAccessibleTableColumnHeaderColumnCountMethod != (jmethodID) 0) {
2453         tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject,
2454                                                        getAccessibleTableColumnHeaderColumnCountMethod,
2455                                                        acParent);
2456         EXCEPTION_CHECK("Getting AccessibleTableColumnHeaderColumnCount - call to CallIntMethod()", FALSE);
2457         PrintDebugString("  ##### table column count = %d", tableInfo->columnCount);
2458     } else {
2459         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableColumnHeaderColumnCountMethod == 0");
2460         return FALSE;
2461     }
2462     // get the header AccessibleTable
2463     if (getAccessibleTableColumnHeaderMethod != (jmethodID) 0) {
2464         jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject,
2465                                                     getAccessibleTableColumnHeaderMethod,
2466                                                     acParent);
2467         EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to CallObjectMethod()", FALSE);
2468         jobject globalRef = jniEnv->NewGlobalRef(accTable);
2469         EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to NewGlobalRef()", FALSE);
2470         tableInfo->accessibleTable = (JOBJECT64)globalRef;
2471         PrintDebugString("  ##### column header AccessibleTable = %p", globalRef);
2472     } else {
2473         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableColumnHeaderMethod == 0");
2474         return FALSE;
2475     }
2476 
2477     // FIX - set unused elements
2478     tableInfo->caption = NULL;
2479     tableInfo->summary = NULL;
2480     tableInfo->accessibleContext = NULL;
2481 
2482     PrintDebugString("  ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader succeeded");
2483     return TRUE;
2484 }
2485 
2486 jobject
2487 AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(jobject acParent, jint row) {
2488 
2489     jobject returnedAccessibleContext;
2490     jobject globalRef;
2491     jthrowable exception;
2492 
2493     PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(%p):",
2494                      acParent);
2495 
2496     if (getAccessibleTableRowDescriptionMethod != (jmethodID) 0) {
2497         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
2498                                                              getAccessibleTableRowDescriptionMethod,
2499                                                              acParent, row);
2500         EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to CallObjectMethod()", FALSE);
2501         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2502         EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to NewGlobalRef()", FALSE);
2503         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2504         EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to DeleteLocalRef()", FALSE);
2505         PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
2506                          returnedAccessibleContext, globalRef);
2507         return globalRef;
2508     } else {
2509         PrintDebugString("  Error! either env == 0 or getAccessibleTableRowDescriptionMethod == 0");
2510         return (jobject) 0;
2511     }
2512 }
2513 
2514 jobject
2515 AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(jobject acParent, jint column) {
2516 
2517     jobject returnedAccessibleContext;
2518     jobject globalRef;
2519     jthrowable exception;
2520 
2521     PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(%p):",
2522                      acParent);
2523 
2524     if (getAccessibleTableColumnDescriptionMethod != (jmethodID) 0) {
2525         returnedAccessibleContext = jniEnv->CallObjectMethod(
2526                                                              accessBridgeObject,
2527                                                              getAccessibleTableColumnDescriptionMethod,
2528                                                              acParent, column);
2529         EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to CallObjectMethod()", FALSE);
2530         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2531         EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to NewGlobalRef()", FALSE);
2532         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2533         EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to DeleteLocalRef()", FALSE);
2534         PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
2535                          returnedAccessibleContext, globalRef);
2536         return globalRef;
2537     } else {
2538         PrintDebugString("  Error! either env == 0 or getAccessibleTableColumnDescriptionMethod == 0");
2539         return (jobject) 0;
2540     }
2541 }
2542 
2543 jint
2544 AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(jobject accessibleTable) {
2545 
2546     jthrowable exception;
2547     jint count;
2548 
2549     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(%p)",
2550                      accessibleTable);
2551 
2552     // Get the table row selection count
2553     if (getAccessibleTableRowSelectionCountMethod != (jmethodID) 0) {
2554         count = jniEnv->CallIntMethod(accessBridgeObject,
2555                                       getAccessibleTableRowSelectionCountMethod,
2556                                       accessibleTable);
2557         EXCEPTION_CHECK("##### Getting AccessibleTableRowSelectionCount - call to CallIntMethod()", FALSE);
2558         PrintDebugString("  ##### table row selection count = %d", count);
2559         return count;
2560     } else {
2561         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableRowSelectionCountMethod == 0");
2562         return 0;
2563     }
2564 
2565     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount failed");
2566     return 0;
2567 }
2568 
2569 BOOL
2570 AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(jobject accessibleTable, jint row) {
2571     jthrowable exception;
2572     BOOL result;
2573 
2574     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(%p, %d)",
2575                      accessibleTable, row);
2576 
2577     if (isAccessibleTableRowSelectedMethod != (jmethodID) 0) {
2578         result = jniEnv->CallBooleanMethod(accessBridgeObject,
2579                                            isAccessibleTableRowSelectedMethod,
2580                                            accessibleTable, row);
2581         EXCEPTION_CHECK("##### Getting isAccessibleTableRowSelected - call to CallBooleanMethod()", FALSE);
2582         PrintDebugString("  ##### table row isSelected = %d", result);
2583         return result;
2584     } else {
2585         PrintDebugString("  ##### Error! either env == 0 or isAccessibleTableRowSelectedMethod == 0");
2586         return FALSE;
2587     }
2588 
2589     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected failed");
2590     return FALSE;
2591 }
2592 
2593 BOOL
2594 AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(jobject accessibleTable, jint count,
2595                                                              jint *selections) {
2596 
2597     jthrowable exception;
2598 
2599     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(%p, %d %p)",
2600                      accessibleTable, count, selections);
2601 
2602     if (getAccessibleTableRowSelectionsMethod == (jmethodID) 0) {
2603         return FALSE;
2604     }
2605     // Get the table row selections
2606     for (int i = 0; i < count; i++) {
2607 
2608         selections[i] = jniEnv->CallIntMethod(accessBridgeObject,
2609                                               getAccessibleTableRowSelectionsMethod,
2610                                               accessibleTable,
2611                                               i);
2612         EXCEPTION_CHECK("##### Getting AccessibleTableRowSelections - call to CallIntMethod()", FALSE);
2613         PrintDebugString("  ##### table row selection[%d] = %d", i, selections[i]);
2614     }
2615 
2616     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections succeeded");
2617     return TRUE;
2618 }
2619 
2620 
2621 jint
2622 AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(jobject accessibleTable) {
2623 
2624     jthrowable exception;
2625     jint count;
2626 
2627     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(%p)",
2628                      accessibleTable);
2629 
2630     // Get the table column selection count
2631     if (getAccessibleTableColumnSelectionCountMethod != (jmethodID) 0) {
2632         count = jniEnv->CallIntMethod(accessBridgeObject,
2633                                       getAccessibleTableColumnSelectionCountMethod,
2634                                       accessibleTable);
2635         EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelectionCount - call to CallIntMethod()", FALSE);
2636         PrintDebugString("  ##### table column selection count = %d", count);
2637         return count;
2638     } else {
2639         PrintDebugString("  ##### Error! either env == 0 or getAccessibleRowCountMethod == 0");
2640         return 0;
2641     }
2642 
2643     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount failed");
2644     return 0;
2645 }
2646 
2647 BOOL
2648 AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(jobject accessibleTable, jint column) {
2649     jthrowable exception;
2650     BOOL result;
2651 
2652     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(%p, %d)",
2653                      accessibleTable, column);
2654 
2655     if (isAccessibleTableColumnSelectedMethod != (jmethodID) 0) {
2656         result = jniEnv->CallBooleanMethod(accessBridgeObject,
2657                                            isAccessibleTableColumnSelectedMethod,
2658                                            accessibleTable, column);
2659         EXCEPTION_CHECK("##### Getting isAccessibleTableColumnSelected - call to CallBooleanMethod()", FALSE);
2660         PrintDebugString("  ##### table column isSelected = %d", result);
2661         return result;
2662     } else {
2663         PrintDebugString("  ##### Error! either env == 0 or isAccessibleTableColumnSelectedMethod == 0");
2664         return FALSE;
2665     }
2666 
2667     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected failed");
2668     return FALSE;
2669 }
2670 
2671 BOOL
2672 AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(jobject accessibleTable, jint count,
2673                                                                 jint *selections) {
2674     jthrowable exception;
2675 
2676     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(%p, %d, %p)",
2677                      accessibleTable, count, selections);
2678 
2679     if (getAccessibleTableColumnSelectionsMethod == (jmethodID) 0) {
2680         return FALSE;
2681     }
2682     // Get the table column selections
2683     for (int i = 0; i < count; i++) {
2684 
2685         selections[i] = jniEnv->CallIntMethod(accessBridgeObject,
2686                                               getAccessibleTableColumnSelectionsMethod,
2687                                               accessibleTable,
2688                                               i);
2689         EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelections - call to CallIntMethod()", FALSE);
2690         PrintDebugString("  ##### table Column selection[%d] = %d", i, selections[i]);
2691     }
2692 
2693     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections succeeded");
2694     return TRUE;
2695 }
2696 
2697 
2698 jint
2699 AccessBridgeJavaEntryPoints::getAccessibleTableRow(jobject accessibleTable, jint index) {
2700     jthrowable exception;
2701     jint result;
2702 
2703     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRow(%p, index=%d)",
2704                      accessibleTable, index);
2705 
2706     if (getAccessibleTableRowMethod != (jmethodID) 0) {
2707         result = jniEnv->CallIntMethod(accessBridgeObject,
2708                                        getAccessibleTableRowMethod,
2709                                        accessibleTable, index);
2710         EXCEPTION_CHECK("##### Getting AccessibleTableRow - call to CallIntMethod()", FALSE);
2711         PrintDebugString("  ##### table row = %d", result);
2712         return result;
2713     } else {
2714         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableRowMethod == 0");
2715         return -1;
2716     }
2717 
2718     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow failed");
2719     return -1;
2720 }
2721 
2722 jint
2723 AccessBridgeJavaEntryPoints::getAccessibleTableColumn(jobject accessibleTable, jint index) {
2724     jthrowable exception;
2725     jint result;
2726 
2727     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn(%p, index=%d)",
2728                      accessibleTable, index);
2729 
2730     if (getAccessibleTableColumnMethod != (jmethodID) 0) {
2731         result = jniEnv->CallIntMethod(accessBridgeObject,
2732                                        getAccessibleTableColumnMethod,
2733                                        accessibleTable, index);
2734         EXCEPTION_CHECK("##### Getting AccessibleTableColumn - call to CallIntMethod()", FALSE);
2735         PrintDebugString("  ##### table column = %d", result);
2736         return result;
2737     } else {
2738         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableColumnMethod == 0");
2739         return -1;
2740     }
2741 
2742     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn failed");
2743     return -1;
2744 }
2745 
2746 jint
2747 AccessBridgeJavaEntryPoints::getAccessibleTableIndex(jobject accessibleTable, jint row, jint column) {
2748     jthrowable exception;
2749     jint result;
2750 
2751     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex(%p, row=%d, col=%d)",
2752                      accessibleTable, row, column);
2753 
2754     if (getAccessibleTableIndexMethod != (jmethodID) 0) {
2755         result = jniEnv->CallIntMethod(accessBridgeObject,
2756                                        getAccessibleTableIndexMethod,
2757                                        accessibleTable, row, column);
2758         EXCEPTION_CHECK("##### Getting getAccessibleTableIndex - call to CallIntMethod()", FALSE);
2759         PrintDebugString("  ##### table index = %d", result);
2760         return result;
2761     } else {
2762         PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableIndexMethod == 0");
2763         return -1;
2764     }
2765 
2766     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex failed");
2767     return -1;
2768 }
2769 
2770 /********** end AccessibleTable routines ******************************/
2771 
2772 
2773 /********** begin AccessibleRelationSet routines **********************/
2774 
2775 BOOL
2776 AccessBridgeJavaEntryPoints::getAccessibleRelationSet(jobject accessibleContext,
2777                                                       AccessibleRelationSetInfo *relationSet) {
2778 
2779     jthrowable exception;
2780     const wchar_t *stringBytes;
2781     jsize length;
2782 
2783     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet(%p, %p)",
2784                      accessibleContext, relationSet);
2785 
2786     if (getAccessibleRelationCountMethod == (jmethodID) 0 ||
2787         getAccessibleRelationKeyMethod == (jmethodID) 0 ||
2788         getAccessibleRelationTargetCountMethod == (jmethodID) 0 ||
2789         getAccessibleRelationTargetMethod == (jmethodID) 0) {
2790         return FALSE;
2791     }
2792 
2793     // Get the relations set count
2794     relationSet->relationCount = jniEnv->CallIntMethod(accessBridgeObject,
2795                                                        getAccessibleRelationCountMethod,
2796                                                        accessibleContext);
2797     EXCEPTION_CHECK("##### Getting AccessibleRelationCount - call to CallIntMethod()", FALSE);
2798     PrintDebugString("  ##### AccessibleRelation count = %d", relationSet->relationCount);
2799 
2800 
2801     // Get the relation set
2802     for (int i = 0; i < relationSet->relationCount && i < MAX_RELATIONS; i++) {
2803 
2804         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
2805                                                        getAccessibleRelationKeyMethod,
2806                                                        accessibleContext,
2807                                                        i);
2808 
2809         EXCEPTION_CHECK("Getting AccessibleRelationKey - call to CallObjectMethod()", FALSE);
2810         if (js != (jstring) 0) {
2811             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
2812             EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringChars()", FALSE);
2813             wcsncpy(relationSet->relations[i].key, stringBytes, (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t)));
2814             length = jniEnv->GetStringLength(js);
2815             relationSet->relations[i].key [length < (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t)) ?
2816                                            length : (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t))-2] = (wchar_t) 0;
2817             EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringLength()", FALSE);
2818             jniEnv->ReleaseStringChars(js, stringBytes);
2819             EXCEPTION_CHECK("Getting AccessibleRelation key - call to ReleaseStringChars()", FALSE);
2820             // jniEnv->CallVoidMethod(accessBridgeObject,
2821             //                        decrementReferenceMethod, js);
2822             //EXCEPTION_CHECK("Getting AccessibleRelation key - call to CallVoidMethod()", FALSE);
2823             PrintDebugString("##### AccessibleRelation key = %ls", relationSet->relations[i].key );
2824             jniEnv->DeleteLocalRef(js);
2825             EXCEPTION_CHECK("Getting AccessibleRelation key - call to DeleteLocalRef()", FALSE);
2826         } else {
2827             PrintDebugString("  AccessibleRelation key is null.");
2828             relationSet->relations[i].key [0] = (wchar_t) 0;
2829         }
2830 
2831         relationSet->relations[i].targetCount = jniEnv->CallIntMethod(accessBridgeObject,
2832                                                                       getAccessibleRelationTargetCountMethod,
2833                                                                       accessibleContext,
2834                                                                       i);
2835 
2836         for (int j = 0; j < relationSet->relations[i].targetCount && j < MAX_RELATION_TARGETS; j++) {
2837             jobject target = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleRelationTargetMethod,
2838                                                       accessibleContext, i, j);
2839             EXCEPTION_CHECK("Getting AccessibleRelationSet - call to CallObjectMethod()", FALSE);
2840             jobject globalRef = jniEnv->NewGlobalRef(target);
2841             EXCEPTION_CHECK("Getting AccessibleRelationSet - call to NewGlobalRef()", FALSE);
2842             relationSet->relations[i].targets[j] = (JOBJECT64)globalRef;
2843             PrintDebugString("  relation set item: %p", globalRef);
2844         }
2845     }
2846 
2847     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet succeeded");
2848     return TRUE;
2849 }
2850 
2851 
2852 /********** end AccessibleRelationSet routines ************************/
2853 
2854 
2855 /********** begin AccessibleHypertext routines **********************/
2856 
2857 BOOL
2858 AccessBridgeJavaEntryPoints::getAccessibleHypertext(jobject accessibleContext,
2859                                                     AccessibleHypertextInfo *hypertext) {
2860 
2861     jthrowable exception;
2862     const wchar_t *stringBytes;
2863     jsize length;
2864 
2865     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertext(%p, %p)",
2866                      accessibleContext, hypertext);
2867 
2868     // get the AccessibleHypertext
2869     jobject ht = jniEnv->CallObjectMethod(accessBridgeObject,
2870                                           getAccessibleHypertextMethod,
2871                                           accessibleContext);
2872     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to CallObjectMethod()", FALSE);
2873     jobject globalRef = jniEnv->NewGlobalRef(ht);
2874     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE);
2875     hypertext->accessibleHypertext = (JOBJECT64)globalRef;
2876     PrintDebugString("  ##### AccessibleHypertext = %p", globalRef);
2877 
2878     if (hypertext->accessibleHypertext == 0) {
2879         PrintDebugString("  ##### null AccessibleHypertext; returning FALSE");
2880         return false;
2881     }
2882 
2883     // get the hyperlink count
2884     hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject,
2885                                                  getAccessibleHyperlinkCountMethod,accessibleContext);
2886 
2887     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE);
2888     PrintDebugString("  ##### hyperlink count = %d", hypertext->linkCount);
2889 
2890 
2891     // get the hypertext links
2892     for (int i = 0; i < hypertext->linkCount && i < MAX_HYPERLINKS; i++) {
2893 
2894         // get the hyperlink
2895         jobject hl = jniEnv->CallObjectMethod(accessBridgeObject,
2896                                               getAccessibleHyperlinkMethod,
2897                                               accessibleContext,
2898                                               i);
2899         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE);
2900         jobject globalRef = jniEnv->NewGlobalRef(hl);
2901         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
2902         hypertext->links[i].accessibleHyperlink = (JOBJECT64)globalRef;
2903         PrintDebugString("  ##### AccessibleHyperlink = %p", globalRef);
2904 
2905         // get the hyperlink text
2906         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
2907                                                        getAccessibleHyperlinkTextMethod,
2908                                                        hypertext->links[i].accessibleHyperlink,
2909                                                        i);
2910 
2911         EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE);
2912         if (js != (jstring) 0) {
2913             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
2914             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE);
2915             wcsncpy(hypertext->links[i].text, stringBytes, (sizeof(hypertext->links[i].text) / sizeof(wchar_t)));
2916             length = jniEnv->GetStringLength(js);
2917             if (length >= (sizeof(hypertext->links[i].text) / sizeof(wchar_t))) {
2918                 length = (sizeof(hypertext->links[i].text) / sizeof(wchar_t)) - 2;
2919             }
2920             hypertext->links[i].text[length] = (wchar_t) 0;
2921             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE);
2922             jniEnv->ReleaseStringChars(js, stringBytes);
2923             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE);
2924             // jniEnv->CallVoidMethod(accessBridgeObject,
2925             //                                     decrementReferenceMethod, js);
2926             //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
2927             PrintDebugString("##### AccessibleHyperlink text = %ls", hypertext->links[i].text );
2928             jniEnv->DeleteLocalRef(js);
2929             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
2930         } else {
2931             PrintDebugString("  AccessibleHyperlink text is null.");
2932             hypertext->links[i].text[0] = (wchar_t) 0;
2933         }
2934 
2935         hypertext->links[i].startIndex = jniEnv->CallIntMethod(accessBridgeObject,
2936                                                                getAccessibleHyperlinkStartIndexMethod,
2937                                                                hypertext->links[i].accessibleHyperlink,
2938                                                                i);
2939         EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
2940         PrintDebugString("  ##### hyperlink start index = %d", hypertext->links[i].startIndex);
2941 
2942 
2943         hypertext->links[i].endIndex = jniEnv->CallIntMethod(accessBridgeObject,
2944                                                              getAccessibleHyperlinkEndIndexMethod,
2945                                                              hypertext->links[i].accessibleHyperlink,
2946                                                              i);
2947         EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
2948         PrintDebugString("  ##### hyperlink end index = %d", hypertext->links[i].endIndex);
2949 
2950     }
2951 
2952     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext succeeded");
2953     return TRUE;
2954 }
2955 
2956 /*
2957  * Activates an AccessibleHyperlink
2958  */
2959 BOOL
2960 AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(jobject accessibleContext,
2961                                                          jobject accessibleHyperlink) {
2962 
2963     jthrowable exception;
2964     BOOL returnVal;
2965 
2966     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(%p, %p):",
2967                      accessibleContext, accessibleHyperlink);
2968 
2969     if (activateAccessibleHyperlinkMethod != (jmethodID) 0) {
2970         returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, activateAccessibleHyperlinkMethod,
2971                                                      accessibleContext, accessibleHyperlink);
2972         EXCEPTION_CHECK("activateAccessibleHyperlink - call to CallBooleanMethod()", FALSE);
2973         return returnVal;
2974     } else {
2975         PrintDebugString("\r\n  Error! either jniEnv == 0 or activateAccessibleHyperlinkMethod == 0");
2976         return FALSE;
2977     }
2978 }
2979 
2980 
2981 /*
2982  * This method is used to iterate through the hyperlinks in a component.  It
2983  * returns hypertext information for a component starting at hyperlink index
2984  * nStartIndex.  No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will
2985  * be returned for each call to this method.
2986  * returns FALSE on error.
2987  */
2988 BOOL
2989 AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(const jobject accessibleContext,
2990                                                        const jint nStartIndex,
2991                                                        /* OUT */ AccessibleHypertextInfo *hypertext) {
2992 
2993     jthrowable exception;
2994     const wchar_t *stringBytes;
2995     jsize length;
2996     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(%p, %p, startIndex = %d)",
2997                      accessibleContext, hypertext, nStartIndex);
2998 
2999     // get the AccessibleHypertext
3000     jobject ht = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleHypertextMethod,
3001                                                               accessibleContext);
3002     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to CallObjectMethod()", FALSE);
3003     jobject globalRef = jniEnv->NewGlobalRef(ht);
3004     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE);
3005     hypertext->accessibleHypertext = (JOBJECT64)globalRef;
3006     PrintDebugString("  ##### AccessibleHypertext = %p", globalRef);
3007     if (hypertext->accessibleHypertext == 0) {
3008         PrintDebugString("  ##### null AccessibleHypertext; returning FALSE");
3009         return FALSE;
3010     }
3011 
3012     // get the hyperlink count
3013     hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod,
3014                                                  accessibleContext);
3015     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE);
3016     PrintDebugString("  ##### hyperlink count = %d", hypertext->linkCount);
3017 
3018     if (nStartIndex >= hypertext->linkCount) {
3019         return FALSE;
3020     }
3021 
3022     // get the hypertext links
3023     // NOTE: To avoid a crash when there are more than MAX_HYPERLINKS (64) links
3024     // in the document, test for i < MAX_HYPERLINKS in addition to
3025     // i < hypertext->linkCount
3026     int bufIndex = 0;
3027     for (int i = nStartIndex; (i < hypertext->linkCount) && (i < nStartIndex + MAX_HYPERLINKS); i++) {
3028         PrintDebugString("  getting hyperlink %d ...", i);
3029 
3030         // get the hyperlink
3031         jobject hl = jniEnv->CallObjectMethod(accessBridgeObject,
3032                                               getAccessibleHyperlinkMethod,
3033                                               hypertext->accessibleHypertext,
3034                                               i);
3035         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE);
3036         jobject globalRef = jniEnv->NewGlobalRef(hl);
3037         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
3038         hypertext->links[bufIndex].accessibleHyperlink = (JOBJECT64)globalRef;
3039         PrintDebugString("  ##### AccessibleHyperlink = %p", globalRef);
3040 
3041         // get the hyperlink text
3042         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3043                                                        getAccessibleHyperlinkTextMethod,
3044                                                        hypertext->links[bufIndex].accessibleHyperlink,
3045                                                        i);
3046 
3047         EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE);
3048         if (js != (jstring) 0) {
3049             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3050             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE);
3051             wcsncpy(hypertext->links[bufIndex].text, stringBytes,
3052                     (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t)));
3053             length = jniEnv->GetStringLength(js);
3054             if (length >= (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t))) {
3055                 length = (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t)) - 2;
3056             }
3057             hypertext->links[bufIndex].text[length] = (wchar_t) 0;
3058             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE);
3059             jniEnv->ReleaseStringChars(js, stringBytes);
3060             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE);
3061             // jniEnv->CallVoidMethod(accessBridgeObject,
3062             //                        decrementReferenceMethod, js);
3063             //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
3064             PrintDebugString("##### AccessibleHyperlink text = %ls", hypertext->links[bufIndex].text );
3065             jniEnv->DeleteLocalRef(js);
3066             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
3067 
3068         } else {
3069             PrintDebugString("  AccessibleHyperlink text is null.");
3070             hypertext->links[bufIndex].text[0] = (wchar_t) 0;
3071         }
3072 
3073         hypertext->links[bufIndex].startIndex = jniEnv->CallIntMethod(accessBridgeObject,
3074                                                                       getAccessibleHyperlinkStartIndexMethod,
3075                                                                       hypertext->links[bufIndex].accessibleHyperlink,
3076                                                                       i);
3077         EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
3078         PrintDebugString("  ##### hyperlink start index = %d", hypertext->links[bufIndex].startIndex);
3079 
3080         hypertext->links[bufIndex].endIndex = jniEnv->CallIntMethod(accessBridgeObject,
3081                                                                     getAccessibleHyperlinkEndIndexMethod,
3082                                                                     hypertext->links[bufIndex].accessibleHyperlink,
3083                                                                     i);
3084         EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
3085         PrintDebugString("  ##### hyperlink end index = %d", hypertext->links[bufIndex].endIndex);
3086 
3087         bufIndex++;
3088     }
3089 
3090     PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt succeeded");
3091     return TRUE;
3092 }
3093 
3094 jint AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(const jobject accessibleContext) {
3095 
3096     jthrowable exception;
3097 
3098     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(%X)",
3099                      accessibleContext);
3100 
3101     if (getAccessibleHyperlinkCountMethod == (jmethodID)0) {
3102         return -1;
3103     }
3104 
3105     // get the hyperlink count
3106     jint linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod,
3107                                            accessibleContext);
3108     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", -1);
3109     PrintDebugString("  ##### hyperlink count = %d", linkCount);
3110 
3111     return linkCount;
3112 }
3113 
3114 
3115 jint AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(const jobject hypertext,
3116                                                                   const jint nIndex) {
3117 
3118     jthrowable exception;
3119 
3120     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(%p, index = %d)",
3121                      hypertext, nIndex);
3122 
3123     if (getAccessibleHypertextLinkIndexMethod == (jmethodID)0) {
3124         return -1;
3125     }
3126 
3127     // get the hyperlink index
3128     jint index = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHypertextLinkIndexMethod,
3129                                        hypertext, nIndex);
3130 
3131     EXCEPTION_CHECK("##### Getting hyperlink index - call to CallIntMethod()", -1);
3132     PrintDebugString("  ##### hyperlink index = %d", index);
3133 
3134     return index;
3135 }
3136 
3137 BOOL AccessBridgeJavaEntryPoints::getAccessibleHyperlink(jobject hypertext,
3138                                                          const jint index,
3139                                                          /* OUT */ AccessibleHyperlinkInfo *info) {
3140 
3141     jthrowable exception;
3142     const wchar_t *stringBytes;
3143     jsize length;
3144 
3145     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHyperlink(%p, index = %d)",
3146                      hypertext, index);
3147 
3148 
3149     // get the hyperlink
3150     jobject hl = jniEnv->CallObjectMethod(accessBridgeObject,
3151                                           getAccessibleHyperlinkMethod,
3152                                           hypertext,
3153                                           index);
3154     EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE);
3155     jobject globalRef = jniEnv->NewGlobalRef(hl);
3156     EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
3157     info->accessibleHyperlink = (JOBJECT64)globalRef;
3158     PrintDebugString("  ##### AccessibleHyperlink = %p", globalRef);
3159 
3160     // get the hyperlink text
3161     jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3162                                                    getAccessibleHyperlinkTextMethod,
3163                                                    info->accessibleHyperlink,
3164                                                    index);
3165 
3166     EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE);
3167     if (js != (jstring) 0) {
3168         stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3169         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE);
3170         wcsncpy(info->text, stringBytes,
3171                 (sizeof(info->text) / sizeof(wchar_t)));
3172         length = jniEnv->GetStringLength(js);
3173         if (length >= (sizeof(info->text) / sizeof(wchar_t))) {
3174             length = (sizeof(info->text) / sizeof(wchar_t)) - 2;
3175         }
3176         info->text[length] = (wchar_t) 0;
3177         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE);
3178         jniEnv->ReleaseStringChars(js, stringBytes);
3179         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE);
3180         // jniEnv->CallVoidMethod(accessBridgeObject,
3181         //                        decrementReferenceMethod, js);
3182         //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
3183         PrintDebugString("##### AccessibleHyperlink text = %ls", info->text );
3184         jniEnv->DeleteLocalRef(js);
3185         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
3186 
3187     } else {
3188         PrintDebugString("  AccessibleHyperlink text is null.");
3189         info->text[0] = (wchar_t) 0;
3190     }
3191 
3192     info->startIndex = jniEnv->CallIntMethod(accessBridgeObject,
3193                                              getAccessibleHyperlinkStartIndexMethod,
3194                                              info->accessibleHyperlink,
3195                                              index);
3196     EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
3197     PrintDebugString("  ##### hyperlink start index = %d", info->startIndex);
3198 
3199     info->endIndex = jniEnv->CallIntMethod(accessBridgeObject,
3200                                            getAccessibleHyperlinkEndIndexMethod,
3201                                            info->accessibleHyperlink,
3202                                            index);
3203     EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
3204     PrintDebugString("  ##### hyperlink end index = %d", info->endIndex);
3205 
3206     return TRUE;
3207 }
3208 
3209 
3210 /********** end AccessibleHypertext routines ************************/
3211 
3212 // Accessible Keybinding methods
3213 BOOL AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(jobject accessibleContext,
3214                                                            AccessibleKeyBindings *keyBindings) {
3215 
3216     jthrowable exception;
3217 
3218     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(%p, %p)",
3219                      accessibleContext, keyBindings);
3220 
3221     if (getAccessibleKeyBindingsCountMethod == (jmethodID) 0 ||
3222         getAccessibleKeyBindingCharMethod == (jmethodID) 0 ||
3223         getAccessibleKeyBindingModifiersMethod == (jmethodID) 0) {
3224         return FALSE;
3225     }
3226 
3227     // get the key binding count
3228     keyBindings->keyBindingsCount = jniEnv->CallIntMethod(accessBridgeObject,
3229                                                           getAccessibleKeyBindingsCountMethod, accessibleContext);
3230 
3231     EXCEPTION_CHECK("##### Getting key bindings count - call to CallIntMethod()", FALSE);
3232 
3233     PrintDebugString("  ##### key bindings count = %d", keyBindings->keyBindingsCount);
3234 
3235     // get the key bindings
3236     for (int i = 0; i < keyBindings->keyBindingsCount && i < MAX_KEY_BINDINGS; i++) {
3237 
3238         // get the key binding character
3239         keyBindings->keyBindingInfo[i].character = jniEnv->CallCharMethod(accessBridgeObject,
3240                                                                           getAccessibleKeyBindingCharMethod,
3241                                                                           accessibleContext,
3242                                                                           i);
3243         EXCEPTION_CHECK("##### Getting key binding character - call to CallCharMethod()", FALSE);
3244         PrintDebugString("  ##### key binding character = %c", keyBindings->keyBindingInfo[i].character);
3245         PrintDebugString("  ##### key binding character in hex = %hx", keyBindings->keyBindingInfo[i].character);

3246 
3247         // get the key binding modifiers
3248         keyBindings->keyBindingInfo[i].modifiers = jniEnv->CallIntMethod(accessBridgeObject,
3249                                                                          getAccessibleKeyBindingModifiersMethod,
3250                                                                          accessibleContext,
3251                                                                          i);
3252         EXCEPTION_CHECK("##### Getting key binding modifiers - call to CallIntMethod()", FALSE);
3253         PrintDebugString("  ##### key binding modifiers = %x", keyBindings->keyBindingInfo[i].modifiers);
3254     }
3255     return FALSE;
3256 }
3257 
3258 // AccessibleIcon methods
3259 BOOL AccessBridgeJavaEntryPoints::getAccessibleIcons(jobject accessibleContext,
3260                                                      AccessibleIcons *icons) {
3261 
3262     jthrowable exception;
3263     const wchar_t *stringBytes;
3264     jsize length;
3265 
3266     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)",
3267                      accessibleContext, icons);
3268 
3269     if (getAccessibleIconsCountMethod == (jmethodID) 0 ||
3270         getAccessibleIconDescriptionMethod == (jmethodID) 0 ||
3271         getAccessibleIconHeightMethod == (jmethodID) 0 ||
3272         getAccessibleIconWidthMethod == (jmethodID) 0) {
3273         PrintDebugString("  ##### missing method(s) !!!");
3274         return FALSE;
3275     }
3276 
3277 
3278     // get the icons count
3279     icons->iconsCount = jniEnv->CallIntMethod(accessBridgeObject,
3280                                               getAccessibleIconsCountMethod, accessibleContext);
3281 
3282     EXCEPTION_CHECK("##### Getting icons count - call to CallIntMethod()", FALSE);
3283     PrintDebugString("  ##### icons count = %d", icons->iconsCount);
3284 
3285 
3286     // get the icons
3287     for (int i = 0; i < icons->iconsCount && i < MAX_ICON_INFO; i++) {
3288 
3289         // get the icon description
3290         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3291                                                        getAccessibleIconDescriptionMethod,
3292                                                        accessibleContext,
3293                                                        i);
3294 
3295         EXCEPTION_CHECK("Getting icon description - call to CallObjectMethod()", FALSE);
3296         if (js != (jstring) 0) {
3297             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3298             EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringChars()", FALSE);
3299             wcsncpy(icons->iconInfo[i].description, stringBytes, (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t)));
3300             length = jniEnv->GetStringLength(js);
3301             if (length >= (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t))) {
3302                 length = (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t)) - 2;
3303             }
3304             icons->iconInfo[i].description[length] = (wchar_t) 0;
3305             EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringLength()", FALSE);
3306             jniEnv->ReleaseStringChars(js, stringBytes);
3307             EXCEPTION_CHECK("Getting AccessibleIcon description - call to ReleaseStringChars()", FALSE);
3308             // jniEnv->CallVoidMethod(accessBridgeObject,
3309             //                        decrementReferenceMethod, js);
3310             //EXCEPTION_CHECK("Getting AccessibleIcon description - call to CallVoidMethod()", FALSE);
3311             PrintDebugString("##### AccessibleIcon description = %ls", icons->iconInfo[i].description );
3312             jniEnv->DeleteLocalRef(js);
3313             EXCEPTION_CHECK("Getting AccessibleIcon description - call to DeleteLocalRef()", FALSE);
3314         } else {
3315             PrintDebugString("  AccessibleIcon description is null.");
3316             icons->iconInfo[i].description[0] = (wchar_t) 0;
3317         }
3318 
3319 
3320         // get the icon height
3321         icons->iconInfo[i].height = jniEnv->CallIntMethod(accessBridgeObject,
3322                                                           getAccessibleIconHeightMethod,
3323                                                           accessibleContext,
3324                                                           i);
3325         EXCEPTION_CHECK("##### Getting icon height - call to CallIntMethod()", FALSE);
3326         PrintDebugString("  ##### icon height = %d", icons->iconInfo[i].height);
3327 
3328         // get the icon width
3329         icons->iconInfo[i].width = jniEnv->CallIntMethod(accessBridgeObject,
3330                                                          getAccessibleIconWidthMethod,
3331                                                          accessibleContext,
3332                                                          i);
3333         EXCEPTION_CHECK("##### Getting icon width - call to CallIntMethod()", FALSE);
3334         PrintDebugString("  ##### icon width = %d", icons->iconInfo[i].width);
3335     }
3336     return FALSE;
3337 }
3338 
3339 // AccessibleActionMethods
3340 BOOL AccessBridgeJavaEntryPoints::getAccessibleActions(jobject accessibleContext,
3341                                                        AccessibleActions *actions) {
3342 
3343     jthrowable exception;
3344     const wchar_t *stringBytes;
3345     jsize length;
3346 
3347     PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)",
3348                      accessibleContext, actions);
3349 
3350     if (getAccessibleActionsCountMethod == (jmethodID) 0 ||
3351         getAccessibleActionNameMethod == (jmethodID) 0) {
3352         PrintDebugString("  ##### missing method(s) !!!");
3353         return FALSE;
3354     }
3355 
3356 
3357     // get the icons count
3358     actions->actionsCount = jniEnv->CallIntMethod(accessBridgeObject,
3359                                                   getAccessibleActionsCountMethod,accessibleContext);
3360 
3361     EXCEPTION_CHECK("##### Getting actions count - call to CallIntMethod()", FALSE);
3362     PrintDebugString("  ##### key actions count = %d", actions->actionsCount);
3363 
3364 
3365     // get the actions
3366     for (int i = 0; i < actions->actionsCount && i < MAX_ACTION_INFO; i++) {
3367 
3368         // get the action name
3369         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3370                                                        getAccessibleActionNameMethod,
3371                                                        accessibleContext,
3372                                                        i);
3373 
3374         EXCEPTION_CHECK("Getting Action Name  - call to CallObjectMethod()", FALSE);
3375         if (js != (jstring) 0) {
3376             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3377             EXCEPTION_CHECK("Getting AccessibleAction Name  - call to GetStringChars()", FALSE);
3378             wcsncpy(actions->actionInfo[i].name , stringBytes, (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t)));
3379             length = jniEnv->GetStringLength(js);
3380             if (length >= (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t))) {
3381                 length = (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t)) - 2;
3382             }
3383             actions->actionInfo[i].name [length] = (wchar_t) 0;
3384             EXCEPTION_CHECK("Getting AccessibleAction name  - call to GetStringLength()", FALSE);
3385             jniEnv->ReleaseStringChars(js, stringBytes);
3386             EXCEPTION_CHECK("Getting AccessibleAction name  - call to ReleaseStringChars()", FALSE);
3387             // jniEnv->CallVoidMethod(accessBridgeObject,
3388             //                        decrementReferenceMethod, js);
3389             //EXCEPTION_CHECK("Getting AccessibleAction name  - call to CallVoidMethod()", FALSE);
3390             PrintDebugString("##### AccessibleAction name  = %ls", actions->actionInfo[i].name  );
3391             jniEnv->DeleteLocalRef(js);
3392             EXCEPTION_CHECK("Getting AccessibleAction name  - call to DeleteLocalRef()", FALSE);
3393         } else {
3394             PrintDebugString("  AccessibleAction name  is null.");
3395             actions->actionInfo[i].name [0] = (wchar_t) 0;
3396         }
3397     }
3398     return FALSE;
3399 }
3400 
3401 BOOL AccessBridgeJavaEntryPoints::doAccessibleActions(jobject accessibleContext,
3402                                                       AccessibleActionsToDo *actionsToDo,
3403                                                       jint *failure) {
3404 
3405     jthrowable exception;
3406     BOOL returnVal;
3407 
3408     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::doAccessibleActions(%p, #actions %d %s):",
3409                      accessibleContext,
3410                      actionsToDo->actionsCount,
3411                      actionsToDo->actions[0].name);
3412 
3413     if (doAccessibleActionsMethod == (jmethodID) 0) {
3414         *failure = 0;
3415         return FALSE;
3416     }
3417 
3418     PrintDebugString("\r\n    doing %d actions ...", actionsToDo->actionsCount);
3419     for (int i = 0; i < actionsToDo->actionsCount && i < MAX_ACTIONS_TO_DO; i++) {
3420         PrintDebugString("\r    doing action %d: %s ...", i, actionsToDo->actions[i].name);
3421 
3422         // create a Java String for the action name
3423         wchar_t *actionName = (wchar_t *)actionsToDo->actions[i].name;
3424         jstring javaName = jniEnv->NewString(actionName, (jsize)wcslen(actionName));
3425         if (javaName == 0) {
3426             PrintDebugString("\r    NewString failed");
3427             *failure = i;
3428             return FALSE;
3429         }
3430 
3431         returnVal = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, doAccessibleActionsMethod,
3432                                                     accessibleContext, javaName);
3433         jniEnv->DeleteLocalRef(javaName);
3434         EXCEPTION_CHECK("doAccessibleActions - call to CallBooleanMethod()", FALSE);
3435 
3436         if (returnVal != TRUE) {
3437             PrintDebugString("\r    Action %d failed", i);
3438             *failure = i;
3439             return FALSE;
3440         }
3441     }
3442     *failure = -1;
3443     return TRUE;
3444 }
3445 
3446 
3447 /********** AccessibleText routines ***********************************/
3448 
3449 BOOL
3450 AccessBridgeJavaEntryPoints::getAccessibleTextInfo(jobject accessibleContext,
3451                                                    AccessibleTextInfo *textInfo,
3452                                                    jint x, jint y) {
3453     jthrowable exception;
3454 
3455     // Verify the Java VM still exists and AccessibleContext is
3456     // an instance of AccessibleText
3457     if (verifyAccessibleText(accessibleContext) == FALSE) {
3458         return FALSE;
3459     }
3460 
3461     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextInfo(%p, %d, %d):",
3462                      accessibleContext, x, y);
3463 
3464     // Get the character count
3465     if (getAccessibleCharCountFromContextMethod != (jmethodID) 0) {
3466         textInfo->charCount = jniEnv->CallIntMethod(accessBridgeObject,
3467                                                     getAccessibleCharCountFromContextMethod,
3468                                                     accessibleContext);
3469         EXCEPTION_CHECK("Getting AccessibleCharCount - call to CallIntMethod()", FALSE);
3470         PrintDebugString("  Char count = %d", textInfo->charCount);
3471     } else {
3472         PrintDebugString("  Error! either env == 0 or getAccessibleCharCountFromContextMethod == 0");
3473         return FALSE;
3474     }
3475 
3476     // Get the index of the caret
3477     if (getAccessibleCaretPositionFromContextMethod != (jmethodID) 0) {
3478         textInfo->caretIndex = jniEnv->CallIntMethod(accessBridgeObject,
3479                                                      getAccessibleCaretPositionFromContextMethod,
3480                                                      accessibleContext);
3481         EXCEPTION_CHECK("Getting AccessibleCaretPosition - call to CallIntMethod()", FALSE);
3482         PrintDebugString("  Index at caret = %d", textInfo->caretIndex);
3483     } else {
3484         PrintDebugString("  Error! either env == 0 or getAccessibleCaretPositionFromContextMethod == 0");
3485         return FALSE;
3486     }
3487 
3488     // Get the index at the given point
3489     if (getAccessibleIndexAtPointFromContextMethod != (jmethodID) 0) {
3490         // If x or y is -1 return -1
3491         if (x == -1 || y == -1) {
3492             textInfo->indexAtPoint = -1;
3493         } else {
3494             textInfo->indexAtPoint = jniEnv->CallIntMethod(accessBridgeObject,
3495                                                            getAccessibleIndexAtPointFromContextMethod,
3496                                                            accessibleContext, x, y);
3497             EXCEPTION_CHECK("Getting AccessibleIndexAtPoint - call to CallIntMethod()", FALSE);
3498         }
3499         PrintDebugString("  Index at point = %d", textInfo->indexAtPoint);
3500     } else {
3501         PrintDebugString("  Error! either env == 0 or getAccessibleIndexAtPointFromContextMethod == 0");
3502         return FALSE;
3503     }
3504     return TRUE;
3505 }
3506 
3507 BOOL
3508 AccessBridgeJavaEntryPoints::getAccessibleTextItems(jobject accessibleContext,
3509                                                     AccessibleTextItemsInfo *textItems, jint index) {
3510     jstring js;
3511     const wchar_t *stringBytes;
3512     jthrowable exception;
3513     jsize length;
3514 
3515     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextItems(%p):", accessibleContext);
3516 
3517     // Verify the Java VM still exists and AccessibleContext is
3518     // an instance of AccessibleText
3519     if (verifyAccessibleText(accessibleContext) == FALSE) {
3520         return FALSE;
3521     }
3522 
3523     // Get the letter at index
3524     if (getAccessibleLetterAtIndexFromContextMethod != (jmethodID) 0) {
3525         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3526                                                 getAccessibleLetterAtIndexFromContextMethod,
3527                                                 accessibleContext, index);
3528         EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallIntMethod()", FALSE);
3529         PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
3530         if (js != (jstring) 0) {
3531             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3532             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to GetStringChars()", FALSE);
3533             textItems->letter = stringBytes[0];
3534             jniEnv->ReleaseStringChars(js, stringBytes);
3535             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to ReleaseStringChars()", FALSE);
3536             jniEnv->CallVoidMethod(accessBridgeObject,
3537                                    decrementReferenceMethod, js);
3538             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallVoidMethod()", FALSE);
3539             PrintDebugString("  Accessible Text letter = %c", textItems->letter);
3540             jniEnv->DeleteLocalRef(js);
3541             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to DeleteLocalRef()", FALSE);
3542         } else {
3543             PrintDebugString("  Accessible Text letter is null.");
3544             textItems->letter = (wchar_t) 0;
3545         }
3546     } else {
3547         PrintDebugString("  Error! either env == 0 or getAccessibleLetterAtIndexFromContextMethod == 0");
3548         return FALSE;
3549     }
3550 
3551 
3552     // Get the word at index
3553     if (getAccessibleWordAtIndexFromContextMethod != (jmethodID) 0) {
3554         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3555                                                 getAccessibleWordAtIndexFromContextMethod,
3556                                                 accessibleContext, index);
3557         EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallIntMethod()", FALSE);
3558         PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
3559         if (js != (jstring) 0) {
3560             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3561             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringChars()", FALSE);
3562             wcsncpy(textItems->word, stringBytes, (sizeof(textItems->word) / sizeof(wchar_t)));
3563             length = jniEnv->GetStringLength(js);
3564             textItems->word[length < (sizeof(textItems->word) / sizeof(wchar_t)) ?
3565                             length : (sizeof(textItems->word) / sizeof(wchar_t))-2] = (wchar_t) 0;
3566             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringLength()", FALSE);
3567             jniEnv->ReleaseStringChars(js, stringBytes);
3568             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to ReleaseStringChars()", FALSE);
3569             jniEnv->CallVoidMethod(accessBridgeObject,
3570                                    decrementReferenceMethod, js);
3571             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallVoidMethod()", FALSE);
3572             wPrintDebugString(L"  Accessible Text word = %ls", textItems->word);
3573             jniEnv->DeleteLocalRef(js);
3574             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to DeleteLocalRef()", FALSE);
3575         } else {
3576             PrintDebugString("  Accessible Text word is null.");
3577             textItems->word[0] = (wchar_t) 0;
3578         }
3579     } else {
3580         PrintDebugString("  Error! either env == 0 or getAccessibleWordAtIndexFromContextMethod == 0");
3581         return FALSE;
3582     }
3583 
3584     // Get the sentence at index
3585     if (getAccessibleSentenceAtIndexFromContextMethod != (jmethodID) 0) {
3586         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3587                                                 getAccessibleSentenceAtIndexFromContextMethod,
3588                                                 accessibleContext, index);
3589         EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallObjectMethod()", FALSE);
3590         PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
3591         if (js != (jstring) 0) {
3592             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3593             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringChars()", FALSE);
3594             wcsncpy(textItems->sentence, stringBytes, (sizeof(textItems->sentence) / sizeof(wchar_t))-2);
3595             length = jniEnv->GetStringLength(js);
3596 
3597             if (length < sizeof(textItems->sentence) / sizeof(wchar_t)) {
3598                 textItems->sentence[length] = (wchar_t) 0;
3599             } else {
3600                 textItems->sentence[(sizeof(textItems->sentence) / sizeof(wchar_t))-2] = (wchar_t) 0;
3601             }
3602             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringLength()", FALSE);
3603             jniEnv->ReleaseStringChars(js, stringBytes);
3604             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to ReleaseStringChars()", FALSE);
3605             jniEnv->CallVoidMethod(accessBridgeObject,
3606                                    decrementReferenceMethod, js);
3607             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallVoidMethod()", FALSE);
3608             wPrintDebugString(L"  Accessible Text sentence = %ls", textItems->sentence);
3609             jniEnv->DeleteLocalRef(js);
3610             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to DeleteLocalRef()", FALSE);
3611         } else {
3612             PrintDebugString("  Accessible Text sentence is null.");
3613             textItems->sentence[0] = (wchar_t) 0;
3614         }
3615     } else {
3616         PrintDebugString("  Error! either env == 0 or getAccessibleSentenceAtIndexFromContextMethod == 0");
3617         return FALSE;
3618     }
3619 
3620     return TRUE;
3621 }
3622 
3623 BOOL
3624 AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(jobject accessibleContext,
3625                                                             AccessibleTextSelectionInfo *selectionInfo) {
3626     jstring js;
3627     const wchar_t *stringBytes;
3628     jthrowable exception;
3629     jsize length;
3630 
3631     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(%p):",
3632                      accessibleContext);
3633 
3634     // Verify the Java VM still exists and AccessibleContext is
3635     // an instance of AccessibleText
3636     if (verifyAccessibleText(accessibleContext) == FALSE) {
3637         return FALSE;
3638     }
3639 
3640     // Get the selection start index
3641     if (getAccessibleTextSelectionStartFromContextMethod != (jmethodID) 0) {
3642         selectionInfo->selectionStartIndex = jniEnv->CallIntMethod(accessBridgeObject,
3643                                                                    getAccessibleTextSelectionStartFromContextMethod,
3644                                                                    accessibleContext);
3645         EXCEPTION_CHECK("Getting AccessibleTextSelectionStart - call to CallIntMethod()", FALSE);
3646         PrintDebugString("  Selection start = %d", selectionInfo->selectionStartIndex);
3647     } else {
3648         PrintDebugString("  Error! either env == 0 or getAccessibleTextSelectionStartFromContextMethod == 0");
3649         return FALSE;
3650     }
3651 
3652     // Get the selection end index
3653     if (getAccessibleTextSelectionEndFromContextMethod != (jmethodID) 0) {
3654         selectionInfo->selectionEndIndex = jniEnv->CallIntMethod(accessBridgeObject,
3655                                                                  getAccessibleTextSelectionEndFromContextMethod,
3656                                                                  accessibleContext);
3657         EXCEPTION_CHECK("Getting AccessibleTextSelectionEnd - call to CallIntMethod()", FALSE);
3658         PrintDebugString("  Selection end = %d", selectionInfo->selectionEndIndex);
3659     } else {
3660         PrintDebugString("  Error! either env == 0 or getAccessibleTextSelectionEndFromContextMethod == 0");
3661         return FALSE;
3662     }
3663 
3664     // Get the selected text
3665     if (getAccessibleTextSelectedTextFromContextMethod != (jmethodID) 0) {
3666         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3667                                                 getAccessibleTextSelectedTextFromContextMethod,
3668                                                 accessibleContext);
3669         EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallObjectMethod()", FALSE);
3670         PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
3671         if (js != (jstring) 0) {
3672             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3673             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringChars()", FALSE);
3674             wcsncpy(selectionInfo->selectedText, stringBytes, (sizeof(selectionInfo->selectedText) / sizeof(wchar_t)));
3675             length = jniEnv->GetStringLength(js);
3676             selectionInfo->selectedText[length < (sizeof(selectionInfo->selectedText) / sizeof(wchar_t)) ?
3677                                         length : (sizeof(selectionInfo->selectedText) / sizeof(wchar_t))-2] = (wchar_t) 0;
3678             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringLength()", FALSE);
3679             jniEnv->ReleaseStringChars(js, stringBytes);
3680             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to ReleaseStringChars()", FALSE);
3681             jniEnv->CallVoidMethod(accessBridgeObject,
3682                                    decrementReferenceMethod, js);
3683             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallVoidMethod()", FALSE);
3684             PrintDebugString("  Accessible's selected text = %s", selectionInfo->selectedText);
3685             jniEnv->DeleteLocalRef(js);
3686             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to DeleteLocalRef()", FALSE);
3687         } else {
3688             PrintDebugString("  Accessible's selected text is null.");
3689             selectionInfo->selectedText[0] = (wchar_t) 0;
3690         }
3691     } else {
3692         PrintDebugString("  Error! either env == 0 or getAccessibleTextSelectedTextFromContextMethod == 0");
3693         return FALSE;
3694     }
3695     return TRUE;
3696 }
3697 
3698 BOOL
3699 AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleContext, jint index, AccessibleTextAttributesInfo *attributes) {
3700     jstring js;
3701     const wchar_t *stringBytes;
3702     jobject AttributeSet;
3703     jthrowable exception;
3704     jsize length;
3705 
3706     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(%p):", accessibleContext);
3707 
3708     // Verify the Java VM still exists and AccessibleContext is
3709     // an instance of AccessibleText
3710     if (verifyAccessibleText(accessibleContext) == FALSE) {
3711         return FALSE;
3712     }
3713 
3714     if (accessibleContext == (jobject) 0) {
3715         PrintDebugString(" passed in AccessibleContext == null! (oops)");
3716 
3717         attributes->bold = FALSE;
3718         attributes->italic = FALSE;
3719         attributes->underline = FALSE;
3720         attributes->strikethrough = FALSE;
3721         attributes->superscript = FALSE;
3722         attributes->subscript = FALSE;
3723         attributes->backgroundColor[0] = (wchar_t) 0;
3724         attributes->foregroundColor[0] = (wchar_t) 0;
3725         attributes->fontFamily[0] = (wchar_t) 0;
3726         attributes->fontSize = -1;
3727         attributes->alignment = -1;
3728         attributes->bidiLevel = -1;
3729         attributes->firstLineIndent = -1;
3730         attributes->leftIndent = -1;
3731         attributes->rightIndent = -1;
3732         attributes->lineSpacing = -1;
3733         attributes->spaceAbove = -1;
3734         attributes->spaceBelow = -1;
3735         attributes->fullAttributesString[0] = (wchar_t) 0;
3736 
3737         return (FALSE);
3738     }
3739 
3740     // Get the AttributeSet
3741     if (getAccessibleAttributeSetAtIndexFromContextMethod != (jmethodID) 0) {
3742         PrintDebugString(" Getting AttributeSet at index...");
3743         AttributeSet = jniEnv->CallObjectMethod(accessBridgeObject,
3744                                                 getAccessibleAttributeSetAtIndexFromContextMethod,
3745                                                 accessibleContext, index);
3746         EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to CallObjectMethod()", FALSE);
3747     } else {
3748         PrintDebugString("  Error! either env == 0 or getAccessibleAttributeSetAtIndexFromContextMethod == 0");
3749         return FALSE;
3750     }
3751 
3752     // It is legal for the AttributeSet object to be null, in which case we return false!
3753     if (AttributeSet == (jobject) 0) {
3754         PrintDebugString(" AttributeSet returned at index is null (this is legal! - see AWT in J2SE 1.3");
3755 
3756         attributes->bold = FALSE;
3757         attributes->italic = FALSE;
3758         attributes->underline = FALSE;
3759         attributes->strikethrough = FALSE;
3760         attributes->superscript = FALSE;
3761         attributes->subscript = FALSE;
3762         attributes->backgroundColor[0] = (wchar_t) 0;
3763         attributes->foregroundColor[0] = (wchar_t) 0;
3764         attributes->fontFamily[0] = (wchar_t) 0;
3765         attributes->fontSize = -1;
3766         attributes->alignment = -1;
3767         attributes->bidiLevel = -1;
3768         attributes->firstLineIndent = -1;
3769         attributes->leftIndent = -1;
3770         attributes->rightIndent = -1;
3771         attributes->lineSpacing = -1;
3772         attributes->spaceAbove = -1;
3773         attributes->spaceBelow = -1;
3774         attributes->fullAttributesString[0] = (wchar_t) 0;
3775 
3776         return (FALSE);
3777     }
3778 
3779     // Get the bold setting
3780     if (getBoldFromAttributeSetMethod != (jmethodID) 0) {
3781         PrintDebugString(" Getting bold from AttributeSet...");
3782         attributes->bold = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3783                                                             getBoldFromAttributeSetMethod,
3784                                                             AttributeSet);
3785         EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallBooleanMethod()", FALSE);
3786     } else {
3787         PrintDebugString("  Error! either env == 0 or getBoldFromAttributeSetMethod == 0");
3788         jniEnv->CallVoidMethod(accessBridgeObject,
3789                                decrementReferenceMethod, AttributeSet);
3790         EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallVoidMethod()", FALSE);
3791         jniEnv->DeleteLocalRef(AttributeSet);
3792         EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to DeleteLocalRef()", FALSE);
3793         return FALSE;
3794     }
3795 
3796     // Get the italic setting
3797     if (getItalicFromAttributeSetMethod != (jmethodID) 0) {
3798         PrintDebugString(" Getting italic from AttributeSet...");
3799         attributes->italic = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3800                                                               getItalicFromAttributeSetMethod,
3801                                                               AttributeSet);
3802         EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallBooleanMethod()", FALSE);
3803     } else {
3804         PrintDebugString("  Error! either env == 0 or getItalicdFromAttributeSetMethod == 0");
3805         jniEnv->CallVoidMethod(accessBridgeObject,
3806                                decrementReferenceMethod, AttributeSet);
3807         EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallVoidMethod()", FALSE);
3808         jniEnv->DeleteLocalRef(AttributeSet);
3809         EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to DeleteLocalRef()", FALSE);
3810         return FALSE;
3811     }
3812 
3813     // Get the underline setting
3814     if (getUnderlineFromAttributeSetMethod != (jmethodID) 0) {
3815         PrintDebugString(" Getting underline from AttributeSet...");
3816         attributes->underline = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3817                                                                  getUnderlineFromAttributeSetMethod,
3818                                                                  AttributeSet);
3819         EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallBooleanMethod()", FALSE);
3820     } else {
3821         PrintDebugString("  Error! either env == 0 or getUnderlineFromAttributeSetMethod == 0");
3822         jniEnv->CallVoidMethod(accessBridgeObject,
3823                                decrementReferenceMethod, AttributeSet);
3824         EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallVoidMethod()", FALSE);
3825         jniEnv->DeleteLocalRef(AttributeSet);
3826         EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to DeleteLocalRef()", FALSE);
3827         return FALSE;
3828     }
3829 
3830     // Get the strikethrough setting
3831     if (getStrikethroughFromAttributeSetMethod != (jmethodID) 0) {
3832         PrintDebugString(" Getting strikethrough from AttributeSet...");
3833         attributes->strikethrough = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3834                                                                      getStrikethroughFromAttributeSetMethod,
3835                                                                      AttributeSet);
3836         EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallBooleanMethod()", FALSE);
3837     } else {
3838         PrintDebugString("  Error! either env == 0 or getStrikethroughFromAttributeSetMethod == 0");
3839         jniEnv->CallVoidMethod(accessBridgeObject,
3840                                decrementReferenceMethod, AttributeSet);
3841         EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallVoidMethod()", FALSE);
3842         jniEnv->DeleteLocalRef(AttributeSet);
3843         EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to DeleteLocalRef()", FALSE);
3844         return FALSE;
3845     }
3846 
3847     // Get the superscript setting
3848     if (getSuperscriptFromAttributeSetMethod != (jmethodID) 0) {
3849         PrintDebugString(" Getting superscript from AttributeSet...");
3850         attributes->superscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3851                                                                    getSuperscriptFromAttributeSetMethod,
3852                                                                    AttributeSet);
3853         EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallBooleanMethod()", FALSE);
3854     } else {
3855         PrintDebugString("  Error! either env == 0 or getSuperscripteFromAttributeSetMethod == 0");
3856         jniEnv->CallVoidMethod(accessBridgeObject,
3857                                decrementReferenceMethod, AttributeSet);
3858         EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallVoidMethod()", FALSE);
3859         jniEnv->DeleteLocalRef(AttributeSet);
3860         EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to DeleteLocalRef()", FALSE);
3861         return FALSE;
3862     }
3863 
3864     // Get the subscript setting
3865     if (getSubscriptFromAttributeSetMethod != (jmethodID) 0) {
3866         PrintDebugString(" Getting subscript from AttributeSet...");
3867         attributes->subscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3868                                                                  getSubscriptFromAttributeSetMethod,
3869                                                                  AttributeSet);
3870         EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallBooleanMethod()", FALSE);
3871     } else {
3872         PrintDebugString("  Error! either env == 0 or getSubscriptFromAttributeSetMethod == 0");
3873         jniEnv->CallVoidMethod(accessBridgeObject,
3874                                decrementReferenceMethod, AttributeSet);
3875         EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallVoidMethod()", FALSE);
3876         jniEnv->DeleteLocalRef(AttributeSet);
3877         EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to DeleteLocalRef()", FALSE);
3878         return FALSE;
3879     }
3880 
3881     // Get the backgroundColor setting
3882     if (getBackgroundColorFromAttributeSetMethod != (jmethodID) 0) {
3883         PrintDebugString(" Getting backgroundColor from AttributeSet...");
3884         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3885                                                 getBackgroundColorFromAttributeSetMethod,
3886                                                 AttributeSet);
3887         EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallObjectMethod()", FALSE);
3888         if (js != (jstring) 0) {
3889             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3890             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringChars()", FALSE);
3891             wcsncpy(attributes->backgroundColor, stringBytes, (sizeof(attributes->backgroundColor) / sizeof(wchar_t)));
3892             length = jniEnv->GetStringLength(js);
3893             attributes->backgroundColor[length < (sizeof(attributes->backgroundColor) / sizeof(wchar_t)) ?
3894                                         length : (sizeof(attributes->backgroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0;
3895             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringLength()", FALSE);
3896             jniEnv->ReleaseStringChars(js, stringBytes);
3897             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE);
3898             jniEnv->CallVoidMethod(accessBridgeObject,
3899                                    decrementReferenceMethod, js);
3900             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3901             wPrintDebugString(L"  AttributeSet's background color = %ls", attributes->backgroundColor);
3902             jniEnv->DeleteLocalRef(js);
3903             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3904         } else {
3905             PrintDebugString("  AttributeSet's background color is null.");
3906             attributes->backgroundColor[0] = (wchar_t) 0;
3907         }
3908     } else {
3909         PrintDebugString("  Error! either env == 0 or getBackgroundColorFromAttributeSetMethod == 0");
3910         jniEnv->CallVoidMethod(accessBridgeObject,
3911                                decrementReferenceMethod, AttributeSet);
3912         EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3913         jniEnv->DeleteLocalRef(AttributeSet);
3914         EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3915         return FALSE;
3916     }
3917 
3918     // Get the foregroundColor setting
3919     if (getForegroundColorFromAttributeSetMethod != (jmethodID) 0) {
3920         PrintDebugString(" Getting foregroundColor from AttributeSet...");
3921         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3922                                                 getForegroundColorFromAttributeSetMethod,
3923                                                 AttributeSet);
3924         EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallObjectMethod()", FALSE);
3925         if (js != (jstring) 0) {
3926             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3927             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringChars()", FALSE);
3928             wcsncpy(attributes->foregroundColor, stringBytes, (sizeof(attributes->foregroundColor) / sizeof(wchar_t)));
3929             length = jniEnv->GetStringLength(js);
3930             attributes->foregroundColor[length < (sizeof(attributes->foregroundColor) / sizeof(wchar_t)) ?
3931                                         length : (sizeof(attributes->foregroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0;
3932             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringLength()", FALSE);
3933             jniEnv->ReleaseStringChars(js, stringBytes);
3934             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE);
3935             jniEnv->CallVoidMethod(accessBridgeObject,
3936                                    decrementReferenceMethod, js);
3937             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3938             wPrintDebugString(L"  AttributeSet's foreground color = %ls", attributes->foregroundColor);
3939             jniEnv->DeleteLocalRef(js);
3940             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3941         } else {
3942             PrintDebugString("  AttributeSet's foreground color is null.");
3943             attributes->foregroundColor[0] = (wchar_t) 0;
3944         }
3945     } else {
3946         PrintDebugString("  Error! either env == 0 or getForegroundColorFromAttributeSetMethod == 0");
3947         jniEnv->CallVoidMethod(accessBridgeObject,
3948                                decrementReferenceMethod, AttributeSet);
3949         EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3950         jniEnv->DeleteLocalRef(AttributeSet);
3951         EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3952         return FALSE;
3953     }
3954 
3955     // Get the fontFamily setting
3956     if (getFontFamilyFromAttributeSetMethod != (jmethodID) 0) {
3957         PrintDebugString(" Getting fontFamily from AttributeSet...");
3958         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3959                                                 getFontFamilyFromAttributeSetMethod,
3960                                                 AttributeSet);
3961         EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallObjectMethod()", FALSE);
3962         if (js != (jstring) 0) {
3963             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3964             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringChars()", FALSE);
3965             wcsncpy(attributes->fontFamily, stringBytes, (sizeof(attributes->fontFamily) / sizeof(wchar_t)));
3966             length = jniEnv->GetStringLength(js);
3967             attributes->fontFamily[length < (sizeof(attributes->fontFamily) / sizeof(wchar_t)) ?
3968                                    length : (sizeof(attributes->fontFamily) / sizeof(wchar_t))-2] = (wchar_t) 0;
3969             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringLength()", FALSE);
3970             jniEnv->ReleaseStringChars(js, stringBytes);
3971             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to ReleaseStringChars()", FALSE);
3972             jniEnv->CallVoidMethod(accessBridgeObject,
3973                                    decrementReferenceMethod, js);
3974             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE);
3975             wPrintDebugString(L"  AttributeSet's fontFamily = %ls", attributes->fontFamily);
3976             jniEnv->DeleteLocalRef(js);
3977             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE);
3978         } else {
3979             PrintDebugString("  AttributeSet's fontFamily is null.");
3980             attributes->backgroundColor[0] = (wchar_t) 0;
3981         }
3982     } else {
3983         PrintDebugString("  Error! either env == 0 or getFontFamilyFromAttributeSetMethod == 0");
3984         jniEnv->CallVoidMethod(accessBridgeObject,
3985                                decrementReferenceMethod, AttributeSet);
3986         EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE);
3987         jniEnv->DeleteLocalRef(AttributeSet);
3988         EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE);
3989         return FALSE;
3990     }
3991 
3992     // Get the font size
3993     if (getFontSizeFromAttributeSetMethod != (jmethodID) 0) {
3994         PrintDebugString(" Getting font size from AttributeSet...");
3995         attributes->fontSize = jniEnv->CallIntMethod(accessBridgeObject,
3996                                                      getFontSizeFromAttributeSetMethod,
3997                                                      AttributeSet);
3998         EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallIntMethod()", FALSE);
3999         PrintDebugString("  AttributeSet's font size = %d", attributes->fontSize);
4000     } else {
4001         PrintDebugString("  Error! either env == 0 or getAlignmentFromAttributeSetMethod == 0");
4002         jniEnv->CallVoidMethod(accessBridgeObject,
4003                                decrementReferenceMethod, AttributeSet);
4004         EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallVoidMethod()", FALSE);
4005         jniEnv->DeleteLocalRef(AttributeSet);
4006         EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to DeleteLocalRef()", FALSE);
4007         return FALSE;
4008     }
4009 
4010 
4011     // Get the alignment setting
4012     if (getAlignmentFromAttributeSetMethod != (jmethodID) 0) {
4013         PrintDebugString(" Getting alignment from AttributeSet...");
4014         attributes->alignment = jniEnv->CallIntMethod(accessBridgeObject,
4015                                                       getAlignmentFromAttributeSetMethod,
4016                                                       AttributeSet);
4017         EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallIntMethod()", FALSE);
4018     } else {
4019         PrintDebugString("  Error! either env == 0 or getAlignmentFromAttributeSetMethod == 0");
4020         jniEnv->CallVoidMethod(accessBridgeObject,
4021                                decrementReferenceMethod, AttributeSet);
4022         EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallVoidMethod()", FALSE);
4023         jniEnv->DeleteLocalRef(AttributeSet);
4024         EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4025         return FALSE;
4026     }
4027 
4028     // Get the bidiLevel setting
4029     if (getBidiLevelFromAttributeSetMethod != (jmethodID) 0) {
4030         PrintDebugString(" Getting bidiLevel from AttributeSet...");
4031         attributes->bidiLevel = jniEnv->CallIntMethod(accessBridgeObject,
4032                                                       getBidiLevelFromAttributeSetMethod,
4033                                                       AttributeSet);
4034         EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallIntMethod()", FALSE);
4035     } else {
4036         PrintDebugString("  Error! either env == 0 or getBidiLevelFromAttributeSetMethod == 0");
4037         jniEnv->CallVoidMethod(accessBridgeObject,
4038                                decrementReferenceMethod, AttributeSet);
4039         EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallVoidMethod()", FALSE);
4040         jniEnv->DeleteLocalRef(AttributeSet);
4041         EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to DeleteLocalRef()", FALSE);
4042         return FALSE;
4043     }
4044 
4045     // Get the firstLineIndent setting
4046     if (getFirstLineIndentFromAttributeSetMethod != (jmethodID) 0) {
4047         PrintDebugString(" Getting firstLineIndent from AttributeSet...");
4048         attributes->firstLineIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4049                                                                        getFirstLineIndentFromAttributeSetMethod,
4050                                                                        AttributeSet);
4051         EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallIntMethod()", FALSE);
4052     } else {
4053         PrintDebugString("  Error! either env == 0 or getFirstLineIndentFromAttributeSetMethod == 0");
4054         jniEnv->CallVoidMethod(accessBridgeObject,
4055                                decrementReferenceMethod, AttributeSet);
4056         EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
4057         jniEnv->DeleteLocalRef(AttributeSet);
4058         EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4059         return FALSE;
4060     }
4061 
4062     // Get the leftIndent setting
4063     if (getLeftIndentFromAttributeSetMethod != (jmethodID) 0) {
4064         PrintDebugString(" Getting leftIndent from AttributeSet...");
4065         attributes->leftIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4066                                                                   getLeftIndentFromAttributeSetMethod,
4067                                                                   AttributeSet);
4068         EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallIntMethod()", FALSE);
4069     } else {
4070         PrintDebugString("  Error! either env == 0 or getLeftIndentFromAttributeSetMethod == 0");
4071         jniEnv->CallVoidMethod(accessBridgeObject,
4072                                decrementReferenceMethod, AttributeSet);
4073         EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
4074         jniEnv->DeleteLocalRef(AttributeSet);
4075         EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4076         return FALSE;
4077     }
4078 
4079     // Get the rightIndent setting
4080     if (getRightIndentFromAttributeSetMethod != (jmethodID) 0) {
4081         PrintDebugString(" Getting rightIndent from AttributeSet...");
4082         attributes->rightIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4083                                                                    getRightIndentFromAttributeSetMethod,
4084                                                                    AttributeSet);
4085         EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallIntMethod()", FALSE);
4086     } else {
4087         PrintDebugString("  Error! either env == 0 or getRightIndentFromAttributeSetMethod == 0");
4088         jniEnv->CallVoidMethod(accessBridgeObject,
4089                                decrementReferenceMethod, AttributeSet);
4090         EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
4091         jniEnv->DeleteLocalRef(AttributeSet);
4092         EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4093         return FALSE;
4094     }
4095 
4096     // Get the lineSpacing setting
4097     if (getLineSpacingFromAttributeSetMethod != (jmethodID) 0) {
4098         PrintDebugString(" Getting lineSpacing from AttributeSet...");
4099         attributes->lineSpacing = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4100                                                                    getLineSpacingFromAttributeSetMethod,
4101                                                                    AttributeSet);
4102         EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallIntMethod()", FALSE);
4103     } else {
4104         PrintDebugString("  Error! either env == 0 or getLineSpacingFromAttributeSetMethod == 0");
4105         jniEnv->CallVoidMethod(accessBridgeObject,
4106                                decrementReferenceMethod, AttributeSet);
4107         EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallVoidMethod()", FALSE);
4108         jniEnv->DeleteLocalRef(AttributeSet);
4109         EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to DeleteLocalRef()", FALSE);
4110         return FALSE;
4111     }
4112 
4113     // Get the spaceAbove setting
4114     if (getSpaceAboveFromAttributeSetMethod != (jmethodID) 0) {
4115         PrintDebugString(" Getting spaceAbove from AttributeSet...");
4116         attributes->spaceAbove = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4117                                                                   getSpaceAboveFromAttributeSetMethod,
4118                                                                   AttributeSet);
4119         EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallIntMethod()", FALSE);
4120     } else {
4121         PrintDebugString("  Error! either env == 0 or getSpaceAboveFromAttributeSetMethod == 0");
4122         jniEnv->CallVoidMethod(accessBridgeObject,
4123                                decrementReferenceMethod, AttributeSet);
4124         EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallVoidMethod()", FALSE);
4125         jniEnv->DeleteLocalRef(AttributeSet);
4126         EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to DeleteLocalRef()", FALSE);
4127         return FALSE;
4128     }
4129 
4130     // Get the spaceBelow setting
4131     if (getSpaceBelowFromAttributeSetMethod != (jmethodID) 0) {
4132         PrintDebugString(" Getting spaceBelow from AttributeSet...");
4133         attributes->spaceBelow = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4134                                                                   getSpaceBelowFromAttributeSetMethod,
4135                                                                   AttributeSet);
4136         EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallIntMethod()", FALSE);
4137     } else {
4138         PrintDebugString("  Error! either env == 0 or getSpaceBelowFromAttributeSetMethod == 0");
4139         jniEnv->CallVoidMethod(accessBridgeObject,
4140                                decrementReferenceMethod, AttributeSet);
4141         EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallVoidMethod()", FALSE);
4142         jniEnv->DeleteLocalRef(AttributeSet);
4143         EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to DeleteLocalRef()", FALSE);
4144         return FALSE;
4145     }
4146 
4147     // Release the AttributeSet object
4148     if (decrementReferenceMethod != (jmethodID) 0) {
4149         PrintDebugString(" Decrementing reference to AttributeSet...");
4150         jniEnv->CallVoidMethod(accessBridgeObject,
4151                                decrementReferenceMethod, AttributeSet);
4152         EXCEPTION_CHECK("Releasing AttributeSet object - call to CallVoidMethod()", FALSE);
4153     } else {
4154         PrintDebugString("  Error! either env == 0 or accessBridgeObject == 0");
4155         jniEnv->DeleteLocalRef(AttributeSet);
4156         EXCEPTION_CHECK("Releasing AttributeSet object - call to DeleteLocalRef()", FALSE);
4157         return FALSE;
4158     }
4159 
4160     // Get the full attributes string at index
4161     if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) {
4162         PrintDebugString(" Getting full attributes string from Context...");
4163         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4164                                                 getAccessibleAttributesAtIndexFromContextMethod,
4165                                                 accessibleContext, index);
4166         EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE);
4167         PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
4168         if (js != (jstring) 0) {
4169             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4170             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE);
4171             wcsncpy(attributes->fullAttributesString, stringBytes, (sizeof(attributes->fullAttributesString) / sizeof(wchar_t)));
4172             length = jniEnv->GetStringLength(js);
4173             attributes->fullAttributesString[length < (sizeof(attributes->fullAttributesString) / sizeof(wchar_t)) ?
4174                                              length : (sizeof(attributes->fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0;
4175             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE);
4176             jniEnv->ReleaseStringChars(js, stringBytes);
4177             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE);
4178             jniEnv->CallVoidMethod(accessBridgeObject,
4179                                    decrementReferenceMethod, js);
4180             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE);
4181             wPrintDebugString(L"  Accessible Text attributes = %ls", attributes->fullAttributesString);
4182             jniEnv->DeleteLocalRef(js);
4183             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
4184         } else {
4185             PrintDebugString("  Accessible Text attributes is null.");
4186             attributes->fullAttributesString[0] = (wchar_t) 0;
4187             jniEnv->DeleteLocalRef(AttributeSet);
4188             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
4189             return FALSE;
4190         }
4191     } else {
4192         PrintDebugString("  Error! either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0");
4193         jniEnv->DeleteLocalRef(AttributeSet);
4194         return FALSE;
4195     }
4196 
4197     jniEnv->DeleteLocalRef(AttributeSet);
4198     EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to DeleteLocalRef()", FALSE);
4199     return TRUE;
4200 }
4201 
4202 BOOL
4203 AccessBridgeJavaEntryPoints::getAccessibleTextRect(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) {
4204 
4205     jthrowable exception;
4206 
4207     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextRect(%p), index = %d",
4208                      accessibleContext, index);
4209 
4210     // Verify the Java VM still exists and AccessibleContext is
4211     // an instance of AccessibleText
4212     if (verifyAccessibleText(accessibleContext) == FALSE) {
4213         return FALSE;
4214     }
4215 
4216     // Get the x coord
4217     if (getAccessibleXcoordTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4218         rectInfo->x = jniEnv->CallIntMethod(accessBridgeObject,
4219                                             getAccessibleXcoordTextRectAtIndexFromContextMethod,
4220                                             accessibleContext, index);
4221         EXCEPTION_CHECK("Getting AccessibleXcoordTextRect - call to CallIntMethod()", FALSE);
4222         PrintDebugString("  X coord = %d", rectInfo->x);
4223     } else {
4224         PrintDebugString("  Error! either env == 0 or getAccessibleXcoordTextRectAtIndexFromContextMethod == 0");
4225         return FALSE;
4226     }
4227 
4228     // Get the y coord
4229     if (getAccessibleYcoordTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4230         rectInfo->y = jniEnv->CallIntMethod(accessBridgeObject,
4231                                             getAccessibleYcoordTextRectAtIndexFromContextMethod,
4232                                             accessibleContext, index);
4233         EXCEPTION_CHECK("Getting AccessibleYcoordTextRect - call to CallIntMethod()", FALSE);
4234         PrintDebugString("  Y coord = %d", rectInfo->y);
4235     } else {
4236         PrintDebugString("  Error! either env == 0 or getAccessibleYcoordTextRectAtIndexFromContextMethod == 0");
4237         return FALSE;
4238     }
4239 
4240     // Get the width
4241     if (getAccessibleWidthTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4242         rectInfo->width = jniEnv->CallIntMethod(accessBridgeObject,
4243                                                 getAccessibleWidthTextRectAtIndexFromContextMethod,
4244                                                 accessibleContext, index);
4245         EXCEPTION_CHECK("Getting AccessibleWidthTextRect - call to CallIntMethod()", FALSE);
4246         PrintDebugString("  Width = %d", rectInfo->width);
4247     } else {
4248         PrintDebugString("  Error! either env == 0 or getAccessibleWidthTextRectAtIndexFromContextMethod == 0");
4249         return FALSE;
4250     }
4251 
4252     // Get the height
4253     if (getAccessibleHeightTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4254         rectInfo->height = jniEnv->CallIntMethod(accessBridgeObject,
4255                                                  getAccessibleHeightTextRectAtIndexFromContextMethod,
4256                                                  accessibleContext, index);
4257         EXCEPTION_CHECK("Getting AccessibleHeightTextRect - call to CallIntMethod()", FALSE);
4258         PrintDebugString("  Height = %d", rectInfo->height);
4259     } else {
4260         PrintDebugString("  Error! either env == 0 or getAccessibleHeightTextRectAtIndexFromContextMethod == 0");
4261         return FALSE;
4262     }
4263 
4264     return TRUE;
4265 }
4266 
4267 // =====
4268 
4269 /**
4270  * gets the bounding rectangle for the text caret
4271  */
4272 BOOL
4273 AccessBridgeJavaEntryPoints::getCaretLocation(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) {
4274 
4275     jthrowable exception;
4276 
4277     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getCaretLocation(%p), index = %d",
4278                      accessibleContext, index);
4279 
4280     // Verify the Java VM still exists and AccessibleContext is
4281     // an instance of AccessibleText
4282     if (verifyAccessibleText(accessibleContext) == FALSE) {
4283         return FALSE;
4284     }
4285 
4286     // Get the x coord
4287     if (getCaretLocationXMethod != (jmethodID) 0) {
4288         rectInfo->x = jniEnv->CallIntMethod(accessBridgeObject,
4289                                             getCaretLocationXMethod,
4290                                             accessibleContext, index);
4291         EXCEPTION_CHECK("Getting caret X coordinate - call to CallIntMethod()", FALSE);
4292         PrintDebugString("  X coord = %d", rectInfo->x);
4293     } else {
4294         PrintDebugString("  Error! either env == 0 or getCaretLocationXMethod == 0");
4295         return FALSE;
4296     }
4297 
4298     // Get the y coord
4299     if (getCaretLocationYMethod != (jmethodID) 0) {
4300         rectInfo->y = jniEnv->CallIntMethod(accessBridgeObject,
4301                                             getCaretLocationYMethod,
4302                                             accessibleContext, index);
4303         EXCEPTION_CHECK("Getting caret Y coordinate - call to CallIntMethod()", FALSE);
4304         PrintDebugString("  Y coord = %d", rectInfo->y);
4305     } else {
4306         PrintDebugString("  Error! either env == 0 or getCaretLocationYMethod == 0");
4307         return FALSE;
4308     }
4309 
4310     // Get the width
4311     if (getCaretLocationWidthMethod != (jmethodID) 0) {
4312         rectInfo->width = jniEnv->CallIntMethod(accessBridgeObject,
4313                                                 getCaretLocationWidthMethod,
4314                                                 accessibleContext, index);
4315         EXCEPTION_CHECK("Getting caret width - call to CallIntMethod()", FALSE);
4316         PrintDebugString("  Width = %d", rectInfo->width);
4317     } else {
4318         PrintDebugString("  Error! either env == 0 or getCaretLocationWidthMethod == 0");
4319         return FALSE;
4320     }
4321 
4322     // Get the height
4323     if (getCaretLocationHeightMethod != (jmethodID) 0) {
4324         rectInfo->height = jniEnv->CallIntMethod(accessBridgeObject,
4325                                                  getCaretLocationHeightMethod,
4326                                                  accessibleContext, index);
4327         EXCEPTION_CHECK("Getting caret height - call to CallIntMethod()", FALSE);
4328         PrintDebugString("  Height = %d", rectInfo->height);
4329     } else {
4330         PrintDebugString("  Error! either env == 0 or getCaretLocationHeightMethod == 0");
4331         return FALSE;
4332     }
4333 
4334     return TRUE;
4335 }
4336 
4337 // =====
4338 
4339 BOOL
4340 AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(jobject accessibleContext, jint index, jint *startIndex, jint *endIndex) {
4341 
4342     jthrowable exception;
4343 
4344     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(%p):", accessibleContext);
4345 
4346     // Verify the Java VM still exists and AccessibleContext is
4347     // an instance of AccessibleText
4348     if (verifyAccessibleText(accessibleContext) == FALSE) {
4349         return FALSE;
4350     }
4351 
4352     // Get the index of the left boundary of the line containing 'index'
4353     if (getAccessibleTextLineLeftBoundsFromContextMethod != (jmethodID) 0) {
4354         *startIndex = jniEnv->CallIntMethod(accessBridgeObject,
4355                                             getAccessibleTextLineLeftBoundsFromContextMethod,
4356                                             accessibleContext, index);
4357         EXCEPTION_CHECK("Getting AccessibleTextLineLeftBounds - call to CallIntMethod()", FALSE);
4358         PrintDebugString("  startIndex = %d", *startIndex);
4359     } else {
4360         PrintDebugString("  Error! either env == 0 or getAccessibleTextLineLeftBoundsFromContextMethod == 0");
4361         return FALSE;
4362     }
4363 
4364     // Get the index of the right boundary of the line containing 'index'
4365     if (getAccessibleTextLineRightBoundsFromContextMethod != (jmethodID) 0) {
4366         *endIndex = jniEnv->CallIntMethod(accessBridgeObject,
4367                                           getAccessibleTextLineRightBoundsFromContextMethod,
4368                                           accessibleContext, index);
4369         EXCEPTION_CHECK("Getting AccessibleTextLineRightBounds - call to CallIntMethod()", FALSE);
4370         PrintDebugString("  endIndex = %d", *endIndex);
4371     } else {
4372         PrintDebugString("  Error! either env == 0 or getAccessibleTextLineRightBoundsFromContextMethod == 0");
4373         return FALSE;
4374     }
4375 
4376     return TRUE;
4377 }
4378 
4379 BOOL
4380 AccessBridgeJavaEntryPoints::getAccessibleTextRange(jobject accessibleContext,
4381                                                     jint start, jint end, wchar_t *text, short len) {
4382     jstring js;
4383     const wchar_t *stringBytes;
4384     jthrowable exception;
4385     jsize length;
4386 
4387     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextRange(%p, %d, %d, *text, %d):", accessibleContext, start, end, len);
4388 
4389     // Verify the Java VM still exists and AccessibleContext is
4390     // an instance of AccessibleText
4391     if (verifyAccessibleText(accessibleContext) == FALSE) {
4392         return FALSE;
4393     }
4394 
4395     // range is inclusive
4396     if (end < start) {
4397         PrintDebugString("  Error! end < start!");
4398         text[0] = (wchar_t) 0;
4399         return FALSE;
4400     }
4401 
4402     // Get the text range within [start, end] inclusive
4403     if (getAccessibleTextRangeFromContextMethod != (jmethodID) 0) {
4404         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4405                                                 getAccessibleTextRangeFromContextMethod,
4406                                                 accessibleContext, start, end);
4407         EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallObjectMethod()", FALSE);
4408         PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
4409         if (js != (jstring) 0) {
4410             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4411             EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringChars()", FALSE);
4412             wPrintDebugString(L"  Accessible Text stringBytes returned from Java = %ls", stringBytes);
4413             wcsncpy(text, stringBytes, len);
4414             length = jniEnv->GetStringLength(js);
4415             PrintDebugString("  Accessible Text stringBytes length = %d", length);
4416             text[length < len ? length : len - 2] = (wchar_t) 0;
4417             wPrintDebugString(L"  Accessible Text 'text' after null termination = %ls", text);
4418             EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringLength()", FALSE);
4419             jniEnv->ReleaseStringChars(js, stringBytes);
4420             EXCEPTION_CHECK("Getting AccessibleTextRange - call to ReleaseStringChars()", FALSE);
4421             jniEnv->CallVoidMethod(accessBridgeObject,
4422                                    decrementReferenceMethod, js);
4423             EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallVoidMethod()", FALSE);
4424             wPrintDebugString(L"  Accessible Text range = %ls", text);
4425             jniEnv->DeleteLocalRef(js);
4426             EXCEPTION_CHECK("Getting AccessibleTextRange - call to DeleteLocalRef()", FALSE);
4427         } else {
4428             PrintDebugString("  current Accessible Text range is null.");
4429             text[0] = (wchar_t) 0;
4430             return FALSE;
4431         }
4432     } else {
4433         PrintDebugString("  Error! either env == 0 or getAccessibleTextRangeFromContextMethod == 0");
4434         return FALSE;
4435     }
4436     return TRUE;
4437 }
4438 
4439 /********** AccessibleValue routines ***************/
4440 
4441 BOOL
4442 AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) {
4443     jstring js;
4444     const wchar_t *stringBytes;
4445     jthrowable exception;
4446     jsize length;
4447 
4448     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(%p):", accessibleContext);
4449 
4450     // Get the current Accessible Value
4451     if (getCurrentAccessibleValueFromContextMethod != (jmethodID) 0) {
4452         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4453                                                 getCurrentAccessibleValueFromContextMethod,
4454                                                 accessibleContext);
4455         EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallObjectMethod()", FALSE);
4456         PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
4457         if (js != (jstring) 0) {
4458             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4459             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringChars()", FALSE);
4460             wcsncpy(value, stringBytes, len);
4461             length = jniEnv->GetStringLength(js);
4462             value[length < len ? length : len - 2] = (wchar_t) 0;
4463             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringLength()", FALSE);
4464             jniEnv->ReleaseStringChars(js, stringBytes);
4465             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to ReleaseStringChars()", FALSE);
4466             jniEnv->CallVoidMethod(accessBridgeObject,
4467                                    decrementReferenceMethod, js);
4468             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallVoidMethod()", FALSE);
4469             PrintDebugString("  current Accessible Value = %s", value);
4470             jniEnv->DeleteLocalRef(js);
4471             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to DeleteLocalRef()", FALSE);
4472         } else {
4473             PrintDebugString("  current Accessible Value is null.");
4474             value[0] = (wchar_t) 0;
4475             return FALSE;
4476         }
4477     } else {
4478         PrintDebugString("  Error! either env == 0 or getCurrentAccessibleValueFromContextMethod == 0");
4479         return FALSE;
4480     }
4481     return TRUE;
4482 }
4483 
4484 BOOL
4485 AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) {
4486     jstring js;
4487     const wchar_t *stringBytes;
4488     jthrowable exception;
4489     jsize length;
4490 
4491     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(%p):", accessibleContext);
4492 
4493     // Get the maximum Accessible Value
4494     if (getMaximumAccessibleValueFromContextMethod != (jmethodID) 0) {
4495         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4496                                                 getMaximumAccessibleValueFromContextMethod,
4497                                                 accessibleContext);
4498         EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallObjectMethod()", FALSE);
4499         PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
4500         if (js != (jstring) 0) {
4501             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4502             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringChars()", FALSE);
4503             wcsncpy(value, stringBytes, len);
4504             length = jniEnv->GetStringLength(js);
4505             value[length < len ? length : len - 2] = (wchar_t) 0;
4506             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringLength()", FALSE);
4507             jniEnv->ReleaseStringChars(js, stringBytes);
4508             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to ReleaseStringChars()", FALSE);
4509             jniEnv->CallVoidMethod(accessBridgeObject,
4510                                    decrementReferenceMethod, js);
4511             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallVoidMethod()", FALSE);
4512             PrintDebugString("  maximum Accessible Value = %s", value);
4513             jniEnv->DeleteLocalRef(js);
4514             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to DeleteLocalRef()", FALSE);
4515         } else {
4516             PrintDebugString("  maximum Accessible Value is null.");
4517             value[0] = (wchar_t) 0;
4518             return FALSE;
4519         }
4520     } else {
4521         PrintDebugString("  Error! either env == 0 or getMaximumAccessibleValueFromContextMethod == 0");
4522         return FALSE;
4523     }
4524     return TRUE;
4525 }
4526 
4527 BOOL
4528 AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) {
4529     jstring js;
4530     const wchar_t *stringBytes;
4531     jthrowable exception;
4532     jsize length;
4533 
4534     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(%p):", accessibleContext);
4535 
4536     // Get the mimimum Accessible Value
4537     if (getMinimumAccessibleValueFromContextMethod != (jmethodID) 0) {
4538         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4539                                                 getMinimumAccessibleValueFromContextMethod,
4540                                                 accessibleContext);
4541         EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallObjectMethod()", FALSE);
4542         PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
4543         if (js != (jstring) 0) {
4544             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4545             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringChars()", FALSE);
4546             wcsncpy(value, stringBytes, len);
4547             length = jniEnv->GetStringLength(js);
4548             value[length < len ? length : len - 2] = (wchar_t) 0;
4549             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringLength()", FALSE);
4550             jniEnv->ReleaseStringChars(js, stringBytes);
4551             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to ReleaseStringChars()", FALSE);
4552             jniEnv->CallVoidMethod(accessBridgeObject,
4553                                    decrementReferenceMethod, js);
4554             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallVoidMethod()", FALSE);
4555             PrintDebugString("  mimimum Accessible Value = %s", value);
4556             jniEnv->DeleteLocalRef(js);
4557             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to DeleteLocalRef()", FALSE);
4558         } else {
4559             PrintDebugString("  mimimum Accessible Value is null.");
4560             value[0] = (wchar_t) 0;
4561             return FALSE;
4562         }
4563     } else {
4564         PrintDebugString("  Error! either env == 0 or getMinimumAccessibleValueFromContextMethod == 0");
4565         return FALSE;
4566     }
4567     return TRUE;
4568 }
4569 
4570 
4571 /********** AccessibleSelection routines ***************/
4572 
4573 void
4574 AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(jobject accessibleContext, int i) {
4575     jthrowable exception;
4576 
4577     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(%p):", accessibleContext);
4578 
4579     // Add the child to the AccessibleSelection
4580     if (addAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4581         jniEnv->CallVoidMethod(accessBridgeObject,
4582                                addAccessibleSelectionFromContextMethod,
4583                                accessibleContext, i);
4584         EXCEPTION_CHECK_VOID("Doing addAccessibleSelection - call to CallVoidMethod()");
4585         PrintDebugString("  returned from CallObjectMethod()");
4586     } else {
4587         PrintDebugString("  Error! either env == 0 or addAccessibleSelectionFromContextMethod == 0");
4588     }
4589 }
4590 
4591 void
4592 AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(jobject accessibleContext) {
4593     jthrowable exception;
4594 
4595     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(%p):", accessibleContext);
4596 
4597     // Clearing the Selection of the AccessibleSelection
4598     if (clearAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4599         jniEnv->CallVoidMethod(accessBridgeObject,
4600                                clearAccessibleSelectionFromContextMethod,
4601                                accessibleContext);
4602         EXCEPTION_CHECK_VOID("Doing clearAccessibleSelection - call to CallVoidMethod()");
4603         PrintDebugString("  returned from CallObjectMethod()");
4604     } else {
4605         PrintDebugString("  Error! either env == 0 or clearAccessibleSelectionFromContextMethod == 0");
4606     }
4607 }
4608 
4609 jobject
4610 AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(jobject accessibleContext, int i) {
4611     jobject returnedAccessibleContext;
4612     jobject globalRef;
4613     jthrowable exception;
4614 
4615     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(%p):", accessibleContext);
4616 
4617     if (getAccessibleSelectionContextFromContextMethod != (jmethodID) 0) {
4618         returnedAccessibleContext = jniEnv->CallObjectMethod(
4619                                                              accessBridgeObject,
4620                                                              getAccessibleSelectionContextFromContextMethod,
4621                                                              accessibleContext, i);
4622         EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to CallObjectMethod()", (jobject) 0);
4623         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
4624         EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to NewGlobalRef()", (jobject) 0);
4625         jniEnv->DeleteLocalRef(returnedAccessibleContext);
4626         EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to DeleteLocalRef()", (jobject) 0);
4627         PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
4628                          returnedAccessibleContext, globalRef);
4629         return globalRef;
4630     } else {
4631         PrintDebugString("  Error! either env == 0 or getAccessibleSelectionContextFromContextMethod == 0");
4632         return (jobject) 0;
4633     }
4634 }
4635 
4636 int
4637 AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(jobject accessibleContext) {
4638     int count;
4639     jthrowable exception;
4640 
4641     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(%p):", accessibleContext);
4642 
4643     // Get (& return) the # of items selected in the AccessibleSelection
4644     if (getAccessibleSelectionCountFromContextMethod != (jmethodID) 0) {
4645         count = jniEnv->CallIntMethod(accessBridgeObject,
4646                                       getAccessibleSelectionCountFromContextMethod,
4647                                       accessibleContext);
4648         EXCEPTION_CHECK("Getting AccessibleSelectionCount - call to CallIntMethod()", -1);
4649         PrintDebugString("  returned from CallObjectMethod()");
4650         return count;
4651     } else {
4652         PrintDebugString("  Error! either env == 0 or getAccessibleSelectionCountFromContextMethod == 0");
4653         return -1;
4654     }
4655 }
4656 
4657 BOOL
4658 AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(jobject accessibleContext, int i) {
4659     jboolean result;
4660     jthrowable exception;
4661 
4662     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(%p):", accessibleContext);
4663 
4664     // Get (& return) the # of items selected in the AccessibleSelection
4665     if (isAccessibleChildSelectedFromContextMethod != (jmethodID) 0) {
4666         result = jniEnv->CallBooleanMethod(accessBridgeObject,
4667                                            isAccessibleChildSelectedFromContextMethod,
4668                                            accessibleContext, i);
4669         EXCEPTION_CHECK("Doing isAccessibleChildSelected - call to CallBooleanMethod()", FALSE);
4670         PrintDebugString("  returned from CallObjectMethod()");
4671         if (result != 0) {
4672             return TRUE;
4673         }
4674     } else {
4675         PrintDebugString("  Error! either env == 0 or isAccessibleChildSelectedFromContextMethod == 0");
4676     }
4677     return FALSE;
4678 }
4679 
4680 
4681 void
4682 AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(jobject accessibleContext, int i) {
4683     jthrowable exception;
4684 
4685     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(%p):", accessibleContext);
4686 
4687     // Remove the i-th child from the AccessibleSelection
4688     if (removeAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4689         jniEnv->CallVoidMethod(accessBridgeObject,
4690                                removeAccessibleSelectionFromContextMethod,
4691                                accessibleContext, i);
4692         EXCEPTION_CHECK_VOID("Doing removeAccessibleSelection - call to CallVoidMethod()");
4693         PrintDebugString("  returned from CallObjectMethod()");
4694     } else {
4695         PrintDebugString("  Error! either env == 0 or removeAccessibleSelectionFromContextMethod == 0");
4696     }
4697 }
4698 
4699 void
4700 AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(jobject accessibleContext) {
4701     jthrowable exception;
4702 
4703     PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(%p):", accessibleContext);
4704 
4705     // Select all children (if possible) of the AccessibleSelection
4706     if (selectAllAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4707         jniEnv->CallVoidMethod(accessBridgeObject,
4708                                selectAllAccessibleSelectionFromContextMethod,
4709                                accessibleContext);
4710         EXCEPTION_CHECK_VOID("Doing selectAllAccessibleSelection - call to CallVoidMethod()");
4711         PrintDebugString("  returned from CallObjectMethod()");
4712     } else {
4713         PrintDebugString("  Error! either env == 0 or selectAllAccessibleSelectionFromContextMethod == 0");
4714     }
4715 }
4716 
4717 
4718 /********** Event Notification Registration routines ***************/
4719 
4720 BOOL
4721 AccessBridgeJavaEntryPoints::addJavaEventNotification(jlong type) {
4722     jthrowable exception;
4723 
4724     PrintDebugString("\r\n  in AccessBridgeJavaEntryPoints::addJavaEventNotification(%016I64X);", type);
4725 
4726     // Let AccessBridge know we want to add an event type
4727     if (addJavaEventNotificationMethod != (jmethodID) 0) {
4728         jniEnv->CallVoidMethod(accessBridgeObject,
4729                                addJavaEventNotificationMethod, type);
4730         EXCEPTION_CHECK("Doing addJavaEventNotification - call to CallVoidMethod()", FALSE);
4731     } else {
4732         PrintDebugString("  Error! either env == 0 or addJavaEventNotificationMethod == 0");
4733         return FALSE;
4734     }
4735     return TRUE;
4736 }
4737 
4738 BOOL
4739 AccessBridgeJavaEntryPoints::removeJavaEventNotification(jlong type) {
4740     jthrowable exception;
4741 
4742     PrintDebugString("\r\n  in AccessBridgeJavaEntryPoints::removeJavaEventNotification(%016I64X):", type);
4743 
4744     // Let AccessBridge know we want to remove an event type
4745     if (removeJavaEventNotificationMethod != (jmethodID) 0) {
4746         jniEnv->CallVoidMethod(accessBridgeObject,
4747                                removeJavaEventNotificationMethod, type);
4748         EXCEPTION_CHECK("Doing removeJavaEventNotification - call to CallVoidMethod()", FALSE);
4749     } else {
4750         PrintDebugString("  Error! either env == 0 or removeJavaEventNotificationMethod == 0");
4751         return FALSE;
4752     }
4753     return TRUE;
4754 }
4755 
4756 BOOL
4757 AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(jlong type) {
4758     jthrowable exception;
4759 
4760     PrintDebugString("\r\n  in AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(%016I64X);", type);
4761 
4762     // Let AccessBridge know we want to add an event type
4763     if (addAccessibilityEventNotificationMethod != (jmethodID) 0) {
4764         PrintDebugString("\r\n     addAccessibilityEventNotification: calling void method: accessBridgeObject = %p", accessBridgeObject);
4765         jniEnv->CallVoidMethod(accessBridgeObject,
4766                                addAccessibilityEventNotificationMethod, type);
4767         EXCEPTION_CHECK("Doing addAccessibilityEvent - call to CallVoidMethod()", FALSE);
4768     } else {
4769         PrintDebugString("  Error! either env == 0 or addAccessibilityEventNotificationMethod == 0");
4770         return FALSE;
4771     }
4772     PrintDebugString("\r\n     addAccessibilityEventNotification: just returning true");
4773     return TRUE;
4774 }
4775 
4776 BOOL
4777 AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(jlong type) {
4778     jthrowable exception;
4779 
4780     PrintDebugString("\r\n  in AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(%016I64X):", type);
4781 
4782     // Let AccessBridge know we want to remove an event type
4783     if (removeAccessibilityEventNotificationMethod != (jmethodID) 0) {
4784         jniEnv->CallVoidMethod(accessBridgeObject,
4785                                removeAccessibilityEventNotificationMethod, type);
4786         EXCEPTION_CHECK("Doing removeAccessibilityEvent - call to CallVoidMethod()", FALSE);
4787     } else {
4788         PrintDebugString("  Error! either env == 0 or removeAccessibilityEventNotificationMethod == 0");
4789         return FALSE;
4790     }
4791     return TRUE;
4792 }


  23  * questions.
  24  */
  25 
  26 /*
  27  * A class to manage JNI calls into AccessBridge.java
  28  */
  29 
  30 #include "AccessBridgeJavaEntryPoints.h"
  31 #include "AccessBridgeDebug.h"
  32 
  33 
  34 
  35 /**
  36  * Initialize the AccessBridgeJavaEntryPoints class
  37  *
  38  */
  39 AccessBridgeJavaEntryPoints::AccessBridgeJavaEntryPoints(JNIEnv *jniEnvironment,
  40                                                          jobject bridgeObject) {
  41     jniEnv = jniEnvironment;
  42     accessBridgeObject = (jobject)bridgeObject;
  43     PrintDebugString("[INFO]: AccessBridgeJavaEntryPoints(%p, %p) called", jniEnv, accessBridgeObject);
  44 }
  45 
  46 
  47 /**
  48  * Destructor
  49  *
  50  */
  51 AccessBridgeJavaEntryPoints::~AccessBridgeJavaEntryPoints() {
  52 }
  53 
  54 // -----------------------------------
  55 
  56 #define FIND_CLASS(classRef, className) \
  57     localClassRef = jniEnv->FindClass(className); \
  58     if (localClassRef == (jclass) 0) { \
  59         PrintDebugString("[ERROR]:  FindClass(%s) failed! -> jniEnv = %p", className, jniEnv); \

  60         return FALSE; \
  61     } \
  62     classRef = (jclass) jniEnv->NewGlobalRef(localClassRef); \
  63     jniEnv->DeleteLocalRef(localClassRef); \
  64     if (classRef == (jclass) 0) { \
  65         PrintDebugString("[ERROR]: FindClass(%s) failed! ->  (ran out of RAM)", className); \

  66         return FALSE; \
  67     }
  68 
  69 
  70 #define FIND_METHOD(methodID, classRef, methodString, methodSignature); \
  71     methodID = jniEnv->GetMethodID(classRef, methodString,  methodSignature); \
  72     if (methodID == (jmethodID) 0) { \
  73         PrintDebugString("[ERROR]: GetMethodID(%s) failed! -> jniEnv = %p; classRef = %p", methodString, jniEnv, classRef); \

  74         return FALSE; \
  75     }
  76 
  77 #define EXCEPTION_CHECK(situationDescription, returnVal)                                        \
  78     if (exception = jniEnv->ExceptionOccurred()) {                                              \
  79         PrintDebugString("[ERROR]: *** Exception occured while doing: %s; returning %d", situationDescription, returnVal);   \
  80         jniEnv->ExceptionDescribe();                                                            \
  81         jniEnv->ExceptionClear();                                                               \
  82         return (returnVal);                                                                     \
  83     }
  84 
  85 #define EXCEPTION_CHECK_VOID(situationDescription)                                              \
  86     if (exception = jniEnv->ExceptionOccurred()) {                                              \
  87         PrintDebugString("[ERROR]: *** Exception occured while doing: %s", situationDescription);   \
  88         jniEnv->ExceptionDescribe();                                                            \
  89         jniEnv->ExceptionClear();                                                               \
  90         return;                                                                                 \
  91     }
  92 
  93 /**
  94  * Make all of the getClass() & getMethod() calls
  95  *
  96  */
  97 BOOL
  98 AccessBridgeJavaEntryPoints::BuildJavaEntryPoints() {
  99     jclass localClassRef;
 100 
 101     PrintDebugString("[INFO]: Calling BuildJavaEntryPoints():");
 102 
 103     FIND_CLASS(bridgeClass, "com/sun/java/accessibility/internal/AccessBridge");
 104 
 105     // ------- general methods
 106 
 107     // GetMethodID(decrementReference)
 108     FIND_METHOD(decrementReferenceMethod, bridgeClass,
 109                 "decrementReference",
 110                 "(Ljava/lang/Object;)V");
 111 
 112     // GetMethodID(getJavaVersionPropertyMethod)
 113     FIND_METHOD(getJavaVersionPropertyMethod, bridgeClass,
 114                 "getJavaVersionProperty",
 115                 "()Ljava/lang/String;");
 116 
 117     // ------- Window methods
 118 
 119     // GetMethodID(isJavaWindow)
 120     FIND_METHOD(isJavaWindowMethod, bridgeClass,
 121                 "isJavaWindow",


 860 //
 861 // Solution:
 862 // Cast the JOBJECT64 to a jobject.  For a 64 bit compile this is basically
 863 // a noop, i.e. JOBJECT64 is a 64 bit jlong and a jobject is a 64 bit reference.
 864 // For a 32 bit compile the cast drops the high order 32 bits, i.e. JOBJECT64
 865 // is a 64 bit jlong and jobject is a 32 bit reference.  For a Legacy build
 866 // JOBJECT64 is a jobject so this is also basically a noop.  The casts are
 867 // done in the methods in JavaAccessBridge::processPackage.
 868 
 869 // -----------------------------------
 870 
 871 /**
 872  * isJavaWindow - returns whether the HWND is a Java window or not
 873  *
 874  */
 875 BOOL
 876 AccessBridgeJavaEntryPoints::isJavaWindow(jint window) {
 877     jthrowable exception;
 878     BOOL returnVal;
 879 
 880     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::isJavaWindow(%X):", window);
 881 
 882     if (isJavaWindowMethod != (jmethodID) 0) {
 883         returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, isJavaWindowMethod, window);
 884         EXCEPTION_CHECK("Getting isJavaWindow - call to CallBooleanMethod()", FALSE);
 885         return returnVal;
 886     } else {
 887         PrintDebugString("[ERROR]: either jniEnv == 0 or isJavaWindowMethod == 0");
 888         return FALSE;
 889     }
 890 }
 891 
 892 // -----------------------------------
 893 
 894 /**
 895  * isSameObject - returns whether two object reference refer to the same object
 896  *
 897  */
 898 BOOL
 899 AccessBridgeJavaEntryPoints::isSameObject(jobject obj1, jobject obj2) {
 900     jthrowable exception;
 901     BOOL returnVal;
 902 
 903     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::isSameObject(%p %p):", obj1, obj2);
 904 
 905     returnVal = (BOOL) jniEnv->IsSameObject((jobject)obj1, (jobject)obj2);
 906     EXCEPTION_CHECK("Calling IsSameObject", FALSE);
 907 
 908     PrintDebugString("[INFO]:   isSameObject returning %d", returnVal);
 909     return returnVal;
 910 }
 911 
 912 // -----------------------------------
 913 
 914 /**
 915  * getAccessibleContextFromHWND - returns the AccessibleContext, if any, for an HWND
 916  *
 917  */
 918 jobject
 919 AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(jint window) {
 920     jobject returnedAccessibleContext;
 921     jobject globalRef;
 922     jthrowable exception;
 923 
 924     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(%X):", window);
 925 
 926     if (getAccessibleContextFromHWNDMethod != (jmethodID) 0) {
 927         returnedAccessibleContext =
 928             (jobject)jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleContextFromHWNDMethod,
 929                                               window);
 930         EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0);
 931         globalRef = (jobject)jniEnv->NewGlobalRef((jobject)returnedAccessibleContext);
 932         EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0);
 933         return globalRef;
 934     } else {
 935         PrintDebugString("[ERROR]:  either jniEnv == 0 or getAccessibleContextFromHWNDMethod == 0");
 936         return (jobject) 0;
 937     }
 938 }
 939 
 940 // -----------------------------------
 941 
 942 /**
 943  * getHWNDFromAccessibleContext - returns the HWND for an AccessibleContext, if any
 944  *      returns (HWND)0 on error.
 945  */
 946 HWND
 947 AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(jobject accessibleContext) {
 948     jthrowable exception;
 949     HWND rHWND;
 950 
 951     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(%X):",
 952                      accessibleContext);
 953 
 954     if (getHWNDFromAccessibleContextMethod != (jmethodID) 0) {
 955         rHWND = (HWND)jniEnv->CallIntMethod(accessBridgeObject, getHWNDFromAccessibleContextMethod,
 956                                             accessibleContext);
 957         EXCEPTION_CHECK("Getting HWNDFromAccessibleContext - call to CallIntMethod()", (HWND)0);
 958         PrintDebugString("[INFO]: rHWND = %X", rHWND);
 959         return rHWND;
 960     } else {
 961         PrintDebugString("[ERROR]: either jniEnv == 0 or getHWNDFromAccessibleContextMethod == 0");
 962         return (HWND)0;
 963     }
 964 }
 965 
 966 
 967 /* ====== Utility methods ===== */
 968 
 969 /**
 970  * Sets a text field to the specified string.  Returns whether successful;
 971  */
 972 BOOL
 973 AccessBridgeJavaEntryPoints::setTextContents(const jobject accessibleContext, const wchar_t *text) {
 974     jthrowable exception;
 975     BOOL result = FALSE;
 976 
 977     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::setTextContents(%p, %ls):",
 978                      accessibleContext, text);
 979 
 980     if (setTextContentsMethod != (jmethodID) 0) {
 981 
 982         // create a Java String for the text
 983         jstring textString = jniEnv->NewString(text, (jsize)wcslen(text));
 984         if (textString == 0) {
 985             PrintDebugString("[ERROR]:    NewString failed");
 986             return FALSE;
 987         }
 988 
 989         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
 990                                                  setTextContentsMethod,
 991                                                  accessibleContext, textString);
 992         EXCEPTION_CHECK("setTextContents - call to CallBooleanMethod()", FALSE);
 993         PrintDebugString("[INFO]:     result = %d", result);
 994         return result;
 995     } else {
 996         PrintDebugString("[ERROR]: either jniEnv == 0 or setTextContentsMethod == 0");
 997         return result;
 998     }
 999 }
1000 
1001 /**
1002  * Returns the Accessible Context of a Page Tab object that is the
1003  * ancestor of a given object.  If the object is a Page Tab object
1004  * or a Page Tab ancestor object was found, returns the object
1005  * AccessibleContext.
1006  * If there is no ancestor object that has an Accessible Role of Page Tab,
1007  * returns (AccessibleContext)0.
1008  */
1009 jobject
1010 AccessBridgeJavaEntryPoints::getParentWithRole(const jobject accessibleContext, const wchar_t *role) {
1011     jthrowable exception;
1012     jobject rAccessibleContext;
1013 
1014     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getParentWithRole(%p):",
1015                      accessibleContext);
1016 
1017     if (getParentWithRoleMethod != (jmethodID) 0) {
1018         // create a Java String for the role
1019         jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role));
1020         if (roleName == 0) {
1021             PrintDebugString("[ERROR]:     NewString failed");
1022             return FALSE;
1023         }
1024 
1025         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1026                                                       getParentWithRoleMethod,
1027                                                       accessibleContext, roleName);
1028         EXCEPTION_CHECK("Getting ParentWithRole - call to CallObjectMethod()", (AccessibleContext)0);
1029         PrintDebugString("[INFO]:     rAccessibleContext = %p", rAccessibleContext);
1030         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1031         EXCEPTION_CHECK("Getting ParentWithRole - call to NewGlobalRef()", FALSE);
1032         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1033                          rAccessibleContext, globalRef);
1034         return globalRef;
1035     } else {
1036         PrintDebugString("[ERROR]: either jniEnv == 0 or getParentWithRoleMethod == 0");
1037         return 0;
1038     }
1039 }
1040 
1041 /**
1042  * Returns the Accessible Context for the top level object in
1043  * a Java Window.  This is same Accessible Context that is obtained
1044  * from GetAccessibleContextFromHWND for that window.  Returns
1045  * (AccessibleContext)0 on error.
1046  */
1047 jobject
1048 AccessBridgeJavaEntryPoints::getTopLevelObject(const jobject accessibleContext) {
1049     jthrowable exception;
1050     jobject rAccessibleContext;
1051 
1052     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getTopLevelObject(%p):",
1053                      accessibleContext);
1054 
1055     if (getTopLevelObjectMethod != (jmethodID) 0) {
1056         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1057                                                       getTopLevelObjectMethod,
1058                                                       accessibleContext);
1059         EXCEPTION_CHECK("Getting TopLevelObject - call to CallObjectMethod()", FALSE);
1060         PrintDebugString("[INFO]:  rAccessibleContext = %p", rAccessibleContext);
1061         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1062         EXCEPTION_CHECK("Getting TopLevelObject - call to NewGlobalRef()", FALSE);
1063         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1064                          rAccessibleContext, globalRef);
1065         return globalRef;
1066     } else {
1067         PrintDebugString("[ERROR]: either jniEnv == 0 or getTopLevelObjectMethod == 0");
1068         return 0;
1069     }
1070 }
1071 
1072 /**
1073  * If there is an Ancestor object that has an Accessible Role of
1074  * Internal Frame, returns the Accessible Context of the Internal
1075  * Frame object.  Otherwise, returns the top level object for that
1076  * Java Window.  Returns (AccessibleContext)0 on error.
1077  */
1078 jobject
1079 AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(const jobject accessibleContext, const wchar_t *role) {
1080     jthrowable exception;
1081     jobject rAccessibleContext;
1082 
1083     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(%p):",
1084                      accessibleContext);
1085 
1086     if (getParentWithRoleElseRootMethod != (jmethodID) 0) {
1087 
1088         // create a Java String for the role
1089         jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role));
1090         if (roleName == 0) {
1091             PrintDebugString("[ERROR]:     NewString failed");
1092             return FALSE;
1093         }
1094 
1095         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1096                                                       getParentWithRoleElseRootMethod,
1097                                                       accessibleContext, roleName);
1098         EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to CallObjectMethod()", (AccessibleContext)0);
1099         PrintDebugString("[INFO]:     rAccessibleContext = %p", rAccessibleContext);
1100         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1101         EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to NewGlobalRef()", FALSE);
1102         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1103                          rAccessibleContext, globalRef);
1104         return globalRef;
1105     } else {
1106         PrintDebugString("[ERROR]:  either jniEnv == 0 or getParentWithRoleElseRootMethod == 0");
1107         return 0;
1108     }
1109 }
1110 
1111 /**
1112  * Returns how deep in the object hierarchy a given object is.
1113  * The top most object in the object hierarchy has an object depth of 0.
1114  * Returns -1 on error.
1115  */
1116 jint
1117 AccessBridgeJavaEntryPoints::getObjectDepth(const jobject accessibleContext) {
1118     jthrowable exception;
1119     jint rResult;
1120 
1121     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getObjectDepth(%p):",
1122                      accessibleContext);
1123 
1124     if (getObjectDepthMethod != (jmethodID) 0) {
1125         rResult = jniEnv->CallIntMethod(accessBridgeObject,
1126                                         getObjectDepthMethod,
1127                                         accessibleContext);
1128         EXCEPTION_CHECK("Getting ObjectDepth - call to CallIntMethod()", -1);
1129         PrintDebugString("[INFO]:     rResult = %d", rResult);
1130         return rResult;
1131     } else {
1132         PrintDebugString("[ERROR]: either jniEnv == 0 or getObjectDepthMethod == 0");
1133         return -1;
1134     }
1135 }
1136 
1137 
1138 
1139 /**
1140  * Returns the Accessible Context of the current ActiveDescendent of an object.
1141  * Returns 0 on error.
1142  */
1143 jobject
1144 AccessBridgeJavaEntryPoints::getActiveDescendent(const jobject accessibleContext) {
1145     jthrowable exception;
1146     jobject rAccessibleContext;
1147 
1148     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getActiveDescendent(%p):",
1149                      accessibleContext);
1150 
1151     if (getActiveDescendentMethod != (jmethodID) 0) {
1152         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1153                                                       getActiveDescendentMethod,
1154                                                       accessibleContext);
1155         EXCEPTION_CHECK("Getting ActiveDescendent - call to CallObjectMethod()", (AccessibleContext)0);
1156         PrintDebugString("[INFO]:     rAccessibleContext = %p", rAccessibleContext);
1157         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1158         EXCEPTION_CHECK("Getting ActiveDescendant - call to NewGlobalRef()", FALSE);
1159         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1160                          rAccessibleContext, globalRef);
1161         return globalRef;
1162     } else {
1163         PrintDebugString("[ERROR]: either jniEnv == 0 or getActiveDescendentMethod == 0");
1164         return (AccessibleContext)0;
1165     }
1166 }
1167 
1168 /**
1169  * Additional methods for Teton
1170  */
1171 
1172 /**
1173  * Returns an AccessibleName for a component using an algorithm optimized
1174  * for the JAWS screen reader by Ben Key (Freedom Scientific).  This method
1175  * is only intended for JAWS. All other uses are entirely optional.
1176  *
1177  * Bug ID 4916682 - Implement JAWS AccessibleName policy
1178  */
1179 BOOL
1180 AccessBridgeJavaEntryPoints::getVirtualAccessibleName (
1181     IN const jobject object,
1182     OUT wchar_t * name,
1183     IN const int nameSize)
1184 {
1185     /*
1186       +
1187       Parameter validation
1188       +
1189     */
1190     if ((name == 0) || (nameSize == 0))
1191     {
1192         return FALSE;
1193     }
1194     ::memset (name, 0, nameSize * sizeof (wchar_t));
1195     if (0 == object)
1196     {
1197         return FALSE;
1198     }
1199 
1200     jstring js = NULL;
1201     const wchar_t * stringBytes = NULL;
1202     jthrowable exception = NULL;
1203     jsize length = 0;
1204     PrintDebugString("[INFO]:  getVirtualAccessibleName called.");
1205     if (getVirtualAccessibleNameFromContextMethod != (jmethodID) 0)
1206     {
1207         js = (jstring) jniEnv->CallObjectMethod (
1208             accessBridgeObject,
1209             getVirtualAccessibleNameFromContextMethod,
1210             object);
1211         EXCEPTION_CHECK("Getting AccessibleName - call to CallObjectMethod()", FALSE);
1212         if (js != (jstring) 0)
1213         {
1214             stringBytes = (const wchar_t *) jniEnv->GetStringChars (js, 0);
1215             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE);
1216             wcsncpy(name, stringBytes, nameSize - 1);
1217             length = jniEnv->GetStringLength(js);
1218             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE);
1219             jniEnv->ReleaseStringChars(js, stringBytes);
1220             EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE);
1221             jniEnv->CallVoidMethod (
1222                 accessBridgeObject,
1223                 decrementReferenceMethod, js);
1224             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
1225             wPrintDebugString(L"  Accessible Name = %ls", name);
1226             jniEnv->DeleteLocalRef(js);
1227             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
1228         }
1229         else
1230         {
1231             PrintDebugString("[INFO]:   Accessible Name is null.");
1232         }
1233     }
1234     else
1235     {
1236         PrintDebugString("[INFO]: either jniEnv == 0 or getVirtualAccessibleNameFromContextMethod == 0");
1237         return FALSE;
1238     }
1239     if ( 0 != name [0] )
1240     {
1241         return TRUE;
1242     }
1243     return FALSE;
1244 }
1245 
1246 
1247 /**
1248  * Request focus for a component. Returns whether successful;
1249  *
1250  * Bug ID 4944757 - requestFocus method needed
1251  */
1252 BOOL
1253 AccessBridgeJavaEntryPoints::requestFocus(const jobject accessibleContext) {
1254 
1255     jthrowable exception;
1256     BOOL result = FALSE;
1257 
1258     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::requestFocus(%p):",
1259                      accessibleContext);
1260 
1261     if (requestFocusMethod != (jmethodID) 0) {
1262         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
1263                                                  requestFocusMethod,
1264                                                  accessibleContext);
1265         EXCEPTION_CHECK("requestFocus - call to CallBooleanMethod()", FALSE);
1266         PrintDebugString("[INFO]:    result = %d", result);
1267         return result;
1268     } else {
1269         PrintDebugString("[ERROR]: either jniEnv == 0 or requestFocusMethod == 0");
1270         return result;
1271     }
1272 }
1273 
1274 /**
1275  * Selects text between two indices.  Selection includes the text at the start index
1276  * and the text at the end index. Returns whether successful;
1277  *
1278  * Bug ID 4944758 - selectTextRange method needed
1279  */
1280 BOOL
1281 AccessBridgeJavaEntryPoints::selectTextRange(const jobject accessibleContext, int startIndex, int endIndex) {
1282 
1283     jthrowable exception;
1284     BOOL result = FALSE;
1285 
1286     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::selectTextRange(%p start = %d end = %d):",
1287                      accessibleContext, startIndex, endIndex);
1288 
1289     if (selectTextRangeMethod != (jmethodID) 0) {
1290         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
1291                                                  selectTextRangeMethod,
1292                                                  accessibleContext,
1293                                                  startIndex, endIndex);
1294         EXCEPTION_CHECK("selectTextRange - call to CallBooleanMethod()", FALSE);
1295         PrintDebugString("[INFO]:     result = %d", result);
1296         return result;
1297     } else {
1298         PrintDebugString("[ERROR]: either jniEnv == 0 or selectTextRangeMethod == 0");
1299         return result;
1300     }
1301 }
1302 
1303 /*
1304  * Returns whether two text attributes are the same.
1305  */
1306 static BOOL CompareAccessibleTextAttributesInfo(AccessibleTextAttributesInfo *one,
1307                                                 AccessibleTextAttributesInfo *two) {
1308     return(one->bold == two->bold
1309            && one->italic == two->italic
1310            && one->underline == two->underline
1311            && one->strikethrough == two->strikethrough
1312            && one->superscript == two->superscript
1313            && one->subscript == two->subscript
1314            && one->fontSize == two->fontSize
1315            && one->alignment == two->alignment
1316            && one->bidiLevel == two->bidiLevel
1317            && one->firstLineIndent == two->firstLineIndent
1318            && one->leftIndent == two->leftIndent


1335  * parameter len the number of characters with the attributes returned. In most
1336  * situations this will be all the characters, and if not the calling program
1337  * can easily get the attributes for the next characters with different
1338  * attributes
1339  *
1340  * Bug ID 4944761 - getTextAttributes between two indices method needed
1341  */
1342 
1343 /* NEW FASTER CODE!!*/
1344 BOOL
1345 AccessBridgeJavaEntryPoints::getTextAttributesInRange(const jobject accessibleContext,
1346                                                       int startIndex, int endIndex,
1347                                                       AccessibleTextAttributesInfo *attributes, short *len) {
1348 
1349     jstring js;
1350     const wchar_t *stringBytes;
1351     jthrowable exception;
1352     jsize length;
1353     BOOL result = FALSE;
1354 
1355     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getTextAttributesInRange(%p start = %d end = %d):",
1356                      accessibleContext, startIndex, endIndex);
1357 
1358     *len = 0;
1359     result = getAccessibleTextAttributes((jobject)accessibleContext, startIndex, attributes);
1360     if (result != TRUE) {
1361         return FALSE;
1362     }
1363     (*len)++;
1364 
1365     for (jint i = startIndex+1; i <= endIndex; i++) {
1366 
1367         AccessibleTextAttributesInfo test_attributes = *attributes;
1368         // Get the full test_attributes string at i
1369         if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) {
1370             PrintDebugString("[INFO]:  Getting full test_attributes string from Context...");
1371             js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1372                                                     getAccessibleAttributesAtIndexFromContextMethod,
1373                                                     accessibleContext, i);
1374             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE);
1375             PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
1376             if (js != (jstring) 0) {
1377                 stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1378                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE);
1379                 wcsncpy(test_attributes.fullAttributesString, stringBytes, (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t)));
1380                 length = jniEnv->GetStringLength(js);
1381                 test_attributes.fullAttributesString[length < (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t)) ?
1382                                                      length : (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0;
1383                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE);
1384                 jniEnv->ReleaseStringChars(js, stringBytes);
1385                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE);
1386                 jniEnv->CallVoidMethod(accessBridgeObject,
1387                                        decrementReferenceMethod, js);
1388                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE);
1389                 wPrintDebugString(L"[INFO]:  Accessible Text attributes = %ls", test_attributes.fullAttributesString);
1390                 jniEnv->DeleteLocalRef(js);
1391                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
1392             } else {
1393                 PrintDebugString("[WARN]:   Accessible Text attributes is null.");
1394                 test_attributes.fullAttributesString[0] = (wchar_t) 0;
1395                 return FALSE;
1396             }
1397         } else {
1398             PrintDebugString("[ERROR]: either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0");
1399             return FALSE;
1400         }
1401 
1402         if(wcscmp(attributes->fullAttributesString,test_attributes.fullAttributesString))
1403             break;
1404         if (result != TRUE) {
1405             return FALSE;
1406         }
1407         (*len)++;
1408     }
1409     return TRUE;
1410 }
1411 
1412 /*
1413  * Returns the number of visible children of a component
1414  *
1415  * Bug ID 4944762- getVisibleChildren for list-like components needed
1416  */
1417 int
1418 AccessBridgeJavaEntryPoints::getVisibleChildrenCount(const jobject accessibleContext) {
1419 
1420     jthrowable exception;
1421     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getVisibleChildrenCount(%p)",
1422                      accessibleContext);
1423 
1424     // get the visible children count
1425     int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod,
1426                                             accessibleContext);
1427     EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE);
1428     PrintDebugString("[INFO]:   ##### visible children count = %d", numChildren);
1429 
1430     return numChildren;
1431 }
1432 
1433 
1434 /*
1435  * This method is used to iterate through the visible children of a component.  It
1436  * returns visible children information for a component starting at nStartIndex.
1437  * No more than MAX_VISIBLE_CHILDREN VisibleChildrenInfo objects will
1438  * be returned for each call to this method. Returns FALSE on error.
1439  *
1440  * Bug ID 4944762- getVisibleChildren for list-like components needed
1441  */
1442 BOOL AccessBridgeJavaEntryPoints::getVisibleChildren(const jobject accessibleContext,
1443                                                      const int nStartIndex,
1444                                                      /* OUT */ VisibleChildrenInfo *visibleChildrenInfo) {
1445 
1446     jthrowable exception;
1447 
1448     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getVisibleChildren(%p, startIndex = %d)",
1449                      accessibleContext, nStartIndex);
1450 
1451     // get the visible children count
1452     int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod,
1453                                             accessibleContext);
1454     EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE);
1455     PrintDebugString("[INFO]:   ##### visible children count = %d", numChildren);
1456 
1457     if (nStartIndex >= numChildren) {
1458         return FALSE;
1459     }
1460 
1461     // get the visible children
1462     int bufIndex = 0;
1463     for (int i = nStartIndex; (i < numChildren) && (i < nStartIndex + MAX_VISIBLE_CHILDREN); i++) {
1464         PrintDebugString("[INFO]:   getting visible child %d ...", i);
1465 
1466         // get the visible child at index i
1467         jobject ac = jniEnv->CallObjectMethod(accessBridgeObject, getVisibleChildMethod,
1468                                               accessibleContext, i);
1469         EXCEPTION_CHECK("##### getVisibleChildMethod - call to CallObjectMethod()", FALSE);
1470         jobject globalRef = jniEnv->NewGlobalRef(ac);
1471         EXCEPTION_CHECK("##### getVisibleChildMethod - call to NewGlobalRef()", FALSE);
1472         visibleChildrenInfo->children[bufIndex] = (JOBJECT64)globalRef;
1473         PrintDebugString("[INFO]:   ##### visible child = %p", globalRef);
1474 
1475         bufIndex++;
1476     }
1477     visibleChildrenInfo->returnedChildrenCount = bufIndex;
1478 
1479     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getVisibleChildren succeeded");
1480     return TRUE;
1481 }
1482 
1483 /**
1484  * Set the caret to a text position. Returns whether successful;
1485  *
1486  * Bug ID 4944770 - setCaretPosition method needed
1487  */
1488 BOOL
1489 AccessBridgeJavaEntryPoints::setCaretPosition(const jobject accessibleContext, int position) {
1490 
1491     jthrowable exception;
1492     BOOL result = FALSE;
1493 
1494     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::setCaretPostion(%p position = %d):",
1495                      accessibleContext, position);
1496 
1497     if (setCaretPositionMethod != (jmethodID) 0) {
1498         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
1499                                                  setCaretPositionMethod,
1500                                                  accessibleContext, position);
1501         EXCEPTION_CHECK("setCaretPostion - call to CallBooleanMethod()", FALSE);
1502         PrintDebugString("[ERROR]:     result = %d", result);
1503         return result;
1504     } else {
1505         PrintDebugString("[ERROR]: either jniEnv == 0 or setCaretPositionMethod == 0");
1506         return result;
1507     }
1508 }
1509 
1510 
1511 // -----------------------------------
1512 
1513 /**
1514  * getVersionInfo - returns the version string of the java.version property
1515  *                  and the AccessBridge.java version
1516  *
1517  */
1518 BOOL
1519 AccessBridgeJavaEntryPoints::getVersionInfo(AccessBridgeVersionInfo *info) {
1520     jstring js;
1521     const wchar_t *stringBytes;
1522     jthrowable exception;
1523     jsize length;
1524 
1525     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getVersionInfo():");
1526 
1527     if (getJavaVersionPropertyMethod != (jmethodID) 0) {
1528         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1529                                                 getJavaVersionPropertyMethod);
1530         EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallObjectMethod()", FALSE);
1531         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
1532         if (js != (jstring) 0) {
1533             length = jniEnv->GetStringLength(js);
1534             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1535             if (stringBytes == NULL) {
1536                 if (!jniEnv->ExceptionCheck()) {
1537                     PrintDebugString("[ERROR]:  *** Exception when getting JavaVersionProperty - call to GetStringChars");
1538                     jniEnv->ExceptionDescribe();
1539                     jniEnv->ExceptionClear();
1540                 }
1541                 return FALSE;
1542             }
1543             wcsncpy(info->bridgeJavaDLLVersion,
1544                     stringBytes,
1545                     sizeof(info->bridgeJavaDLLVersion)  / sizeof(wchar_t));
1546             info->bridgeJavaDLLVersion[length < (sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t)) ?
1547                             length : (sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1548             wcsncpy(info->VMversion,
1549                     stringBytes,
1550                     sizeof(info->VMversion)  / sizeof(wchar_t));
1551             info->VMversion[length < (sizeof(info->VMversion) / sizeof(wchar_t)) ?
1552                             length : (sizeof(info->VMversion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1553             wcsncpy(info->bridgeJavaClassVersion,
1554                     stringBytes,
1555                     sizeof(info->bridgeJavaClassVersion)  / sizeof(wchar_t));
1556             info->bridgeJavaClassVersion[length < (sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t)) ?
1557                                          length : (sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1558             wcsncpy(info->bridgeWinDLLVersion,
1559                     stringBytes,
1560                     sizeof(info->bridgeWinDLLVersion)  / sizeof(wchar_t));
1561             info->bridgeWinDLLVersion[length < (sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t)) ?
1562                                          length : (sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1563             jniEnv->ReleaseStringChars(js, stringBytes);
1564             EXCEPTION_CHECK("Getting JavaVersionProperty - call to ReleaseStringChars()", FALSE);
1565             jniEnv->CallVoidMethod(accessBridgeObject,
1566                                    decrementReferenceMethod, js);
1567             EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallVoidMethod()", FALSE);
1568             wPrintDebugString(L"  Java version = %ls", info->VMversion);
1569             jniEnv->DeleteLocalRef(js);
1570             EXCEPTION_CHECK("Getting JavaVersionProperty - call to DeleteLocalRef()", FALSE);
1571         } else {
1572             PrintDebugString("[WARN]:   Java version is null.");
1573             info->VMversion[0] = (wchar_t) 0;
1574             return FALSE;
1575         }
1576     } else {
1577         PrintDebugString("[ERROR]:  either env == 0 or getJavaVersionPropertyMethod == 0");
1578         return FALSE;
1579     }
1580 
1581     return TRUE;
1582 }
1583 
1584 
1585 /*
1586  * Verifies the Java VM still exists and obj is an
1587  * instance of AccessibleText
1588  */
1589 BOOL AccessBridgeJavaEntryPoints::verifyAccessibleText(jobject obj) {
1590     JavaVM *vm;
1591     BOOL retval;
1592     jthrowable exception;
1593 
1594     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::verifyAccessibleText");
1595 
1596     if (jniEnv->GetJavaVM(&vm) != 0) {
1597         PrintDebugString("[ERROR]:  No Java VM");
1598         return FALSE;
1599     }
1600 
1601     if (obj == (jobject)0) {
1602         PrintDebugString("[ERROR]:  Null jobject");
1603         return FALSE;
1604     }
1605 
1606     // Copied from getAccessibleContextInfo
1607     if (getAccessibleTextFromContextMethod != (jmethodID) 0) {
1608         jobject returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
1609                                                            getAccessibleTextFromContextMethod,
1610                                                            (jobject)obj);
1611         EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE);
1612         PrintDebugString("[ERROR]:   AccessibleText = %p", returnedJobject);
1613         retval = returnedJobject != (jobject) 0;
1614         jniEnv->DeleteLocalRef(returnedJobject);
1615         EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE);
1616     } else {
1617         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextFromContextMethod == 0");
1618         return FALSE;
1619     }
1620     if (retval == FALSE) {
1621         PrintDebugString("[ERROR]:  jobject is not an AccessibleText");
1622     }
1623     return retval;
1624 }
1625 
1626 
1627 /********** AccessibleContext routines ***********************************/
1628 
1629 /**
1630  * getAccessibleContextAt - performs the Java method call:
1631  *   Accessible AccessBridge.getAccessibleContextAt(x, y)
1632  *
1633  * Note: this call explicitly goes through the AccessBridge,
1634  * so that it can keep a reference the returned jobject for the JavaVM.
1635  * You must explicity call INTreleaseJavaObject() when you are through using
1636  * the Accessible returned, to let the AccessBridge know it can release the
1637  * object, so that the can then garbage collect it.
1638  *
1639  */
1640 jobject
1641 AccessBridgeJavaEntryPoints::getAccessibleContextAt(jint x, jint y, jobject accessibleContext) {
1642     jobject returnedAccessibleContext;
1643     jobject globalRef;
1644     jthrowable exception;
1645 
1646     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleContextAt(%d, %d, %p):",
1647                      x, y, accessibleContext);
1648 
1649     if (getAccessibleContextAtMethod != (jmethodID) 0) {
1650         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1651                                                              getAccessibleContextAtMethod,
1652                                                              x, y, accessibleContext);
1653         EXCEPTION_CHECK("Getting AccessibleContextAt - call to CallObjectMethod()", FALSE);
1654         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
1655         EXCEPTION_CHECK("Getting AccessibleContextAt - call to NewGlobalRef()", FALSE);
1656         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1657                          returnedAccessibleContext, globalRef);
1658         return globalRef;
1659     } else {
1660         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleContextAtMethod == 0");
1661         return (jobject) 0;
1662     }
1663 }
1664 
1665 /**
1666  * getAccessibleWithFocus - performs the Java method calls:
1667  *   Accessible Translator.getAccessible(SwingEventMonitor.getComponentWithFocus();
1668  *
1669  * Note: this call explicitly goes through the AccessBridge,
1670  * so that the AccessBridge can hide expected changes in how this functions
1671  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1672  * of this functionality may be built into the platform
1673  *
1674  */
1675 jobject
1676 AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus() {
1677     jobject returnedAccessibleContext;
1678     jobject globalRef;
1679     jthrowable exception;
1680 
1681     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus()");
1682 
1683     if (getAccessibleContextWithFocusMethod != (jmethodID) 0) {
1684         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1685                                                              getAccessibleContextWithFocusMethod);
1686         EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to CallObjectMethod()", FALSE);
1687         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
1688         EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to NewGlobalRef()", FALSE);
1689         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1690                          returnedAccessibleContext, globalRef);
1691         return globalRef;
1692     } else {
1693         PrintDebugString("[ERROR]:  either jniEnv == 0 or getAccessibleContextWithFocusMethod == 0");
1694         return (jobject) 0;
1695     }
1696 }
1697 
1698 /**
1699  * getAccessibleContextInfo - fills a struct with a bunch of information
1700  * contained in the Java Accessibility API
1701  *
1702  * Note: if the AccessibleContext parameter is bogus, this call will blow up
1703  *
1704  * Note: this call explicitly goes through the AccessBridge,
1705  * so that it can keep a reference the returned jobject for the JavaVM.
1706  * You must explicity call releaseJavaObject() when you are through using
1707  * the AccessibleContext returned, to let the AccessBridge know it can release the
1708  * object, so that the JavaVM can then garbage collect it.
1709  */
1710 BOOL
1711 AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, AccessibleContextInfo *info) {
1712     jstring js;
1713     const wchar_t *stringBytes;
1714     jobject returnedJobject;
1715     jthrowable exception;
1716     jsize length;
1717 
1718     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleContextInfo(%p):", accessibleContext);
1719 
1720     ZeroMemory(info, sizeof(AccessibleContextInfo));
1721 
1722     if (accessibleContext == (jobject) 0) {
1723         PrintDebugString("[WARN]:  passed in AccessibleContext == null! (oops)");
1724         return (FALSE);
1725     }
1726 
1727     // Get the Accessible Name
1728     if (getAccessibleNameFromContextMethod != (jmethodID) 0) {
1729         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1730                                                 getAccessibleNameFromContextMethod,
1731                                                 accessibleContext);
1732         EXCEPTION_CHECK("Getting AccessibleName - call to CallObjectMethod()", FALSE);
1733         if (js != (jstring) 0) {
1734             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1735             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE);
1736             wcsncpy(info->name, stringBytes, (sizeof(info->name) / sizeof(wchar_t)));
1737             length = jniEnv->GetStringLength(js);
1738             info->name[length < (sizeof(info->name) / sizeof(wchar_t)) ?
1739                        length : (sizeof(info->name) / sizeof(wchar_t))-2] = (wchar_t) 0;
1740             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE);
1741             jniEnv->ReleaseStringChars(js, stringBytes);
1742             EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE);
1743             jniEnv->CallVoidMethod(accessBridgeObject,
1744                                    decrementReferenceMethod, js);
1745             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
1746             wPrintDebugString(L"[INFO]:   Accessible Name = %ls", info->name);
1747             jniEnv->DeleteLocalRef(js);
1748             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
1749         } else {
1750             PrintDebugString("[WARN]:   Accessible Name is null.");
1751             info->name[0] = (wchar_t) 0;
1752         }
1753     } else {
1754         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleNameFromContextMethod == 0");
1755         return FALSE;
1756     }
1757 
1758 
1759     // Get the Accessible Description
1760     if (getAccessibleDescriptionFromContextMethod != (jmethodID) 0) {
1761         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1762                                                 getAccessibleDescriptionFromContextMethod,
1763                                                 accessibleContext);
1764         EXCEPTION_CHECK("Getting AccessibleDescription - call to CallObjectMethod()", FALSE);
1765         if (js != (jstring) 0) {
1766             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1767             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE);
1768             wcsncpy(info->description, stringBytes, (sizeof(info->description) / sizeof(wchar_t)));
1769             length = jniEnv->GetStringLength(js);
1770             info->description[length < (sizeof(info->description) / sizeof(wchar_t)) ?
1771                               length : (sizeof(info->description) / sizeof(wchar_t))-2] = (wchar_t) 0;
1772             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE);
1773             jniEnv->ReleaseStringChars(js, stringBytes);
1774             EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE);
1775             jniEnv->CallVoidMethod(accessBridgeObject,
1776                                    decrementReferenceMethod, js);
1777             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
1778             wPrintDebugString(L"[INFO]:   Accessible Description = %ls", info->description);
1779             jniEnv->DeleteLocalRef(js);
1780             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
1781         } else {
1782             PrintDebugString("[WARN]:   Accessible Description is null.");
1783             info->description[0] = (wchar_t) 0;
1784         }
1785     } else {
1786         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleDescriptionFromContextMethod == 0");
1787         return FALSE;
1788     }
1789 
1790 
1791     // Get the Accessible Role String
1792     if (getAccessibleRoleStringFromContextMethod != (jmethodID) 0) {
1793         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1794                                                 getAccessibleRoleStringFromContextMethod,
1795                                                 accessibleContext);
1796         EXCEPTION_CHECK("Getting AccessibleRole - call to CallObjectMethod()", FALSE);
1797         if (js != (jstring) 0) {
1798             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1799             EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringChars()", FALSE);
1800             wcsncpy(info->role, stringBytes, (sizeof(info->role) / sizeof(wchar_t)));
1801             length = jniEnv->GetStringLength(js);
1802             info->role[length < (sizeof(info->role) / sizeof(wchar_t)) ?
1803                        length : (sizeof(info->role) / sizeof(wchar_t))-2] = (wchar_t) 0;
1804             EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringLength()", FALSE);
1805             jniEnv->ReleaseStringChars(js, stringBytes);
1806             EXCEPTION_CHECK("Getting AccessibleRole - call to ReleaseStringChars()", FALSE);
1807             jniEnv->CallVoidMethod(accessBridgeObject,
1808                                    decrementReferenceMethod, js);
1809             EXCEPTION_CHECK("Getting AccessibleRole - call to CallVoidMethod()", FALSE);
1810             wPrintDebugString(L"[INFO]:   Accessible Role = %ls", info->role);
1811             jniEnv->DeleteLocalRef(js);
1812             EXCEPTION_CHECK("Getting AccessibleRole - call to DeleteLocalRef()", FALSE);
1813         } else {
1814             PrintDebugString("[WARN]:   Accessible Role is null.");
1815             info->role[0] = (wchar_t) 0;
1816         }
1817     } else {
1818         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleRoleStringFromContextMethod == 0");
1819         return FALSE;
1820     }
1821 
1822 
1823     // Get the Accessible Role String in the en_US locale
1824     if (getAccessibleRoleStringFromContext_en_USMethod != (jmethodID) 0) {
1825         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1826                                                 getAccessibleRoleStringFromContext_en_USMethod,
1827                                                 accessibleContext);
1828         EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallObjectMethod()", FALSE);
1829         if (js != (jstring) 0) {
1830             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1831             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringChars()", FALSE);
1832             wcsncpy(info->role_en_US, stringBytes, (sizeof(info->role_en_US) / sizeof(wchar_t)));
1833             length = jniEnv->GetStringLength(js);
1834             info->role_en_US[length < (sizeof(info->role_en_US) / sizeof(wchar_t)) ?
1835                              length : (sizeof(info->role_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0;
1836             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringLength()", FALSE);
1837             jniEnv->ReleaseStringChars(js, stringBytes);
1838             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to ReleaseStringChars()", FALSE);
1839             jniEnv->CallVoidMethod(accessBridgeObject,
1840                                    decrementReferenceMethod, js);
1841             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallVoidMethod()", FALSE);
1842             wPrintDebugString(L"[INFO]:   Accessible Role en_US = %ls", info->role_en_US);
1843             jniEnv->DeleteLocalRef(js);
1844             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to DeleteLocalRef()", FALSE);
1845         } else {
1846             PrintDebugString("[WARN]:   Accessible Role en_US is null.");
1847             info->role[0] = (wchar_t) 0;
1848         }
1849     } else {
1850         PrintDebugString("[ERROR]: either env == 0 or getAccessibleRoleStringFromContext_en_USMethod == 0");
1851         return FALSE;
1852     }
1853 
1854     // Get the Accessible States String
1855     if (getAccessibleStatesStringFromContextMethod != (jmethodID) 0) {
1856         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1857                                                 getAccessibleStatesStringFromContextMethod,
1858                                                 accessibleContext);
1859         EXCEPTION_CHECK("Getting AccessibleState - call to CallObjectMethod()", FALSE);
1860         if (js != (jstring) 0) {
1861             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1862             EXCEPTION_CHECK("Getting AccessibleState - call to GetStringChars()", FALSE);
1863             wcsncpy(info->states, stringBytes, (sizeof(info->states) / sizeof(wchar_t)));
1864             length = jniEnv->GetStringLength(js);
1865             info->states[length < (sizeof(info->states) / sizeof(wchar_t)) ?
1866                          length : (sizeof(info->states) / sizeof(wchar_t))-2] = (wchar_t) 0;
1867             EXCEPTION_CHECK("Getting AccessibleState - call to GetStringLength()", FALSE);
1868             jniEnv->ReleaseStringChars(js, stringBytes);
1869             EXCEPTION_CHECK("Getting AccessibleState - call to ReleaseStringChars()", FALSE);
1870             jniEnv->CallVoidMethod(accessBridgeObject,
1871                                    decrementReferenceMethod, js);
1872             EXCEPTION_CHECK("Getting AccessibleState - call to CallVoidMethod()", FALSE);
1873             wPrintDebugString(L"[INFO]:   Accessible States = %ls", info->states);
1874             jniEnv->DeleteLocalRef(js);
1875             EXCEPTION_CHECK("Getting AccessibleState - call to DeleteLocalRef()", FALSE);
1876         } else {
1877             PrintDebugString("[WARN]:   Accessible States is null.");
1878             info->states[0] = (wchar_t) 0;
1879         }
1880     } else {
1881         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleStatesStringFromContextMethod == 0");
1882         return FALSE;
1883     }
1884 
1885     // Get the Accessible States String in the en_US locale
1886     if (getAccessibleStatesStringFromContext_en_USMethod != (jmethodID) 0) {
1887         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1888                                                 getAccessibleStatesStringFromContext_en_USMethod,
1889                                                 accessibleContext);
1890         EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallObjectMethod()", FALSE);
1891         if (js != (jstring) 0) {
1892             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1893             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringChars()", FALSE);
1894             wcsncpy(info->states_en_US, stringBytes, (sizeof(info->states_en_US) / sizeof(wchar_t)));
1895             length = jniEnv->GetStringLength(js);
1896             info->states_en_US[length < (sizeof(info->states_en_US) / sizeof(wchar_t)) ?
1897                                length : (sizeof(info->states_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0;
1898             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringLength()", FALSE);
1899             jniEnv->ReleaseStringChars(js, stringBytes);
1900             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to ReleaseStringChars()", FALSE);
1901             jniEnv->CallVoidMethod(accessBridgeObject,
1902                                    decrementReferenceMethod, js);
1903             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallVoidMethod()", FALSE);
1904             wPrintDebugString(L"[INFO]:   Accessible States en_US = %ls", info->states_en_US);
1905             jniEnv->DeleteLocalRef(js);
1906             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to DeleteLocalRef()", FALSE);
1907         } else {
1908             PrintDebugString("[WARN]:   Accessible States en_US is null.");
1909             info->states[0] = (wchar_t) 0;
1910         }
1911     } else {
1912         PrintDebugString("[ERROR]: either env == 0 or getAccessibleStatesStringFromContext_en_USMethod == 0");
1913         return FALSE;
1914     }
1915 
1916 
1917     // Get the index in Parent
1918     if (getAccessibleIndexInParentFromContextMethod != (jmethodID) 0) {
1919         info->indexInParent = jniEnv->CallIntMethod(accessBridgeObject,
1920                                                     getAccessibleIndexInParentFromContextMethod,
1921                                                     accessibleContext);
1922         EXCEPTION_CHECK("Getting AccessibleIndexInParent - call to CallIntMethod()", FALSE);
1923         PrintDebugString("[INFO]:   Index in Parent = %d", info->indexInParent);
1924     } else {
1925         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleIndexInParentFromContextMethod == 0");
1926         return FALSE;
1927     }
1928 
1929 
1930     PrintDebugString("[INFO]: *** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %p ***",
1931                      jniEnv, accessBridgeObject, accessibleContext);
1932 
1933     // Get the children count
1934     if (getAccessibleChildrenCountFromContextMethod != (jmethodID) 0) {
1935         info->childrenCount = jniEnv->CallIntMethod(accessBridgeObject,
1936                                                     getAccessibleChildrenCountFromContextMethod,
1937                                                     accessibleContext);
1938         EXCEPTION_CHECK("Getting AccessibleChildrenCount - call to CallIntMethod()", FALSE);
1939         PrintDebugString("[INFO]:   Children count = %d", info->childrenCount);
1940     } else {
1941         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleChildrenCountFromContextMethod == 0");
1942         return FALSE;
1943     }
1944 
1945     PrintDebugString("[INFO]: *** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %X ***",
1946                      jniEnv, accessBridgeObject, accessibleContext);
1947 
1948 
1949     // Get the x coord
1950     if (getAccessibleXcoordFromContextMethod != (jmethodID) 0) {
1951         info->x = jniEnv->CallIntMethod(accessBridgeObject,
1952                                         getAccessibleXcoordFromContextMethod,
1953                                         accessibleContext);
1954         EXCEPTION_CHECK("Getting AccessibleXcoord - call to CallIntMethod()", FALSE);
1955         PrintDebugString("[INFO]:   X coord = %d", info->x);
1956     } else {
1957         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleXcoordFromContextMethod == 0");
1958         return FALSE;
1959     }
1960 
1961     PrintDebugString("[INFO]: *** jniEnv: %X; accessBridgeObject: %X; AccessibleContext: %p ***",
1962                      jniEnv, accessBridgeObject, accessibleContext);
1963 
1964 
1965     // Get the y coord
1966     if (getAccessibleYcoordFromContextMethod != (jmethodID) 0) {
1967         info->y = jniEnv->CallIntMethod(accessBridgeObject,
1968                                         getAccessibleYcoordFromContextMethod,
1969                                         accessibleContext);
1970         EXCEPTION_CHECK("Getting AccessibleYcoord - call to CallIntMethod()", FALSE);
1971         PrintDebugString("[INFO]:   Y coord = %d", info->y);
1972     } else {
1973         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleYcoordFromContextMethod == 0");
1974         return FALSE;
1975     }
1976 
1977     // Get the width
1978     if (getAccessibleWidthFromContextMethod != (jmethodID) 0) {
1979         info->width = jniEnv->CallIntMethod(accessBridgeObject,
1980                                             getAccessibleWidthFromContextMethod,
1981                                             accessibleContext);
1982         EXCEPTION_CHECK("Getting AccessibleWidth - call to CallIntMethod()", FALSE);
1983         PrintDebugString("[INFO]:   Width = %d", info->width);
1984     } else {
1985         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleWidthFromContextMethod == 0");
1986         return FALSE;
1987     }
1988 
1989     // Get the height
1990     if (getAccessibleHeightFromContextMethod != (jmethodID) 0) {
1991         info->height = jniEnv->CallIntMethod(accessBridgeObject,
1992                                              getAccessibleHeightFromContextMethod,
1993                                              accessibleContext);
1994         EXCEPTION_CHECK("Getting AccessibleHeight - call to CallIntMethod()", FALSE);
1995         PrintDebugString("[INFO]:   Height = %d", info->height);
1996     } else {
1997         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleHeightFromContextMethod == 0");
1998         return FALSE;
1999     }
2000 
2001     // Get the AccessibleComponent
2002     if (getAccessibleComponentFromContextMethod != (jmethodID) 0) {
2003         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2004                                                    getAccessibleComponentFromContextMethod,
2005                                                    accessibleContext);
2006         EXCEPTION_CHECK("Getting AccessibleComponent - call to CallObjectMethod()", FALSE);
2007         PrintDebugString("[INFO]:   AccessibleComponent = %p", returnedJobject);
2008         info->accessibleComponent = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2009         jniEnv->DeleteLocalRef(returnedJobject);
2010         EXCEPTION_CHECK("Getting AccessibleComponent - call to DeleteLocalRef()", FALSE);
2011     } else {
2012         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleComponentFromContextMethod == 0");
2013         return FALSE;
2014     }
2015 
2016     // Get the AccessibleAction
2017     if (getAccessibleActionFromContextMethod != (jmethodID) 0) {
2018         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2019                                                    getAccessibleActionFromContextMethod,
2020                                                    accessibleContext);
2021         EXCEPTION_CHECK("Getting AccessibleAction - call to CallObjectMethod()", FALSE);
2022         PrintDebugString("[INFO]:   AccessibleAction = %p", returnedJobject);
2023         info->accessibleAction = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2024         jniEnv->DeleteLocalRef(returnedJobject);
2025         EXCEPTION_CHECK("Getting AccessibleAction - call to DeleteLocalRef()", FALSE);
2026     } else {
2027         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleActionFromContextMethod == 0");
2028         return FALSE;
2029     }
2030 
2031     // Get the AccessibleSelection
2032     if (getAccessibleSelectionFromContextMethod != (jmethodID) 0) {
2033         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2034                                                    getAccessibleSelectionFromContextMethod,
2035                                                    accessibleContext);
2036         EXCEPTION_CHECK("Getting AccessibleSelection - call to CallObjectMethod()", FALSE);
2037         PrintDebugString("[INFO]:   AccessibleSelection = %p", returnedJobject);
2038         info->accessibleSelection = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2039         jniEnv->DeleteLocalRef(returnedJobject);
2040         EXCEPTION_CHECK("Getting AccessibleSelection - call to DeleteLocalRef()", FALSE);
2041     } else {
2042         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleSelectionFromContextMethod == 0");
2043         return FALSE;
2044     }
2045 
2046     // Get the AccessibleTable
2047     if (getAccessibleTableFromContextMethod != (jmethodID) 0) {
2048         PrintDebugString("[INFO]: ##### Calling getAccessibleTableFromContextMethod ...");
2049         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2050                                                    getAccessibleTableFromContextMethod,
2051                                                    accessibleContext);
2052         PrintDebugString("[INFO]: ##### ... Returned from getAccessibleTableFromContextMethod");
2053         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2054         PrintDebugString("[INFO]:   ##### AccessibleTable = %p", returnedJobject);
2055         if (returnedJobject != (jobject) 0) {
2056             info->accessibleInterfaces |= cAccessibleTableInterface;
2057         }
2058         jniEnv->DeleteLocalRef(returnedJobject);
2059         EXCEPTION_CHECK("##### Getting AccessibleTable - call to DeleteLocalRef()", FALSE);
2060 
2061         /*
2062           returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2063           getAccessibleTableFromContextMethod,
2064           AccessibleContext);
2065           PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod");
2066           EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2067           PrintDebugString("  ##### AccessibleTable = %X", returnedJobject);
2068           info->accessibleTable = returnedJobject;
2069         */
2070 
2071     } else {
2072         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableFromContextMethod == 0");
2073         return FALSE;
2074     }
2075 
2076     // Get the AccessibleText
2077     if (getAccessibleTextFromContextMethod != (jmethodID) 0) {
2078         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2079                                                    getAccessibleTextFromContextMethod,
2080                                                    accessibleContext);
2081         EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE);
2082         PrintDebugString("[INFO]:   AccessibleText = %p", returnedJobject);
2083         info->accessibleText = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2084         jniEnv->DeleteLocalRef(returnedJobject);
2085         EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE);
2086     } else {
2087         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextFromContextMethod == 0");
2088         return FALSE;
2089     }
2090 
2091     // Get the AccessibleValue
2092     if (getAccessibleValueFromContextMethod != (jmethodID) 0) {
2093         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2094                                                    getAccessibleValueFromContextMethod,
2095                                                    accessibleContext);
2096         EXCEPTION_CHECK("Getting AccessibleValue - call to CallObjectMethod()", FALSE);
2097         PrintDebugString("[INFO]:   AccessibleValue = %p", returnedJobject);
2098         if (returnedJobject != (jobject) 0) {
2099             info->accessibleInterfaces |= cAccessibleValueInterface;
2100         }
2101         jniEnv->DeleteLocalRef(returnedJobject);
2102         EXCEPTION_CHECK("Getting AccessibleValue - call to DeleteLocalRef()", FALSE);
2103     } else {
2104         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleValueFromContextMethod == 0");
2105         return FALSE;
2106     }
2107 
2108     // FIX
2109     // get the AccessibleHypertext
2110     if (getAccessibleHypertextMethod != (jmethodID) 0 &&
2111         getAccessibleHyperlinkCountMethod != (jmethodID) 0 &&
2112         getAccessibleHyperlinkMethod != (jmethodID) 0 &&
2113         getAccessibleHyperlinkTextMethod != (jmethodID) 0 &&
2114         getAccessibleHyperlinkStartIndexMethod != (jmethodID) 0 &&
2115         getAccessibleHyperlinkEndIndexMethod != (jmethodID) 0) {
2116         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2117                                                    getAccessibleHypertextMethod,
2118                                                    accessibleContext);
2119         EXCEPTION_CHECK("Getting AccessibleHypertext - call to CallObjectMethod()", FALSE);
2120         PrintDebugString("[INFO]:   AccessibleHypertext = %p",
2121                          returnedJobject);
2122         if (returnedJobject != (jobject) 0) {
2123             info->accessibleInterfaces |= cAccessibleHypertextInterface;
2124         }
2125         jniEnv->DeleteLocalRef(returnedJobject);
2126         EXCEPTION_CHECK("Getting AccessibleHypertext - call to DeleteLocalRef()", FALSE);
2127     }
2128 
2129     // set new accessibleInterfaces flags from old BOOL values
2130     if(info->accessibleComponent)
2131         info->accessibleInterfaces |= cAccessibleComponentInterface;
2132     if(info->accessibleAction)
2133         info->accessibleInterfaces |= cAccessibleActionInterface;
2134     if(info->accessibleSelection)
2135         info->accessibleInterfaces |= cAccessibleSelectionInterface;
2136     if(info->accessibleText)
2137         info->accessibleInterfaces |= cAccessibleTextInterface;
2138     // FIX END
2139 
2140     return TRUE;
2141 }
2142 
2143 /**
2144  * getAccessibleChildFromContext - performs the Java method call:
2145  *   AccessibleContext AccessBridge.getAccessibleChildContext(AccessibleContext)
2146  *
2147  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2148  *
2149  * Note: this call explicitly goes through the AccessBridge,
2150  * so that it can keep a reference the returned jobject for the JavaVM.
2151  * You must explicity call releaseJavaObject() when you are through using
2152  * the AccessibleContext returned, to let the AccessBridge know it can release the
2153  * object, so that the JavaVM can then garbage collect it.
2154  */
2155 jobject
2156 AccessBridgeJavaEntryPoints::getAccessibleChildFromContext(jobject accessibleContext, jint childIndex) {
2157     jobject returnedAccessibleContext;
2158     jobject globalRef;
2159     jthrowable exception;
2160 
2161     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleChildContext(%p, %d):",
2162                      accessibleContext, childIndex);
2163 
2164     if (getAccessibleChildFromContextMethod != (jmethodID) 0) {
2165         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
2166                                                              getAccessibleChildFromContextMethod,
2167                                                              accessibleContext, childIndex);
2168         EXCEPTION_CHECK("Getting AccessibleChild - call to CallObjectMethod()", FALSE);
2169         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2170         EXCEPTION_CHECK("Getting AccessibleChild - call to NewGlobalRef()", FALSE);
2171         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2172         EXCEPTION_CHECK("Getting AccessibleChild - call to DeleteLocalRef()", FALSE);
2173         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
2174                          returnedAccessibleContext, globalRef);
2175         return globalRef;
2176     } else {
2177         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleChildContextMethod == 0");
2178         return (jobject) 0;
2179     }
2180 }
2181 
2182 /**
2183  * getAccessibleParentFromContext - returns the AccessibleContext parent
2184  *
2185  */
2186 jobject
2187 AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(jobject accessibleContext)
2188 {
2189     jobject returnedAccessibleContext;
2190     jobject globalRef;
2191     jthrowable exception;
2192 
2193     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(%p):", accessibleContext);
2194 
2195     if (getAccessibleParentFromContextMethod != (jmethodID) 0) {
2196         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
2197                                                              getAccessibleParentFromContextMethod,
2198                                                              accessibleContext);
2199         EXCEPTION_CHECK("Getting AccessibleParent - call to CallObjectMethod()", FALSE);
2200         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2201         EXCEPTION_CHECK("Getting AccessibleParent - call to NewGlobalRef()", FALSE);
2202         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2203         EXCEPTION_CHECK("Getting AccessibleParent - call to DeleteLocalRef()", FALSE);
2204         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
2205                          returnedAccessibleContext, globalRef);
2206         return globalRef;
2207     } else {
2208         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleParentFromContextMethod == 0");
2209         return (jobject) 0;
2210     }
2211 }
2212 
2213 
2214 /********** AccessibleTable routines **********************************/
2215 
2216 BOOL
2217 AccessBridgeJavaEntryPoints::getAccessibleTableInfo(jobject accessibleContext,
2218                                                     AccessibleTableInfo *tableInfo) {
2219 
2220     jthrowable exception;
2221 
2222     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo(%p):",
2223                      accessibleContext);
2224 
2225     // get the table row count
2226     if (getAccessibleTableRowCountMethod != (jmethodID) 0) {
2227         tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject,
2228                                                     getAccessibleTableRowCountMethod,
2229                                                     accessibleContext);
2230         EXCEPTION_CHECK("##### Getting AccessibleTableRowCount - call to CallIntMethod()", FALSE);
2231         PrintDebugString("[INFO]:   ##### table row count = %d", tableInfo->rowCount);
2232     } else {
2233         PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowCountMethod == 0");
2234         return FALSE;
2235     }
2236 
2237     // get the table column count
2238     if (getAccessibleTableColumnCountMethod != (jmethodID) 0) {
2239         tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject,
2240                                                        getAccessibleTableColumnCountMethod,
2241                                                        accessibleContext);
2242         EXCEPTION_CHECK("Getting AccessibleTableColumnCount - call to CallIntMethod()", FALSE);
2243         PrintDebugString("[INFO]:   ##### table column count = %d", tableInfo->columnCount);
2244     } else {
2245         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnCountMethod == 0");
2246         return FALSE;
2247     }
2248 
2249     // get the AccessibleTable
2250     if (getAccessibleTableFromContextMethod != (jmethodID) 0) {
2251         PrintDebugString("[INFO]: ##### Calling getAccessibleTableFromContextMethod ...");
2252         jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject,
2253                                                     getAccessibleTableFromContextMethod,
2254                                                     accessibleContext);
2255         PrintDebugString("[INFO]: ##### ... Returned from getAccessibleTableFromContextMethod");
2256         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2257         jobject globalRef = jniEnv->NewGlobalRef(accTable);
2258         EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE);
2259         tableInfo->accessibleTable = (JOBJECT64)globalRef;
2260         PrintDebugString("[INFO]:   ##### accessibleTable = %p", globalRef);
2261     } else {
2262         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableFromContextMethod == 0");
2263         return FALSE;
2264     }
2265 
2266     // cache the AccessibleContext
2267     if (getContextFromAccessibleTableMethod != (jmethodID) 0) {
2268         PrintDebugString("[INFO]: ##### Calling getContextFromAccessibleTable Method ...");
2269         jobject ac = jniEnv->CallObjectMethod(accessBridgeObject,
2270                                               getContextFromAccessibleTableMethod,
2271                                               accessibleContext);
2272         PrintDebugString("[INFO]: ##### ... Returned from getContextFromAccessibleTable Method");
2273         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2274         jobject globalRef = jniEnv->NewGlobalRef(ac);
2275         EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE);
2276         tableInfo->accessibleContext = (JOBJECT64)globalRef;
2277         PrintDebugString("[INFO]:   ##### accessibleContext = %p", globalRef);
2278     } else {
2279         PrintDebugString("[ERROR]: either env == 0 or getContextFromAccessibleTable Method == 0");
2280         return FALSE;
2281     }
2282 
2283     // FIX - set unused elements
2284     tableInfo->caption = NULL;
2285     tableInfo->summary = NULL;
2286 
2287     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo succeeded");
2288     return TRUE;
2289 }
2290 
2291 BOOL
2292 AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(jobject accessibleTable, jint row, jint column,
2293                                                         AccessibleTableCellInfo *tableCellInfo) {
2294 
2295     jthrowable exception;
2296 
2297     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(%p): row=%d, column=%d",
2298                      accessibleTable, row, column);
2299 
2300     // FIX
2301     ZeroMemory(tableCellInfo, sizeof(AccessibleTableCellInfo));
2302     tableCellInfo->row = row;
2303     tableCellInfo->column = column;
2304     // FIX END
2305 
2306     // get the table cell index
2307     if (getAccessibleTableCellIndexMethod != (jmethodID) 0) {
2308         tableCellInfo->index = jniEnv->CallIntMethod(accessBridgeObject,
2309                                                      getAccessibleTableCellIndexMethod,
2310                                                      accessibleTable, row, column);
2311         EXCEPTION_CHECK("##### Getting AccessibleTableCellIndex - call to CallIntMethod()", FALSE);
2312         PrintDebugString("[INFO]:   ##### table cell index = %d", tableCellInfo->index);
2313     } else {
2314         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellIndexMethod == 0");
2315         return FALSE;
2316     }
2317 
2318     // get the table cell row extent
2319     if (getAccessibleTableCellRowExtentMethod != (jmethodID) 0) {
2320         tableCellInfo->rowExtent = jniEnv->CallIntMethod(accessBridgeObject,
2321                                                          getAccessibleTableCellRowExtentMethod,
2322                                                          accessibleTable, row, column);
2323         EXCEPTION_CHECK("##### Getting AccessibleTableCellRowExtentCount - call to CallIntMethod()", FALSE);
2324         PrintDebugString("[INFO]:   ##### table cell row extent = %d", tableCellInfo->rowExtent);
2325     } else {
2326         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellRowExtentMethod == 0");
2327         return FALSE;
2328     }
2329 
2330     // get the table cell column extent
2331     if (getAccessibleTableCellColumnExtentMethod != (jmethodID) 0) {
2332         tableCellInfo->columnExtent = jniEnv->CallIntMethod(accessBridgeObject,
2333                                                             getAccessibleTableCellColumnExtentMethod,
2334                                                             accessibleTable, row, column);
2335         EXCEPTION_CHECK("##### Getting AccessibleTableCellColumnExtentCount - call to CallIntMethod()", FALSE);
2336         PrintDebugString("[INFO]:  ##### table cell column extent = %d", tableCellInfo->columnExtent);
2337     } else {
2338         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellColumnExtentMethod == 0");
2339         return FALSE;
2340     }
2341 
2342     // get whether the table cell is selected
2343     if (isAccessibleTableCellSelectedMethod != (jmethodID) 0) {
2344         tableCellInfo->isSelected = jniEnv->CallBooleanMethod(accessBridgeObject,
2345                                                               isAccessibleTableCellSelectedMethod,
2346                                                               accessibleTable, row, column);
2347         EXCEPTION_CHECK("##### Getting isAccessibleTableCellSelected - call to CallBooleanMethod()", FALSE);
2348         PrintDebugString("[INFO]:   ##### table cell isSelected = %d", tableCellInfo->isSelected);
2349     } else {
2350         PrintDebugString("[ERROR]: either env == 0 or isAccessibleTableCellSelectedMethod == 0");
2351         return FALSE;
2352     }
2353 
2354     // get the table cell AccessibleContext
2355     if (getAccessibleTableCellAccessibleContextMethod != (jmethodID) 0) {
2356         jobject tableCellAC = jniEnv->CallObjectMethod(accessBridgeObject,
2357                                                        getAccessibleTableCellAccessibleContextMethod,
2358                                                        accessibleTable, row, column);
2359         EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to CallObjectMethod()", FALSE);
2360         jobject globalRef = jniEnv->NewGlobalRef(tableCellAC);
2361         EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to NewGlobalRef()", FALSE);
2362         tableCellInfo->accessibleContext = (JOBJECT64)globalRef;
2363         PrintDebugString("[INFO]:   ##### table cell AccessibleContext = %p", globalRef);
2364     } else {
2365         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellAccessibleContextMethod == 0");
2366         return FALSE;
2367     }
2368 
2369     PrintDebugString("[INFO]:  ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo succeeded");
2370     return TRUE;
2371 }
2372 
2373 BOOL
2374 AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(jobject acParent, AccessibleTableInfo *tableInfo) {
2375 
2376     jthrowable exception;
2377 
2378     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(%p):",
2379                      acParent);
2380 
2381     // get the header row count
2382     if (getAccessibleTableRowHeaderRowCountMethod != (jmethodID) 0) {
2383         tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject,
2384                                                     getAccessibleTableRowHeaderRowCountMethod,
2385                                                     acParent);
2386         EXCEPTION_CHECK("##### Getting AccessibleTableRowHeaderRowCount - call to CallIntMethod()", FALSE);
2387         PrintDebugString("[INFO]:   ##### table row count = %d", tableInfo->rowCount);
2388     } else {
2389         PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowHeaderRowCountMethod == 0");
2390         return FALSE;
2391     }
2392 
2393     // get the header column count
2394     if (getAccessibleTableRowHeaderColumnCountMethod != (jmethodID) 0) {
2395         tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject,
2396                                                        getAccessibleTableRowHeaderColumnCountMethod,
2397                                                        acParent);
2398         EXCEPTION_CHECK("Getting AccessibleTableRowHeaderColumnCount - call to CallIntMethod()", FALSE);
2399         PrintDebugString("[INFO]:   ##### table column count = %d", tableInfo->columnCount);
2400     } else {
2401         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowHeaderColumnCountMethod == 0");
2402         return FALSE;
2403     }
2404 
2405     // get the header AccessibleTable
2406     if (getAccessibleTableRowHeaderMethod != (jmethodID) 0) {
2407         jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject,
2408                                                     getAccessibleTableRowHeaderMethod,
2409                                                     acParent);
2410         EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to CallObjectMethod()", FALSE);
2411         jobject globalRef = jniEnv->NewGlobalRef(accTable);
2412         EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to NewGlobalRef()", FALSE);
2413         tableInfo->accessibleTable = (JOBJECT64)globalRef;
2414         PrintDebugString("[INFO]:   ##### row header AccessibleTable = %p", globalRef);
2415     } else {
2416         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowHeaderMethod == 0");
2417         return FALSE;
2418     }
2419 
2420     // FIX - set unused elements
2421     tableInfo->caption = NULL;
2422     tableInfo->summary = NULL;
2423     tableInfo->accessibleContext = NULL;
2424 
2425     PrintDebugString("[INFO]:   ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader succeeded");
2426     return TRUE;
2427 }
2428 
2429 BOOL
2430 AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(jobject acParent, AccessibleTableInfo *tableInfo) {
2431     jthrowable exception;
2432 
2433     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(%p):",
2434                      acParent);
2435 
2436     // get the header row count
2437     if (getAccessibleTableColumnHeaderRowCountMethod != (jmethodID) 0) {
2438         tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject,
2439                                                     getAccessibleTableColumnHeaderRowCountMethod,
2440                                                     acParent);
2441         EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeaderRowCount - call to CallIntMethod()", FALSE);
2442         PrintDebugString("[INFO]:   ##### table row count = %d", tableInfo->rowCount);
2443     } else {
2444         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleColumnHeaderRowCountMethod == 0");
2445         return FALSE;
2446     }
2447 
2448     // get the header column count
2449     if (getAccessibleTableColumnHeaderColumnCountMethod != (jmethodID) 0) {
2450         tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject,
2451                                                        getAccessibleTableColumnHeaderColumnCountMethod,
2452                                                        acParent);
2453         EXCEPTION_CHECK("Getting AccessibleTableColumnHeaderColumnCount - call to CallIntMethod()", FALSE);
2454         PrintDebugString("[INFO]:   ##### table column count = %d", tableInfo->columnCount);
2455     } else {
2456         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnHeaderColumnCountMethod == 0");
2457         return FALSE;
2458     }
2459     // get the header AccessibleTable
2460     if (getAccessibleTableColumnHeaderMethod != (jmethodID) 0) {
2461         jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject,
2462                                                     getAccessibleTableColumnHeaderMethod,
2463                                                     acParent);
2464         EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to CallObjectMethod()", FALSE);
2465         jobject globalRef = jniEnv->NewGlobalRef(accTable);
2466         EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to NewGlobalRef()", FALSE);
2467         tableInfo->accessibleTable = (JOBJECT64)globalRef;
2468         PrintDebugString("[INFO]:   ##### column header AccessibleTable = %p", globalRef);
2469     } else {
2470         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnHeaderMethod == 0");
2471         return FALSE;
2472     }
2473 
2474     // FIX - set unused elements
2475     tableInfo->caption = NULL;
2476     tableInfo->summary = NULL;
2477     tableInfo->accessibleContext = NULL;
2478 
2479     PrintDebugString("[INFO]:   ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader succeeded");
2480     return TRUE;
2481 }
2482 
2483 jobject
2484 AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(jobject acParent, jint row) {
2485 
2486     jobject returnedAccessibleContext;
2487     jobject globalRef;
2488     jthrowable exception;
2489 
2490     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(%p):",
2491                      acParent);
2492 
2493     if (getAccessibleTableRowDescriptionMethod != (jmethodID) 0) {
2494         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
2495                                                              getAccessibleTableRowDescriptionMethod,
2496                                                              acParent, row);
2497         EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to CallObjectMethod()", FALSE);
2498         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2499         EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to NewGlobalRef()", FALSE);
2500         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2501         EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to DeleteLocalRef()", FALSE);
2502         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
2503                          returnedAccessibleContext, globalRef);
2504         return globalRef;
2505     } else {
2506         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowDescriptionMethod == 0");
2507         return (jobject) 0;
2508     }
2509 }
2510 
2511 jobject
2512 AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(jobject acParent, jint column) {
2513 
2514     jobject returnedAccessibleContext;
2515     jobject globalRef;
2516     jthrowable exception;
2517 
2518     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(%p):",
2519                      acParent);
2520 
2521     if (getAccessibleTableColumnDescriptionMethod != (jmethodID) 0) {
2522         returnedAccessibleContext = jniEnv->CallObjectMethod(
2523                                                              accessBridgeObject,
2524                                                              getAccessibleTableColumnDescriptionMethod,
2525                                                              acParent, column);
2526         EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to CallObjectMethod()", FALSE);
2527         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2528         EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to NewGlobalRef()", FALSE);
2529         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2530         EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to DeleteLocalRef()", FALSE);
2531         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
2532                          returnedAccessibleContext, globalRef);
2533         return globalRef;
2534     } else {
2535         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnDescriptionMethod == 0");
2536         return (jobject) 0;
2537     }
2538 }
2539 
2540 jint
2541 AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(jobject accessibleTable) {
2542 
2543     jthrowable exception;
2544     jint count;
2545 
2546     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(%p)",
2547                      accessibleTable);
2548 
2549     // Get the table row selection count
2550     if (getAccessibleTableRowSelectionCountMethod != (jmethodID) 0) {
2551         count = jniEnv->CallIntMethod(accessBridgeObject,
2552                                       getAccessibleTableRowSelectionCountMethod,
2553                                       accessibleTable);
2554         EXCEPTION_CHECK("##### Getting AccessibleTableRowSelectionCount - call to CallIntMethod()", FALSE);
2555         PrintDebugString("[INFO]:   ##### table row selection count = %d", count);
2556         return count;
2557     } else {
2558         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowSelectionCountMethod == 0");
2559         return 0;
2560     }
2561 
2562     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount failed");
2563     return 0;
2564 }
2565 
2566 BOOL
2567 AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(jobject accessibleTable, jint row) {
2568     jthrowable exception;
2569     BOOL result;
2570 
2571     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(%p, %d)",
2572                      accessibleTable, row);
2573 
2574     if (isAccessibleTableRowSelectedMethod != (jmethodID) 0) {
2575         result = jniEnv->CallBooleanMethod(accessBridgeObject,
2576                                            isAccessibleTableRowSelectedMethod,
2577                                            accessibleTable, row);
2578         EXCEPTION_CHECK("##### Getting isAccessibleTableRowSelected - call to CallBooleanMethod()", FALSE);
2579         PrintDebugString("[INFO]:   ##### table row isSelected = %d", result);
2580         return result;
2581     } else {
2582         PrintDebugString("[ERROR]: either env == 0 or isAccessibleTableRowSelectedMethod == 0");
2583         return FALSE;
2584     }
2585 
2586     PrintDebugString("[ERROR]:  AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected failed");
2587     return FALSE;
2588 }
2589 
2590 BOOL
2591 AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(jobject accessibleTable, jint count,
2592                                                              jint *selections) {
2593 
2594     jthrowable exception;
2595 
2596     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(%p, %d %p)",
2597                      accessibleTable, count, selections);
2598 
2599     if (getAccessibleTableRowSelectionsMethod == (jmethodID) 0) {
2600         return FALSE;
2601     }
2602     // Get the table row selections
2603     for (int i = 0; i < count; i++) {
2604 
2605         selections[i] = jniEnv->CallIntMethod(accessBridgeObject,
2606                                               getAccessibleTableRowSelectionsMethod,
2607                                               accessibleTable,
2608                                               i);
2609         EXCEPTION_CHECK("##### Getting AccessibleTableRowSelections - call to CallIntMethod()", FALSE);
2610         PrintDebugString("[INFO]:   ##### table row selection[%d] = %d", i, selections[i]);
2611     }
2612 
2613     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections succeeded");
2614     return TRUE;
2615 }
2616 
2617 
2618 jint
2619 AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(jobject accessibleTable) {
2620 
2621     jthrowable exception;
2622     jint count;
2623 
2624     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(%p)",
2625                      accessibleTable);
2626 
2627     // Get the table column selection count
2628     if (getAccessibleTableColumnSelectionCountMethod != (jmethodID) 0) {
2629         count = jniEnv->CallIntMethod(accessBridgeObject,
2630                                       getAccessibleTableColumnSelectionCountMethod,
2631                                       accessibleTable);
2632         EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelectionCount - call to CallIntMethod()", FALSE);
2633         PrintDebugString("[INFO]:   ##### table column selection count = %d", count);
2634         return count;
2635     } else {
2636         PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowCountMethod == 0");
2637         return 0;
2638     }
2639 
2640     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount failed");
2641     return 0;
2642 }
2643 
2644 BOOL
2645 AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(jobject accessibleTable, jint column) {
2646     jthrowable exception;
2647     BOOL result;
2648 
2649     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(%p, %d)",
2650                      accessibleTable, column);
2651 
2652     if (isAccessibleTableColumnSelectedMethod != (jmethodID) 0) {
2653         result = jniEnv->CallBooleanMethod(accessBridgeObject,
2654                                            isAccessibleTableColumnSelectedMethod,
2655                                            accessibleTable, column);
2656         EXCEPTION_CHECK("##### Getting isAccessibleTableColumnSelected - call to CallBooleanMethod()", FALSE);
2657         PrintDebugString("[INFO]:   ##### table column isSelected = %d", result);
2658         return result;
2659     } else {
2660         PrintDebugString("[ERROR]:  either env == 0 or isAccessibleTableColumnSelectedMethod == 0");
2661         return FALSE;
2662     }
2663 
2664     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected failed");
2665     return FALSE;
2666 }
2667 
2668 BOOL
2669 AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(jobject accessibleTable, jint count,
2670                                                                 jint *selections) {
2671     jthrowable exception;
2672 
2673     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(%p, %d, %p)",
2674                      accessibleTable, count, selections);
2675 
2676     if (getAccessibleTableColumnSelectionsMethod == (jmethodID) 0) {
2677         return FALSE;
2678     }
2679     // Get the table column selections
2680     for (int i = 0; i < count; i++) {
2681 
2682         selections[i] = jniEnv->CallIntMethod(accessBridgeObject,
2683                                               getAccessibleTableColumnSelectionsMethod,
2684                                               accessibleTable,
2685                                               i);
2686         EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelections - call to CallIntMethod()", FALSE);
2687         PrintDebugString("[INFO]:   ##### table Column selection[%d] = %d", i, selections[i]);
2688     }
2689 
2690     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections succeeded");
2691     return TRUE;
2692 }
2693 
2694 
2695 jint
2696 AccessBridgeJavaEntryPoints::getAccessibleTableRow(jobject accessibleTable, jint index) {
2697     jthrowable exception;
2698     jint result;
2699 
2700     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow(%p, index=%d)",
2701                      accessibleTable, index);
2702 
2703     if (getAccessibleTableRowMethod != (jmethodID) 0) {
2704         result = jniEnv->CallIntMethod(accessBridgeObject,
2705                                        getAccessibleTableRowMethod,
2706                                        accessibleTable, index);
2707         EXCEPTION_CHECK("##### Getting AccessibleTableRow - call to CallIntMethod()", FALSE);
2708         PrintDebugString("[INFO]:   ##### table row = %d", result);
2709         return result;
2710     } else {
2711         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowMethod == 0");
2712         return -1;
2713     }
2714 
2715     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow failed");
2716     return -1;
2717 }
2718 
2719 jint
2720 AccessBridgeJavaEntryPoints::getAccessibleTableColumn(jobject accessibleTable, jint index) {
2721     jthrowable exception;
2722     jint result;
2723 
2724     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn(%p, index=%d)",
2725                      accessibleTable, index);
2726 
2727     if (getAccessibleTableColumnMethod != (jmethodID) 0) {
2728         result = jniEnv->CallIntMethod(accessBridgeObject,
2729                                        getAccessibleTableColumnMethod,
2730                                        accessibleTable, index);
2731         EXCEPTION_CHECK("##### Getting AccessibleTableColumn - call to CallIntMethod()", FALSE);
2732         PrintDebugString("[INFO]:   ##### table column = %d", result);
2733         return result;
2734     } else {
2735         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnMethod == 0");
2736         return -1;
2737     }
2738 
2739     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn failed");
2740     return -1;
2741 }
2742 
2743 jint
2744 AccessBridgeJavaEntryPoints::getAccessibleTableIndex(jobject accessibleTable, jint row, jint column) {
2745     jthrowable exception;
2746     jint result;
2747 
2748     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex(%p, row=%d, col=%d)",
2749                      accessibleTable, row, column);
2750 
2751     if (getAccessibleTableIndexMethod != (jmethodID) 0) {
2752         result = jniEnv->CallIntMethod(accessBridgeObject,
2753                                        getAccessibleTableIndexMethod,
2754                                        accessibleTable, row, column);
2755         EXCEPTION_CHECK("##### Getting getAccessibleTableIndex - call to CallIntMethod()", FALSE);
2756         PrintDebugString("[INFO]:   ##### table index = %d", result);
2757         return result;
2758     } else {
2759         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableIndexMethod == 0");
2760         return -1;
2761     }
2762 
2763     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex failed");
2764     return -1;
2765 }
2766 
2767 /********** end AccessibleTable routines ******************************/
2768 
2769 
2770 /********** begin AccessibleRelationSet routines **********************/
2771 
2772 BOOL
2773 AccessBridgeJavaEntryPoints::getAccessibleRelationSet(jobject accessibleContext,
2774                                                       AccessibleRelationSetInfo *relationSet) {
2775 
2776     jthrowable exception;
2777     const wchar_t *stringBytes;
2778     jsize length;
2779 
2780     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet(%p, %p)",
2781                      accessibleContext, relationSet);
2782 
2783     if (getAccessibleRelationCountMethod == (jmethodID) 0 ||
2784         getAccessibleRelationKeyMethod == (jmethodID) 0 ||
2785         getAccessibleRelationTargetCountMethod == (jmethodID) 0 ||
2786         getAccessibleRelationTargetMethod == (jmethodID) 0) {
2787         return FALSE;
2788     }
2789 
2790     // Get the relations set count
2791     relationSet->relationCount = jniEnv->CallIntMethod(accessBridgeObject,
2792                                                        getAccessibleRelationCountMethod,
2793                                                        accessibleContext);
2794     EXCEPTION_CHECK("##### Getting AccessibleRelationCount - call to CallIntMethod()", FALSE);
2795     PrintDebugString("[INFO]:   ##### AccessibleRelation count = %d", relationSet->relationCount);
2796 
2797 
2798     // Get the relation set
2799     for (int i = 0; i < relationSet->relationCount && i < MAX_RELATIONS; i++) {
2800 
2801         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
2802                                                        getAccessibleRelationKeyMethod,
2803                                                        accessibleContext,
2804                                                        i);
2805 
2806         EXCEPTION_CHECK("Getting AccessibleRelationKey - call to CallObjectMethod()", FALSE);
2807         if (js != (jstring) 0) {
2808             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
2809             EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringChars()", FALSE);
2810             wcsncpy(relationSet->relations[i].key, stringBytes, (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t)));
2811             length = jniEnv->GetStringLength(js);
2812             relationSet->relations[i].key [length < (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t)) ?
2813                                            length : (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t))-2] = (wchar_t) 0;
2814             EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringLength()", FALSE);
2815             jniEnv->ReleaseStringChars(js, stringBytes);
2816             EXCEPTION_CHECK("Getting AccessibleRelation key - call to ReleaseStringChars()", FALSE);
2817             // jniEnv->CallVoidMethod(accessBridgeObject,
2818             //                        decrementReferenceMethod, js);
2819             //EXCEPTION_CHECK("Getting AccessibleRelation key - call to CallVoidMethod()", FALSE);
2820             PrintDebugString("[INFO]: ##### AccessibleRelation key = %ls", relationSet->relations[i].key );
2821             jniEnv->DeleteLocalRef(js);
2822             EXCEPTION_CHECK("Getting AccessibleRelation key - call to DeleteLocalRef()", FALSE);
2823         } else {
2824             PrintDebugString("[WARN]:   AccessibleRelation key is null.");
2825             relationSet->relations[i].key [0] = (wchar_t) 0;
2826         }
2827 
2828         relationSet->relations[i].targetCount = jniEnv->CallIntMethod(accessBridgeObject,
2829                                                                       getAccessibleRelationTargetCountMethod,
2830                                                                       accessibleContext,
2831                                                                       i);
2832 
2833         for (int j = 0; j < relationSet->relations[i].targetCount && j < MAX_RELATION_TARGETS; j++) {
2834             jobject target = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleRelationTargetMethod,
2835                                                       accessibleContext, i, j);
2836             EXCEPTION_CHECK("Getting AccessibleRelationSet - call to CallObjectMethod()", FALSE);
2837             jobject globalRef = jniEnv->NewGlobalRef(target);
2838             EXCEPTION_CHECK("Getting AccessibleRelationSet - call to NewGlobalRef()", FALSE);
2839             relationSet->relations[i].targets[j] = (JOBJECT64)globalRef;
2840             PrintDebugString("[INFO]:   relation set item: %p", globalRef);
2841         }
2842     }
2843 
2844     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet succeeded");
2845     return TRUE;
2846 }
2847 
2848 
2849 /********** end AccessibleRelationSet routines ************************/
2850 
2851 
2852 /********** begin AccessibleHypertext routines **********************/
2853 
2854 BOOL
2855 AccessBridgeJavaEntryPoints::getAccessibleHypertext(jobject accessibleContext,
2856                                                     AccessibleHypertextInfo *hypertext) {
2857 
2858     jthrowable exception;
2859     const wchar_t *stringBytes;
2860     jsize length;
2861 
2862     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext(%p, %p)",
2863                      accessibleContext, hypertext);
2864 
2865     // get the AccessibleHypertext
2866     jobject ht = jniEnv->CallObjectMethod(accessBridgeObject,
2867                                           getAccessibleHypertextMethod,
2868                                           accessibleContext);
2869     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to CallObjectMethod()", FALSE);
2870     jobject globalRef = jniEnv->NewGlobalRef(ht);
2871     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE);
2872     hypertext->accessibleHypertext = (JOBJECT64)globalRef;
2873     PrintDebugString("[INFO]:   ##### AccessibleHypertext = %p", globalRef);
2874 
2875     if (hypertext->accessibleHypertext == 0) {
2876         PrintDebugString("[WARN]:   ##### null AccessibleHypertext; returning FALSE");
2877         return false;
2878     }
2879 
2880     // get the hyperlink count
2881     hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject,
2882                                                  getAccessibleHyperlinkCountMethod,accessibleContext);
2883 
2884     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE);
2885     PrintDebugString("[INFO]:   ##### hyperlink count = %d", hypertext->linkCount);
2886 
2887 
2888     // get the hypertext links
2889     for (int i = 0; i < hypertext->linkCount && i < MAX_HYPERLINKS; i++) {
2890 
2891         // get the hyperlink
2892         jobject hl = jniEnv->CallObjectMethod(accessBridgeObject,
2893                                               getAccessibleHyperlinkMethod,
2894                                               accessibleContext,
2895                                               i);
2896         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE);
2897         jobject globalRef = jniEnv->NewGlobalRef(hl);
2898         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
2899         hypertext->links[i].accessibleHyperlink = (JOBJECT64)globalRef;
2900         PrintDebugString("[INFO]:   ##### AccessibleHyperlink = %p", globalRef);
2901 
2902         // get the hyperlink text
2903         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
2904                                                        getAccessibleHyperlinkTextMethod,
2905                                                        hypertext->links[i].accessibleHyperlink,
2906                                                        i);
2907 
2908         EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE);
2909         if (js != (jstring) 0) {
2910             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
2911             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE);
2912             wcsncpy(hypertext->links[i].text, stringBytes, (sizeof(hypertext->links[i].text) / sizeof(wchar_t)));
2913             length = jniEnv->GetStringLength(js);
2914             if (length >= (sizeof(hypertext->links[i].text) / sizeof(wchar_t))) {
2915                 length = (sizeof(hypertext->links[i].text) / sizeof(wchar_t)) - 2;
2916             }
2917             hypertext->links[i].text[length] = (wchar_t) 0;
2918             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE);
2919             jniEnv->ReleaseStringChars(js, stringBytes);
2920             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE);
2921             // jniEnv->CallVoidMethod(accessBridgeObject,
2922             //                                     decrementReferenceMethod, js);
2923             //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
2924             PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", hypertext->links[i].text );
2925             jniEnv->DeleteLocalRef(js);
2926             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
2927         } else {
2928             PrintDebugString("[WARN]:   AccessibleHyperlink text is null.");
2929             hypertext->links[i].text[0] = (wchar_t) 0;
2930         }
2931 
2932         hypertext->links[i].startIndex = jniEnv->CallIntMethod(accessBridgeObject,
2933                                                                getAccessibleHyperlinkStartIndexMethod,
2934                                                                hypertext->links[i].accessibleHyperlink,
2935                                                                i);
2936         EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
2937         PrintDebugString("[INFO]:   ##### hyperlink start index = %d", hypertext->links[i].startIndex);
2938 
2939 
2940         hypertext->links[i].endIndex = jniEnv->CallIntMethod(accessBridgeObject,
2941                                                              getAccessibleHyperlinkEndIndexMethod,
2942                                                              hypertext->links[i].accessibleHyperlink,
2943                                                              i);
2944         EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
2945         PrintDebugString("[INFO]:   ##### hyperlink end index = %d", hypertext->links[i].endIndex);
2946 
2947     }
2948 
2949     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext succeeded");
2950     return TRUE;
2951 }
2952 
2953 /*
2954  * Activates an AccessibleHyperlink
2955  */
2956 BOOL
2957 AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(jobject accessibleContext,
2958                                                          jobject accessibleHyperlink) {
2959 
2960     jthrowable exception;
2961     BOOL returnVal;
2962 
2963     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(%p, %p):",
2964                      accessibleContext, accessibleHyperlink);
2965 
2966     if (activateAccessibleHyperlinkMethod != (jmethodID) 0) {
2967         returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, activateAccessibleHyperlinkMethod,
2968                                                      accessibleContext, accessibleHyperlink);
2969         EXCEPTION_CHECK("activateAccessibleHyperlink - call to CallBooleanMethod()", FALSE);
2970         return returnVal;
2971     } else {
2972         PrintDebugString("[ERROR]: either jniEnv == 0 or activateAccessibleHyperlinkMethod == 0");
2973         return FALSE;
2974     }
2975 }
2976 
2977 
2978 /*
2979  * This method is used to iterate through the hyperlinks in a component.  It
2980  * returns hypertext information for a component starting at hyperlink index
2981  * nStartIndex.  No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will
2982  * be returned for each call to this method.
2983  * returns FALSE on error.
2984  */
2985 BOOL
2986 AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(const jobject accessibleContext,
2987                                                        const jint nStartIndex,
2988                                                        /* OUT */ AccessibleHypertextInfo *hypertext) {
2989 
2990     jthrowable exception;
2991     const wchar_t *stringBytes;
2992     jsize length;
2993     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(%p, %p, startIndex = %d)",
2994                      accessibleContext, hypertext, nStartIndex);
2995 
2996     // get the AccessibleHypertext
2997     jobject ht = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleHypertextMethod,
2998                                                               accessibleContext);
2999     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to CallObjectMethod()", FALSE);
3000     jobject globalRef = jniEnv->NewGlobalRef(ht);
3001     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE);
3002     hypertext->accessibleHypertext = (JOBJECT64)globalRef;
3003     PrintDebugString("[INFO]:   ##### AccessibleHypertext = %p", globalRef);
3004     if (hypertext->accessibleHypertext == 0) {
3005         PrintDebugString("[WARN]:   ##### null AccessibleHypertext; returning FALSE");
3006         return FALSE;
3007     }
3008 
3009     // get the hyperlink count
3010     hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod,
3011                                                  accessibleContext);
3012     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE);
3013     PrintDebugString("[INFO]:   ##### hyperlink count = %d", hypertext->linkCount);
3014 
3015     if (nStartIndex >= hypertext->linkCount) {
3016         return FALSE;
3017     }
3018 
3019     // get the hypertext links
3020     // NOTE: To avoid a crash when there are more than MAX_HYPERLINKS (64) links
3021     // in the document, test for i < MAX_HYPERLINKS in addition to
3022     // i < hypertext->linkCount
3023     int bufIndex = 0;
3024     for (int i = nStartIndex; (i < hypertext->linkCount) && (i < nStartIndex + MAX_HYPERLINKS); i++) {
3025         PrintDebugString("[INFO]:   getting hyperlink %d ...", i);
3026 
3027         // get the hyperlink
3028         jobject hl = jniEnv->CallObjectMethod(accessBridgeObject,
3029                                               getAccessibleHyperlinkMethod,
3030                                               hypertext->accessibleHypertext,
3031                                               i);
3032         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE);
3033         jobject globalRef = jniEnv->NewGlobalRef(hl);
3034         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
3035         hypertext->links[bufIndex].accessibleHyperlink = (JOBJECT64)globalRef;
3036         PrintDebugString("[INFO]:   ##### AccessibleHyperlink = %p", globalRef);
3037 
3038         // get the hyperlink text
3039         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3040                                                        getAccessibleHyperlinkTextMethod,
3041                                                        hypertext->links[bufIndex].accessibleHyperlink,
3042                                                        i);
3043 
3044         EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE);
3045         if (js != (jstring) 0) {
3046             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3047             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE);
3048             wcsncpy(hypertext->links[bufIndex].text, stringBytes,
3049                     (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t)));
3050             length = jniEnv->GetStringLength(js);
3051             if (length >= (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t))) {
3052                 length = (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t)) - 2;
3053             }
3054             hypertext->links[bufIndex].text[length] = (wchar_t) 0;
3055             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE);
3056             jniEnv->ReleaseStringChars(js, stringBytes);
3057             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE);
3058             // jniEnv->CallVoidMethod(accessBridgeObject,
3059             //                        decrementReferenceMethod, js);
3060             //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
3061             PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", hypertext->links[bufIndex].text );
3062             jniEnv->DeleteLocalRef(js);
3063             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
3064 
3065         } else {
3066             PrintDebugString("[WARN]:   AccessibleHyperlink text is null.");
3067             hypertext->links[bufIndex].text[0] = (wchar_t) 0;
3068         }
3069 
3070         hypertext->links[bufIndex].startIndex = jniEnv->CallIntMethod(accessBridgeObject,
3071                                                                       getAccessibleHyperlinkStartIndexMethod,
3072                                                                       hypertext->links[bufIndex].accessibleHyperlink,
3073                                                                       i);
3074         EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
3075         PrintDebugString("[INFO]:   ##### hyperlink start index = %d", hypertext->links[bufIndex].startIndex);
3076 
3077         hypertext->links[bufIndex].endIndex = jniEnv->CallIntMethod(accessBridgeObject,
3078                                                                     getAccessibleHyperlinkEndIndexMethod,
3079                                                                     hypertext->links[bufIndex].accessibleHyperlink,
3080                                                                     i);
3081         EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
3082         PrintDebugString("[INFO]:   ##### hyperlink end index = %d", hypertext->links[bufIndex].endIndex);
3083 
3084         bufIndex++;
3085     }
3086 
3087     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt succeeded");
3088     return TRUE;
3089 }
3090 
3091 jint AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(const jobject accessibleContext) {
3092 
3093     jthrowable exception;
3094 
3095     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(%X)",
3096                      accessibleContext);
3097 
3098     if (getAccessibleHyperlinkCountMethod == (jmethodID)0) {
3099         return -1;
3100     }
3101 
3102     // get the hyperlink count
3103     jint linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod,
3104                                            accessibleContext);
3105     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", -1);
3106     PrintDebugString("[INFO]:   ##### hyperlink count = %d", linkCount);
3107 
3108     return linkCount;
3109 }
3110 
3111 
3112 jint AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(const jobject hypertext,
3113                                                                   const jint nIndex) {
3114 
3115     jthrowable exception;
3116 
3117     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(%p, index = %d)",
3118                      hypertext, nIndex);
3119 
3120     if (getAccessibleHypertextLinkIndexMethod == (jmethodID)0) {
3121         return -1;
3122     }
3123 
3124     // get the hyperlink index
3125     jint index = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHypertextLinkIndexMethod,
3126                                        hypertext, nIndex);
3127 
3128     EXCEPTION_CHECK("##### Getting hyperlink index - call to CallIntMethod()", -1);
3129     PrintDebugString("[INFO]:   ##### hyperlink index = %d", index);
3130 
3131     return index;
3132 }
3133 
3134 BOOL AccessBridgeJavaEntryPoints::getAccessibleHyperlink(jobject hypertext,
3135                                                          const jint index,
3136                                                          /* OUT */ AccessibleHyperlinkInfo *info) {
3137 
3138     jthrowable exception;
3139     const wchar_t *stringBytes;
3140     jsize length;
3141 
3142     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHyperlink(%p, index = %d)",
3143                      hypertext, index);
3144 
3145 
3146     // get the hyperlink
3147     jobject hl = jniEnv->CallObjectMethod(accessBridgeObject,
3148                                           getAccessibleHyperlinkMethod,
3149                                           hypertext,
3150                                           index);
3151     EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE);
3152     jobject globalRef = jniEnv->NewGlobalRef(hl);
3153     EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
3154     info->accessibleHyperlink = (JOBJECT64)globalRef;
3155     PrintDebugString("[INFO]:   ##### AccessibleHyperlink = %p", globalRef);
3156 
3157     // get the hyperlink text
3158     jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3159                                                    getAccessibleHyperlinkTextMethod,
3160                                                    info->accessibleHyperlink,
3161                                                    index);
3162 
3163     EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE);
3164     if (js != (jstring) 0) {
3165         stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3166         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE);
3167         wcsncpy(info->text, stringBytes,
3168                 (sizeof(info->text) / sizeof(wchar_t)));
3169         length = jniEnv->GetStringLength(js);
3170         if (length >= (sizeof(info->text) / sizeof(wchar_t))) {
3171             length = (sizeof(info->text) / sizeof(wchar_t)) - 2;
3172         }
3173         info->text[length] = (wchar_t) 0;
3174         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE);
3175         jniEnv->ReleaseStringChars(js, stringBytes);
3176         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE);
3177         // jniEnv->CallVoidMethod(accessBridgeObject,
3178         //                        decrementReferenceMethod, js);
3179         //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
3180         PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", info->text );
3181         jniEnv->DeleteLocalRef(js);
3182         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
3183 
3184     } else {
3185         PrintDebugString("[WARN]:   AccessibleHyperlink text is null.");
3186         info->text[0] = (wchar_t) 0;
3187     }
3188 
3189     info->startIndex = jniEnv->CallIntMethod(accessBridgeObject,
3190                                              getAccessibleHyperlinkStartIndexMethod,
3191                                              info->accessibleHyperlink,
3192                                              index);
3193     EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
3194     PrintDebugString("[INFO]:   ##### hyperlink start index = %d", info->startIndex);
3195 
3196     info->endIndex = jniEnv->CallIntMethod(accessBridgeObject,
3197                                            getAccessibleHyperlinkEndIndexMethod,
3198                                            info->accessibleHyperlink,
3199                                            index);
3200     EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
3201     PrintDebugString("[INFO]:   ##### hyperlink end index = %d", info->endIndex);
3202 
3203     return TRUE;
3204 }
3205 
3206 
3207 /********** end AccessibleHypertext routines ************************/
3208 
3209 // Accessible Keybinding methods
3210 BOOL AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(jobject accessibleContext,
3211                                                            AccessibleKeyBindings *keyBindings) {
3212 
3213     jthrowable exception;
3214 
3215     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(%p, %p)",
3216                      accessibleContext, keyBindings);
3217 
3218     if (getAccessibleKeyBindingsCountMethod == (jmethodID) 0 ||
3219         getAccessibleKeyBindingCharMethod == (jmethodID) 0 ||
3220         getAccessibleKeyBindingModifiersMethod == (jmethodID) 0) {
3221         return FALSE;
3222     }
3223 
3224     // get the key binding count
3225     keyBindings->keyBindingsCount = jniEnv->CallIntMethod(accessBridgeObject,
3226                                                           getAccessibleKeyBindingsCountMethod, accessibleContext);
3227 
3228     EXCEPTION_CHECK("##### Getting key bindings count - call to CallIntMethod()", FALSE);
3229 
3230     PrintDebugString("[INFO]:   ##### key bindings count = %d", keyBindings->keyBindingsCount);
3231 
3232     // get the key bindings
3233     for (int i = 0; i < keyBindings->keyBindingsCount && i < MAX_KEY_BINDINGS; i++) {
3234 
3235         // get the key binding character
3236         keyBindings->keyBindingInfo[i].character = jniEnv->CallCharMethod(accessBridgeObject,
3237                                                                           getAccessibleKeyBindingCharMethod,
3238                                                                           accessibleContext,
3239                                                                           i);
3240         EXCEPTION_CHECK("##### Getting key binding character - call to CallCharMethod()", FALSE);
3241         PrintDebugString("[INFO]:   ##### key binding character = %c"\
3242                          "          ##### key binding character in hex = %hx"\
3243                          , keyBindings->keyBindingInfo[i].character, keyBindings->keyBindingInfo[i].character);
3244 
3245         // get the key binding modifiers
3246         keyBindings->keyBindingInfo[i].modifiers = jniEnv->CallIntMethod(accessBridgeObject,
3247                                                                          getAccessibleKeyBindingModifiersMethod,
3248                                                                          accessibleContext,
3249                                                                          i);
3250         EXCEPTION_CHECK("##### Getting key binding modifiers - call to CallIntMethod()", FALSE);
3251         PrintDebugString("[INFO]:  ##### key binding modifiers = %x", keyBindings->keyBindingInfo[i].modifiers);
3252     }
3253     return FALSE;
3254 }
3255 
3256 // AccessibleIcon methods
3257 BOOL AccessBridgeJavaEntryPoints::getAccessibleIcons(jobject accessibleContext,
3258                                                      AccessibleIcons *icons) {
3259 
3260     jthrowable exception;
3261     const wchar_t *stringBytes;
3262     jsize length;
3263 
3264     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)",
3265                      accessibleContext, icons);
3266 
3267     if (getAccessibleIconsCountMethod == (jmethodID) 0 ||
3268         getAccessibleIconDescriptionMethod == (jmethodID) 0 ||
3269         getAccessibleIconHeightMethod == (jmethodID) 0 ||
3270         getAccessibleIconWidthMethod == (jmethodID) 0) {
3271         PrintDebugString("[WARN]:   ##### missing method(s) !!!");
3272         return FALSE;
3273     }
3274 
3275 
3276     // get the icons count
3277     icons->iconsCount = jniEnv->CallIntMethod(accessBridgeObject,
3278                                               getAccessibleIconsCountMethod, accessibleContext);
3279 
3280     EXCEPTION_CHECK("##### Getting icons count - call to CallIntMethod()", FALSE);
3281     PrintDebugString("[INFO]:   ##### icons count = %d", icons->iconsCount);
3282 
3283 
3284     // get the icons
3285     for (int i = 0; i < icons->iconsCount && i < MAX_ICON_INFO; i++) {
3286 
3287         // get the icon description
3288         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3289                                                        getAccessibleIconDescriptionMethod,
3290                                                        accessibleContext,
3291                                                        i);
3292 
3293         EXCEPTION_CHECK("Getting icon description - call to CallObjectMethod()", FALSE);
3294         if (js != (jstring) 0) {
3295             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3296             EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringChars()", FALSE);
3297             wcsncpy(icons->iconInfo[i].description, stringBytes, (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t)));
3298             length = jniEnv->GetStringLength(js);
3299             if (length >= (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t))) {
3300                 length = (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t)) - 2;
3301             }
3302             icons->iconInfo[i].description[length] = (wchar_t) 0;
3303             EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringLength()", FALSE);
3304             jniEnv->ReleaseStringChars(js, stringBytes);
3305             EXCEPTION_CHECK("Getting AccessibleIcon description - call to ReleaseStringChars()", FALSE);
3306             // jniEnv->CallVoidMethod(accessBridgeObject,
3307             //                        decrementReferenceMethod, js);
3308             //EXCEPTION_CHECK("Getting AccessibleIcon description - call to CallVoidMethod()", FALSE);
3309             PrintDebugString("[INFO]: ##### AccessibleIcon description = %ls", icons->iconInfo[i].description );
3310             jniEnv->DeleteLocalRef(js);
3311             EXCEPTION_CHECK("Getting AccessibleIcon description - call to DeleteLocalRef()", FALSE);
3312         } else {
3313             PrintDebugString("[WARN]:   AccessibleIcon description is null.");
3314             icons->iconInfo[i].description[0] = (wchar_t) 0;
3315         }
3316 
3317 
3318         // get the icon height
3319         icons->iconInfo[i].height = jniEnv->CallIntMethod(accessBridgeObject,
3320                                                           getAccessibleIconHeightMethod,
3321                                                           accessibleContext,
3322                                                           i);
3323         EXCEPTION_CHECK("##### Getting icon height - call to CallIntMethod()", FALSE);
3324         PrintDebugString("[INFO]:   ##### icon height = %d", icons->iconInfo[i].height);
3325 
3326         // get the icon width
3327         icons->iconInfo[i].width = jniEnv->CallIntMethod(accessBridgeObject,
3328                                                          getAccessibleIconWidthMethod,
3329                                                          accessibleContext,
3330                                                          i);
3331         EXCEPTION_CHECK("##### Getting icon width - call to CallIntMethod()", FALSE);
3332         PrintDebugString("[INFO]:   ##### icon width = %d", icons->iconInfo[i].width);
3333     }
3334     return FALSE;
3335 }
3336 
3337 // AccessibleActionMethods
3338 BOOL AccessBridgeJavaEntryPoints::getAccessibleActions(jobject accessibleContext,
3339                                                        AccessibleActions *actions) {
3340 
3341     jthrowable exception;
3342     const wchar_t *stringBytes;
3343     jsize length;
3344 
3345     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)",
3346                      accessibleContext, actions);
3347 
3348     if (getAccessibleActionsCountMethod == (jmethodID) 0 ||
3349         getAccessibleActionNameMethod == (jmethodID) 0) {
3350         PrintDebugString("[WARN]:   ##### missing method(s) !!!");
3351         return FALSE;
3352     }
3353 
3354 
3355     // get the icons count
3356     actions->actionsCount = jniEnv->CallIntMethod(accessBridgeObject,
3357                                                   getAccessibleActionsCountMethod,accessibleContext);
3358 
3359     EXCEPTION_CHECK("##### Getting actions count - call to CallIntMethod()", FALSE);
3360     PrintDebugString("[INFO]:   ##### key actions count = %d", actions->actionsCount);
3361 
3362 
3363     // get the actions
3364     for (int i = 0; i < actions->actionsCount && i < MAX_ACTION_INFO; i++) {
3365 
3366         // get the action name
3367         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3368                                                        getAccessibleActionNameMethod,
3369                                                        accessibleContext,
3370                                                        i);
3371 
3372         EXCEPTION_CHECK("Getting Action Name  - call to CallObjectMethod()", FALSE);
3373         if (js != (jstring) 0) {
3374             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3375             EXCEPTION_CHECK("Getting AccessibleAction Name  - call to GetStringChars()", FALSE);
3376             wcsncpy(actions->actionInfo[i].name , stringBytes, (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t)));
3377             length = jniEnv->GetStringLength(js);
3378             if (length >= (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t))) {
3379                 length = (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t)) - 2;
3380             }
3381             actions->actionInfo[i].name [length] = (wchar_t) 0;
3382             EXCEPTION_CHECK("Getting AccessibleAction name  - call to GetStringLength()", FALSE);
3383             jniEnv->ReleaseStringChars(js, stringBytes);
3384             EXCEPTION_CHECK("Getting AccessibleAction name  - call to ReleaseStringChars()", FALSE);
3385             // jniEnv->CallVoidMethod(accessBridgeObject,
3386             //                        decrementReferenceMethod, js);
3387             //EXCEPTION_CHECK("Getting AccessibleAction name  - call to CallVoidMethod()", FALSE);
3388             PrintDebugString("[INFO]: ##### AccessibleAction name  = %ls", actions->actionInfo[i].name  );
3389             jniEnv->DeleteLocalRef(js);
3390             EXCEPTION_CHECK("Getting AccessibleAction name  - call to DeleteLocalRef()", FALSE);
3391         } else {
3392             PrintDebugString("[WARN]:   AccessibleAction name  is null.");
3393             actions->actionInfo[i].name [0] = (wchar_t) 0;
3394         }
3395     }
3396     return FALSE;
3397 }
3398 
3399 BOOL AccessBridgeJavaEntryPoints::doAccessibleActions(jobject accessibleContext,
3400                                                       AccessibleActionsToDo *actionsToDo,
3401                                                       jint *failure) {
3402 
3403     jthrowable exception;
3404     BOOL returnVal;
3405 
3406     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::doAccessibleActions(%p, #actions %d %s):",
3407                      accessibleContext,
3408                      actionsToDo->actionsCount,
3409                      actionsToDo->actions[0].name);
3410 
3411     if (doAccessibleActionsMethod == (jmethodID) 0) {
3412         *failure = 0;
3413         return FALSE;
3414     }
3415 
3416     PrintDebugString("[INFO]:     doing %d actions ...", actionsToDo->actionsCount);
3417     for (int i = 0; i < actionsToDo->actionsCount && i < MAX_ACTIONS_TO_DO; i++) {
3418         PrintDebugString("[INFO]:     doing action %d: %s ...", i, actionsToDo->actions[i].name);
3419 
3420         // create a Java String for the action name
3421         wchar_t *actionName = (wchar_t *)actionsToDo->actions[i].name;
3422         jstring javaName = jniEnv->NewString(actionName, (jsize)wcslen(actionName));
3423         if (javaName == 0) {
3424             PrintDebugString("[ERROR]:     NewString failed");
3425             *failure = i;
3426             return FALSE;
3427         }
3428 
3429         returnVal = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, doAccessibleActionsMethod,
3430                                                     accessibleContext, javaName);
3431         jniEnv->DeleteLocalRef(javaName);
3432         EXCEPTION_CHECK("doAccessibleActions - call to CallBooleanMethod()", FALSE);
3433 
3434         if (returnVal != TRUE) {
3435             PrintDebugString("[ERROR]:     Action %d failed", i);
3436             *failure = i;
3437             return FALSE;
3438         }
3439     }
3440     *failure = -1;
3441     return TRUE;
3442 }
3443 
3444 
3445 /********** AccessibleText routines ***********************************/
3446 
3447 BOOL
3448 AccessBridgeJavaEntryPoints::getAccessibleTextInfo(jobject accessibleContext,
3449                                                    AccessibleTextInfo *textInfo,
3450                                                    jint x, jint y) {
3451     jthrowable exception;
3452 
3453     // Verify the Java VM still exists and AccessibleContext is
3454     // an instance of AccessibleText
3455     if (verifyAccessibleText(accessibleContext) == FALSE) {
3456         return FALSE;
3457     }
3458 
3459     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextInfo(%p, %d, %d):",
3460                      accessibleContext, x, y);
3461 
3462     // Get the character count
3463     if (getAccessibleCharCountFromContextMethod != (jmethodID) 0) {
3464         textInfo->charCount = jniEnv->CallIntMethod(accessBridgeObject,
3465                                                     getAccessibleCharCountFromContextMethod,
3466                                                     accessibleContext);
3467         EXCEPTION_CHECK("Getting AccessibleCharCount - call to CallIntMethod()", FALSE);
3468         PrintDebugString("[INFO]:   Char count = %d", textInfo->charCount);
3469     } else {
3470         PrintDebugString("[ERROR]: either env == 0 or getAccessibleCharCountFromContextMethod == 0");
3471         return FALSE;
3472     }
3473 
3474     // Get the index of the caret
3475     if (getAccessibleCaretPositionFromContextMethod != (jmethodID) 0) {
3476         textInfo->caretIndex = jniEnv->CallIntMethod(accessBridgeObject,
3477                                                      getAccessibleCaretPositionFromContextMethod,
3478                                                      accessibleContext);
3479         EXCEPTION_CHECK("Getting AccessibleCaretPosition - call to CallIntMethod()", FALSE);
3480         PrintDebugString("[INFO]:   Index at caret = %d", textInfo->caretIndex);
3481     } else {
3482         PrintDebugString("[ERROR]: either env == 0 or getAccessibleCaretPositionFromContextMethod == 0");
3483         return FALSE;
3484     }
3485 
3486     // Get the index at the given point
3487     if (getAccessibleIndexAtPointFromContextMethod != (jmethodID) 0) {
3488         // If x or y is -1 return -1
3489         if (x == -1 || y == -1) {
3490             textInfo->indexAtPoint = -1;
3491         } else {
3492             textInfo->indexAtPoint = jniEnv->CallIntMethod(accessBridgeObject,
3493                                                            getAccessibleIndexAtPointFromContextMethod,
3494                                                            accessibleContext, x, y);
3495             EXCEPTION_CHECK("Getting AccessibleIndexAtPoint - call to CallIntMethod()", FALSE);
3496         }
3497         PrintDebugString("[INFO]:   Index at point = %d", textInfo->indexAtPoint);
3498     } else {
3499         PrintDebugString("[ERROR]: either env == 0 or getAccessibleIndexAtPointFromContextMethod == 0");
3500         return FALSE;
3501     }
3502     return TRUE;
3503 }
3504 
3505 BOOL
3506 AccessBridgeJavaEntryPoints::getAccessibleTextItems(jobject accessibleContext,
3507                                                     AccessibleTextItemsInfo *textItems, jint index) {
3508     jstring js;
3509     const wchar_t *stringBytes;
3510     jthrowable exception;
3511     jsize length;
3512 
3513     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextItems(%p):", accessibleContext);
3514 
3515     // Verify the Java VM still exists and AccessibleContext is
3516     // an instance of AccessibleText
3517     if (verifyAccessibleText(accessibleContext) == FALSE) {
3518         return FALSE;
3519     }
3520 
3521     // Get the letter at index
3522     if (getAccessibleLetterAtIndexFromContextMethod != (jmethodID) 0) {
3523         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3524                                                 getAccessibleLetterAtIndexFromContextMethod,
3525                                                 accessibleContext, index);
3526         EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallIntMethod()", FALSE);
3527         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
3528         if (js != (jstring) 0) {
3529             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3530             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to GetStringChars()", FALSE);
3531             textItems->letter = stringBytes[0];
3532             jniEnv->ReleaseStringChars(js, stringBytes);
3533             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to ReleaseStringChars()", FALSE);
3534             jniEnv->CallVoidMethod(accessBridgeObject,
3535                                    decrementReferenceMethod, js);
3536             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallVoidMethod()", FALSE);
3537             PrintDebugString("[INFO]:   Accessible Text letter = %c", textItems->letter);
3538             jniEnv->DeleteLocalRef(js);
3539             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to DeleteLocalRef()", FALSE);
3540         } else {
3541             PrintDebugString("[WARN]:   Accessible Text letter is null.");
3542             textItems->letter = (wchar_t) 0;
3543         }
3544     } else {
3545         PrintDebugString("[ERROR]: either env == 0 or getAccessibleLetterAtIndexFromContextMethod == 0");
3546         return FALSE;
3547     }
3548 
3549 
3550     // Get the word at index
3551     if (getAccessibleWordAtIndexFromContextMethod != (jmethodID) 0) {
3552         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3553                                                 getAccessibleWordAtIndexFromContextMethod,
3554                                                 accessibleContext, index);
3555         EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallIntMethod()", FALSE);
3556         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
3557         if (js != (jstring) 0) {
3558             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3559             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringChars()", FALSE);
3560             wcsncpy(textItems->word, stringBytes, (sizeof(textItems->word) / sizeof(wchar_t)));
3561             length = jniEnv->GetStringLength(js);
3562             textItems->word[length < (sizeof(textItems->word) / sizeof(wchar_t)) ?
3563                             length : (sizeof(textItems->word) / sizeof(wchar_t))-2] = (wchar_t) 0;
3564             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringLength()", FALSE);
3565             jniEnv->ReleaseStringChars(js, stringBytes);
3566             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to ReleaseStringChars()", FALSE);
3567             jniEnv->CallVoidMethod(accessBridgeObject,
3568                                    decrementReferenceMethod, js);
3569             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallVoidMethod()", FALSE);
3570             wPrintDebugString(L"[INFO]:   Accessible Text word = %ls", textItems->word);
3571             jniEnv->DeleteLocalRef(js);
3572             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to DeleteLocalRef()", FALSE);
3573         } else {
3574             PrintDebugString("[WARN]:   Accessible Text word is null.");
3575             textItems->word[0] = (wchar_t) 0;
3576         }
3577     } else {
3578         PrintDebugString("[ERROR]: either env == 0 or getAccessibleWordAtIndexFromContextMethod == 0");
3579         return FALSE;
3580     }
3581 
3582     // Get the sentence at index
3583     if (getAccessibleSentenceAtIndexFromContextMethod != (jmethodID) 0) {
3584         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3585                                                 getAccessibleSentenceAtIndexFromContextMethod,
3586                                                 accessibleContext, index);
3587         EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallObjectMethod()", FALSE);
3588         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
3589         if (js != (jstring) 0) {
3590             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3591             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringChars()", FALSE);
3592             wcsncpy(textItems->sentence, stringBytes, (sizeof(textItems->sentence) / sizeof(wchar_t))-2);
3593             length = jniEnv->GetStringLength(js);
3594 
3595             if (length < sizeof(textItems->sentence) / sizeof(wchar_t)) {
3596                 textItems->sentence[length] = (wchar_t) 0;
3597             } else {
3598                 textItems->sentence[(sizeof(textItems->sentence) / sizeof(wchar_t))-2] = (wchar_t) 0;
3599             }
3600             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringLength()", FALSE);
3601             jniEnv->ReleaseStringChars(js, stringBytes);
3602             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to ReleaseStringChars()", FALSE);
3603             jniEnv->CallVoidMethod(accessBridgeObject,
3604                                    decrementReferenceMethod, js);
3605             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallVoidMethod()", FALSE);
3606             wPrintDebugString(L"[INFO]:   Accessible Text sentence = %ls", textItems->sentence);
3607             jniEnv->DeleteLocalRef(js);
3608             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to DeleteLocalRef()", FALSE);
3609         } else {
3610             PrintDebugString("[WARN]:   Accessible Text sentence is null.");
3611             textItems->sentence[0] = (wchar_t) 0;
3612         }
3613     } else {
3614         PrintDebugString("[ERROR]: either env == 0 or getAccessibleSentenceAtIndexFromContextMethod == 0");
3615         return FALSE;
3616     }
3617 
3618     return TRUE;
3619 }
3620 
3621 BOOL
3622 AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(jobject accessibleContext,
3623                                                             AccessibleTextSelectionInfo *selectionInfo) {
3624     jstring js;
3625     const wchar_t *stringBytes;
3626     jthrowable exception;
3627     jsize length;
3628 
3629     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(%p):",
3630                      accessibleContext);
3631 
3632     // Verify the Java VM still exists and AccessibleContext is
3633     // an instance of AccessibleText
3634     if (verifyAccessibleText(accessibleContext) == FALSE) {
3635         return FALSE;
3636     }
3637 
3638     // Get the selection start index
3639     if (getAccessibleTextSelectionStartFromContextMethod != (jmethodID) 0) {
3640         selectionInfo->selectionStartIndex = jniEnv->CallIntMethod(accessBridgeObject,
3641                                                                    getAccessibleTextSelectionStartFromContextMethod,
3642                                                                    accessibleContext);
3643         EXCEPTION_CHECK("Getting AccessibleTextSelectionStart - call to CallIntMethod()", FALSE);
3644         PrintDebugString("[INFO]:   Selection start = %d", selectionInfo->selectionStartIndex);
3645     } else {
3646         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextSelectionStartFromContextMethod == 0");
3647         return FALSE;
3648     }
3649 
3650     // Get the selection end index
3651     if (getAccessibleTextSelectionEndFromContextMethod != (jmethodID) 0) {
3652         selectionInfo->selectionEndIndex = jniEnv->CallIntMethod(accessBridgeObject,
3653                                                                  getAccessibleTextSelectionEndFromContextMethod,
3654                                                                  accessibleContext);
3655         EXCEPTION_CHECK("Getting AccessibleTextSelectionEnd - call to CallIntMethod()", FALSE);
3656         PrintDebugString("[INFO]:   Selection end = %d", selectionInfo->selectionEndIndex);
3657     } else {
3658         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextSelectionEndFromContextMethod == 0");
3659         return FALSE;
3660     }
3661 
3662     // Get the selected text
3663     if (getAccessibleTextSelectedTextFromContextMethod != (jmethodID) 0) {
3664         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3665                                                 getAccessibleTextSelectedTextFromContextMethod,
3666                                                 accessibleContext);
3667         EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallObjectMethod()", FALSE);
3668         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
3669         if (js != (jstring) 0) {
3670             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3671             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringChars()", FALSE);
3672             wcsncpy(selectionInfo->selectedText, stringBytes, (sizeof(selectionInfo->selectedText) / sizeof(wchar_t)));
3673             length = jniEnv->GetStringLength(js);
3674             selectionInfo->selectedText[length < (sizeof(selectionInfo->selectedText) / sizeof(wchar_t)) ?
3675                                         length : (sizeof(selectionInfo->selectedText) / sizeof(wchar_t))-2] = (wchar_t) 0;
3676             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringLength()", FALSE);
3677             jniEnv->ReleaseStringChars(js, stringBytes);
3678             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to ReleaseStringChars()", FALSE);
3679             jniEnv->CallVoidMethod(accessBridgeObject,
3680                                    decrementReferenceMethod, js);
3681             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallVoidMethod()", FALSE);
3682             PrintDebugString("[INFO]:   Accessible's selected text = %s", selectionInfo->selectedText);
3683             jniEnv->DeleteLocalRef(js);
3684             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to DeleteLocalRef()", FALSE);
3685         } else {
3686             PrintDebugString("[WARN]:   Accessible's selected text is null.");
3687             selectionInfo->selectedText[0] = (wchar_t) 0;
3688         }
3689     } else {
3690         PrintDebugString("[WARN]: either env == 0 or getAccessibleTextSelectedTextFromContextMethod == 0");
3691         return FALSE;
3692     }
3693     return TRUE;
3694 }
3695 
3696 BOOL
3697 AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleContext, jint index, AccessibleTextAttributesInfo *attributes) {
3698     jstring js;
3699     const wchar_t *stringBytes;
3700     jobject AttributeSet;
3701     jthrowable exception;
3702     jsize length;
3703 
3704     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(%p):", accessibleContext);
3705 
3706     // Verify the Java VM still exists and AccessibleContext is
3707     // an instance of AccessibleText
3708     if (verifyAccessibleText(accessibleContext) == FALSE) {
3709         return FALSE;
3710     }
3711 
3712     if (accessibleContext == (jobject) 0) {
3713         PrintDebugString("[WARN]:  passed in AccessibleContext == null! (oops)");
3714 
3715         attributes->bold = FALSE;
3716         attributes->italic = FALSE;
3717         attributes->underline = FALSE;
3718         attributes->strikethrough = FALSE;
3719         attributes->superscript = FALSE;
3720         attributes->subscript = FALSE;
3721         attributes->backgroundColor[0] = (wchar_t) 0;
3722         attributes->foregroundColor[0] = (wchar_t) 0;
3723         attributes->fontFamily[0] = (wchar_t) 0;
3724         attributes->fontSize = -1;
3725         attributes->alignment = -1;
3726         attributes->bidiLevel = -1;
3727         attributes->firstLineIndent = -1;
3728         attributes->leftIndent = -1;
3729         attributes->rightIndent = -1;
3730         attributes->lineSpacing = -1;
3731         attributes->spaceAbove = -1;
3732         attributes->spaceBelow = -1;
3733         attributes->fullAttributesString[0] = (wchar_t) 0;
3734 
3735         return (FALSE);
3736     }
3737 
3738     // Get the AttributeSet
3739     if (getAccessibleAttributeSetAtIndexFromContextMethod != (jmethodID) 0) {
3740         PrintDebugString("[INFO]:  Getting AttributeSet at index...");
3741         AttributeSet = jniEnv->CallObjectMethod(accessBridgeObject,
3742                                                 getAccessibleAttributeSetAtIndexFromContextMethod,
3743                                                 accessibleContext, index);
3744         EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to CallObjectMethod()", FALSE);
3745     } else {
3746         PrintDebugString("[ERROR]: either env == 0 or getAccessibleAttributeSetAtIndexFromContextMethod == 0");
3747         return FALSE;
3748     }
3749 
3750     // It is legal for the AttributeSet object to be null, in which case we return false!
3751     if (AttributeSet == (jobject) 0) {
3752         PrintDebugString("[WARN]:  AttributeSet returned at index is null (this is legal! - see AWT in J2SE 1.3");
3753 
3754         attributes->bold = FALSE;
3755         attributes->italic = FALSE;
3756         attributes->underline = FALSE;
3757         attributes->strikethrough = FALSE;
3758         attributes->superscript = FALSE;
3759         attributes->subscript = FALSE;
3760         attributes->backgroundColor[0] = (wchar_t) 0;
3761         attributes->foregroundColor[0] = (wchar_t) 0;
3762         attributes->fontFamily[0] = (wchar_t) 0;
3763         attributes->fontSize = -1;
3764         attributes->alignment = -1;
3765         attributes->bidiLevel = -1;
3766         attributes->firstLineIndent = -1;
3767         attributes->leftIndent = -1;
3768         attributes->rightIndent = -1;
3769         attributes->lineSpacing = -1;
3770         attributes->spaceAbove = -1;
3771         attributes->spaceBelow = -1;
3772         attributes->fullAttributesString[0] = (wchar_t) 0;
3773 
3774         return (FALSE);
3775     }
3776 
3777     // Get the bold setting
3778     if (getBoldFromAttributeSetMethod != (jmethodID) 0) {
3779         PrintDebugString("[INFO]:  Getting bold from AttributeSet...");
3780         attributes->bold = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3781                                                             getBoldFromAttributeSetMethod,
3782                                                             AttributeSet);
3783         EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallBooleanMethod()", FALSE);
3784     } else {
3785         PrintDebugString("[ERROR]: either env == 0 or getBoldFromAttributeSetMethod == 0");
3786         jniEnv->CallVoidMethod(accessBridgeObject,
3787                                decrementReferenceMethod, AttributeSet);
3788         EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallVoidMethod()", FALSE);
3789         jniEnv->DeleteLocalRef(AttributeSet);
3790         EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to DeleteLocalRef()", FALSE);
3791         return FALSE;
3792     }
3793 
3794     // Get the italic setting
3795     if (getItalicFromAttributeSetMethod != (jmethodID) 0) {
3796         PrintDebugString("[INFO]:  Getting italic from AttributeSet...");
3797         attributes->italic = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3798                                                               getItalicFromAttributeSetMethod,
3799                                                               AttributeSet);
3800         EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallBooleanMethod()", FALSE);
3801     } else {
3802         PrintDebugString("[ERROR]: either env == 0 or getItalicdFromAttributeSetMethod == 0");
3803         jniEnv->CallVoidMethod(accessBridgeObject,
3804                                decrementReferenceMethod, AttributeSet);
3805         EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallVoidMethod()", FALSE);
3806         jniEnv->DeleteLocalRef(AttributeSet);
3807         EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to DeleteLocalRef()", FALSE);
3808         return FALSE;
3809     }
3810 
3811     // Get the underline setting
3812     if (getUnderlineFromAttributeSetMethod != (jmethodID) 0) {
3813         PrintDebugString("[INFO]:  Getting underline from AttributeSet...");
3814         attributes->underline = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3815                                                                  getUnderlineFromAttributeSetMethod,
3816                                                                  AttributeSet);
3817         EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallBooleanMethod()", FALSE);
3818     } else {
3819         PrintDebugString("[ERROR]:  either env == 0 or getUnderlineFromAttributeSetMethod == 0");
3820         jniEnv->CallVoidMethod(accessBridgeObject,
3821                                decrementReferenceMethod, AttributeSet);
3822         EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallVoidMethod()", FALSE);
3823         jniEnv->DeleteLocalRef(AttributeSet);
3824         EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to DeleteLocalRef()", FALSE);
3825         return FALSE;
3826     }
3827 
3828     // Get the strikethrough setting
3829     if (getStrikethroughFromAttributeSetMethod != (jmethodID) 0) {
3830         PrintDebugString("[INFO]:  Getting strikethrough from AttributeSet...");
3831         attributes->strikethrough = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3832                                                                      getStrikethroughFromAttributeSetMethod,
3833                                                                      AttributeSet);
3834         EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallBooleanMethod()", FALSE);
3835     } else {
3836         PrintDebugString("[ERROR]: either env == 0 or getStrikethroughFromAttributeSetMethod == 0");
3837         jniEnv->CallVoidMethod(accessBridgeObject,
3838                                decrementReferenceMethod, AttributeSet);
3839         EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallVoidMethod()", FALSE);
3840         jniEnv->DeleteLocalRef(AttributeSet);
3841         EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to DeleteLocalRef()", FALSE);
3842         return FALSE;
3843     }
3844 
3845     // Get the superscript setting
3846     if (getSuperscriptFromAttributeSetMethod != (jmethodID) 0) {
3847         PrintDebugString("[INFO]:  Getting superscript from AttributeSet...");
3848         attributes->superscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3849                                                                    getSuperscriptFromAttributeSetMethod,
3850                                                                    AttributeSet);
3851         EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallBooleanMethod()", FALSE);
3852     } else {
3853         PrintDebugString("[ERROR]: either env == 0 or getSuperscripteFromAttributeSetMethod == 0");
3854         jniEnv->CallVoidMethod(accessBridgeObject,
3855                                decrementReferenceMethod, AttributeSet);
3856         EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallVoidMethod()", FALSE);
3857         jniEnv->DeleteLocalRef(AttributeSet);
3858         EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to DeleteLocalRef()", FALSE);
3859         return FALSE;
3860     }
3861 
3862     // Get the subscript setting
3863     if (getSubscriptFromAttributeSetMethod != (jmethodID) 0) {
3864         PrintDebugString("[INFO]:  Getting subscript from AttributeSet...");
3865         attributes->subscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3866                                                                  getSubscriptFromAttributeSetMethod,
3867                                                                  AttributeSet);
3868         EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallBooleanMethod()", FALSE);
3869     } else {
3870         PrintDebugString("[ERROR]: either env == 0 or getSubscriptFromAttributeSetMethod == 0");
3871         jniEnv->CallVoidMethod(accessBridgeObject,
3872                                decrementReferenceMethod, AttributeSet);
3873         EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallVoidMethod()", FALSE);
3874         jniEnv->DeleteLocalRef(AttributeSet);
3875         EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to DeleteLocalRef()", FALSE);
3876         return FALSE;
3877     }
3878 
3879     // Get the backgroundColor setting
3880     if (getBackgroundColorFromAttributeSetMethod != (jmethodID) 0) {
3881         PrintDebugString("[INFO]:  Getting backgroundColor from AttributeSet...");
3882         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3883                                                 getBackgroundColorFromAttributeSetMethod,
3884                                                 AttributeSet);
3885         EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallObjectMethod()", FALSE);
3886         if (js != (jstring) 0) {
3887             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3888             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringChars()", FALSE);
3889             wcsncpy(attributes->backgroundColor, stringBytes, (sizeof(attributes->backgroundColor) / sizeof(wchar_t)));
3890             length = jniEnv->GetStringLength(js);
3891             attributes->backgroundColor[length < (sizeof(attributes->backgroundColor) / sizeof(wchar_t)) ?
3892                                         length : (sizeof(attributes->backgroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0;
3893             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringLength()", FALSE);
3894             jniEnv->ReleaseStringChars(js, stringBytes);
3895             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE);
3896             jniEnv->CallVoidMethod(accessBridgeObject,
3897                                    decrementReferenceMethod, js);
3898             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3899             wPrintDebugString(L"[INFO]:   AttributeSet's background color = %ls", attributes->backgroundColor);
3900             jniEnv->DeleteLocalRef(js);
3901             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3902         } else {
3903             PrintDebugString("[WARN]:   AttributeSet's background color is null.");
3904             attributes->backgroundColor[0] = (wchar_t) 0;
3905         }
3906     } else {
3907         PrintDebugString("[ERROR]: either env == 0 or getBackgroundColorFromAttributeSetMethod == 0");
3908         jniEnv->CallVoidMethod(accessBridgeObject,
3909                                decrementReferenceMethod, AttributeSet);
3910         EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3911         jniEnv->DeleteLocalRef(AttributeSet);
3912         EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3913         return FALSE;
3914     }
3915 
3916     // Get the foregroundColor setting
3917     if (getForegroundColorFromAttributeSetMethod != (jmethodID) 0) {
3918         PrintDebugString("[INFO]:  Getting foregroundColor from AttributeSet...");
3919         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3920                                                 getForegroundColorFromAttributeSetMethod,
3921                                                 AttributeSet);
3922         EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallObjectMethod()", FALSE);
3923         if (js != (jstring) 0) {
3924             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3925             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringChars()", FALSE);
3926             wcsncpy(attributes->foregroundColor, stringBytes, (sizeof(attributes->foregroundColor) / sizeof(wchar_t)));
3927             length = jniEnv->GetStringLength(js);
3928             attributes->foregroundColor[length < (sizeof(attributes->foregroundColor) / sizeof(wchar_t)) ?
3929                                         length : (sizeof(attributes->foregroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0;
3930             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringLength()", FALSE);
3931             jniEnv->ReleaseStringChars(js, stringBytes);
3932             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE);
3933             jniEnv->CallVoidMethod(accessBridgeObject,
3934                                    decrementReferenceMethod, js);
3935             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3936             wPrintDebugString(L"[INFO]:   AttributeSet's foreground color = %ls", attributes->foregroundColor);
3937             jniEnv->DeleteLocalRef(js);
3938             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3939         } else {
3940             PrintDebugString("[WARN]:   AttributeSet's foreground color is null.");
3941             attributes->foregroundColor[0] = (wchar_t) 0;
3942         }
3943     } else {
3944         PrintDebugString("[ERROR]: either env == 0 or getForegroundColorFromAttributeSetMethod == 0");
3945         jniEnv->CallVoidMethod(accessBridgeObject,
3946                                decrementReferenceMethod, AttributeSet);
3947         EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3948         jniEnv->DeleteLocalRef(AttributeSet);
3949         EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3950         return FALSE;
3951     }
3952 
3953     // Get the fontFamily setting
3954     if (getFontFamilyFromAttributeSetMethod != (jmethodID) 0) {
3955         PrintDebugString("[INFO]:  Getting fontFamily from AttributeSet...");
3956         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3957                                                 getFontFamilyFromAttributeSetMethod,
3958                                                 AttributeSet);
3959         EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallObjectMethod()", FALSE);
3960         if (js != (jstring) 0) {
3961             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3962             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringChars()", FALSE);
3963             wcsncpy(attributes->fontFamily, stringBytes, (sizeof(attributes->fontFamily) / sizeof(wchar_t)));
3964             length = jniEnv->GetStringLength(js);
3965             attributes->fontFamily[length < (sizeof(attributes->fontFamily) / sizeof(wchar_t)) ?
3966                                    length : (sizeof(attributes->fontFamily) / sizeof(wchar_t))-2] = (wchar_t) 0;
3967             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringLength()", FALSE);
3968             jniEnv->ReleaseStringChars(js, stringBytes);
3969             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to ReleaseStringChars()", FALSE);
3970             jniEnv->CallVoidMethod(accessBridgeObject,
3971                                    decrementReferenceMethod, js);
3972             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE);
3973             wPrintDebugString(L"[INFO]:   AttributeSet's fontFamily = %ls", attributes->fontFamily);
3974             jniEnv->DeleteLocalRef(js);
3975             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE);
3976         } else {
3977             PrintDebugString("[WARN]:   AttributeSet's fontFamily is null.");
3978             attributes->backgroundColor[0] = (wchar_t) 0;
3979         }
3980     } else {
3981         PrintDebugString("[ERROR]: either env == 0 or getFontFamilyFromAttributeSetMethod == 0");
3982         jniEnv->CallVoidMethod(accessBridgeObject,
3983                                decrementReferenceMethod, AttributeSet);
3984         EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE);
3985         jniEnv->DeleteLocalRef(AttributeSet);
3986         EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE);
3987         return FALSE;
3988     }
3989 
3990     // Get the font size
3991     if (getFontSizeFromAttributeSetMethod != (jmethodID) 0) {
3992         PrintDebugString("[INFO]:  Getting font size from AttributeSet...");
3993         attributes->fontSize = jniEnv->CallIntMethod(accessBridgeObject,
3994                                                      getFontSizeFromAttributeSetMethod,
3995                                                      AttributeSet);
3996         EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallIntMethod()", FALSE);
3997         PrintDebugString("[INFO]:   AttributeSet's font size = %d", attributes->fontSize);
3998     } else {
3999         PrintDebugString("[ERROR]: either env == 0 or getAlignmentFromAttributeSetMethod == 0");
4000         jniEnv->CallVoidMethod(accessBridgeObject,
4001                                decrementReferenceMethod, AttributeSet);
4002         EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallVoidMethod()", FALSE);
4003         jniEnv->DeleteLocalRef(AttributeSet);
4004         EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to DeleteLocalRef()", FALSE);
4005         return FALSE;
4006     }
4007 
4008 
4009     // Get the alignment setting
4010     if (getAlignmentFromAttributeSetMethod != (jmethodID) 0) {
4011         PrintDebugString(" Getting alignment from AttributeSet...");
4012         attributes->alignment = jniEnv->CallIntMethod(accessBridgeObject,
4013                                                       getAlignmentFromAttributeSetMethod,
4014                                                       AttributeSet);
4015         EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallIntMethod()", FALSE);
4016     } else {
4017         PrintDebugString("[ERROR]: either env == 0 or getAlignmentFromAttributeSetMethod == 0");
4018         jniEnv->CallVoidMethod(accessBridgeObject,
4019                                decrementReferenceMethod, AttributeSet);
4020         EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallVoidMethod()", FALSE);
4021         jniEnv->DeleteLocalRef(AttributeSet);
4022         EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4023         return FALSE;
4024     }
4025 
4026     // Get the bidiLevel setting
4027     if (getBidiLevelFromAttributeSetMethod != (jmethodID) 0) {
4028         PrintDebugString("[INFO]:  Getting bidiLevel from AttributeSet...");
4029         attributes->bidiLevel = jniEnv->CallIntMethod(accessBridgeObject,
4030                                                       getBidiLevelFromAttributeSetMethod,
4031                                                       AttributeSet);
4032         EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallIntMethod()", FALSE);
4033     } else {
4034         PrintDebugString("[ERROR]: either env == 0 or getBidiLevelFromAttributeSetMethod == 0");
4035         jniEnv->CallVoidMethod(accessBridgeObject,
4036                                decrementReferenceMethod, AttributeSet);
4037         EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallVoidMethod()", FALSE);
4038         jniEnv->DeleteLocalRef(AttributeSet);
4039         EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to DeleteLocalRef()", FALSE);
4040         return FALSE;
4041     }
4042 
4043     // Get the firstLineIndent setting
4044     if (getFirstLineIndentFromAttributeSetMethod != (jmethodID) 0) {
4045         PrintDebugString("[ERROR]:  Getting firstLineIndent from AttributeSet...");
4046         attributes->firstLineIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4047                                                                        getFirstLineIndentFromAttributeSetMethod,
4048                                                                        AttributeSet);
4049         EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallIntMethod()", FALSE);
4050     } else {
4051         PrintDebugString("[ERROR]: either env == 0 or getFirstLineIndentFromAttributeSetMethod == 0");
4052         jniEnv->CallVoidMethod(accessBridgeObject,
4053                                decrementReferenceMethod, AttributeSet);
4054         EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
4055         jniEnv->DeleteLocalRef(AttributeSet);
4056         EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4057         return FALSE;
4058     }
4059 
4060     // Get the leftIndent setting
4061     if (getLeftIndentFromAttributeSetMethod != (jmethodID) 0) {
4062         PrintDebugString("[INFO]:  Getting leftIndent from AttributeSet...");
4063         attributes->leftIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4064                                                                   getLeftIndentFromAttributeSetMethod,
4065                                                                   AttributeSet);
4066         EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallIntMethod()", FALSE);
4067     } else {
4068         PrintDebugString("[ERROR]: either env == 0 or getLeftIndentFromAttributeSetMethod == 0");
4069         jniEnv->CallVoidMethod(accessBridgeObject,
4070                                decrementReferenceMethod, AttributeSet);
4071         EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
4072         jniEnv->DeleteLocalRef(AttributeSet);
4073         EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4074         return FALSE;
4075     }
4076 
4077     // Get the rightIndent setting
4078     if (getRightIndentFromAttributeSetMethod != (jmethodID) 0) {
4079         PrintDebugString("[INFO]:  Getting rightIndent from AttributeSet...");
4080         attributes->rightIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4081                                                                    getRightIndentFromAttributeSetMethod,
4082                                                                    AttributeSet);
4083         EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallIntMethod()", FALSE);
4084     } else {
4085         PrintDebugString("[ERROR]: either env == 0 or getRightIndentFromAttributeSetMethod == 0");
4086         jniEnv->CallVoidMethod(accessBridgeObject,
4087                                decrementReferenceMethod, AttributeSet);
4088         EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
4089         jniEnv->DeleteLocalRef(AttributeSet);
4090         EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4091         return FALSE;
4092     }
4093 
4094     // Get the lineSpacing setting
4095     if (getLineSpacingFromAttributeSetMethod != (jmethodID) 0) {
4096         PrintDebugString("[INFO]:  Getting lineSpacing from AttributeSet...");
4097         attributes->lineSpacing = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4098                                                                    getLineSpacingFromAttributeSetMethod,
4099                                                                    AttributeSet);
4100         EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallIntMethod()", FALSE);
4101     } else {
4102         PrintDebugString("[ERROR]:  either env == 0 or getLineSpacingFromAttributeSetMethod == 0");
4103         jniEnv->CallVoidMethod(accessBridgeObject,
4104                                decrementReferenceMethod, AttributeSet);
4105         EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallVoidMethod()", FALSE);
4106         jniEnv->DeleteLocalRef(AttributeSet);
4107         EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to DeleteLocalRef()", FALSE);
4108         return FALSE;
4109     }
4110 
4111     // Get the spaceAbove setting
4112     if (getSpaceAboveFromAttributeSetMethod != (jmethodID) 0) {
4113         PrintDebugString("[INFO]:  Getting spaceAbove from AttributeSet...");
4114         attributes->spaceAbove = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4115                                                                   getSpaceAboveFromAttributeSetMethod,
4116                                                                   AttributeSet);
4117         EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallIntMethod()", FALSE);
4118     } else {
4119         PrintDebugString("[ERROR]:  either env == 0 or getSpaceAboveFromAttributeSetMethod == 0");
4120         jniEnv->CallVoidMethod(accessBridgeObject,
4121                                decrementReferenceMethod, AttributeSet);
4122         EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallVoidMethod()", FALSE);
4123         jniEnv->DeleteLocalRef(AttributeSet);
4124         EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to DeleteLocalRef()", FALSE);
4125         return FALSE;
4126     }
4127 
4128     // Get the spaceBelow setting
4129     if (getSpaceBelowFromAttributeSetMethod != (jmethodID) 0) {
4130         PrintDebugString("[INFO]:  Getting spaceBelow from AttributeSet...");
4131         attributes->spaceBelow = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4132                                                                   getSpaceBelowFromAttributeSetMethod,
4133                                                                   AttributeSet);
4134         EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallIntMethod()", FALSE);
4135     } else {
4136         PrintDebugString("[ERROR]:  either env == 0 or getSpaceBelowFromAttributeSetMethod == 0");
4137         jniEnv->CallVoidMethod(accessBridgeObject,
4138                                decrementReferenceMethod, AttributeSet);
4139         EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallVoidMethod()", FALSE);
4140         jniEnv->DeleteLocalRef(AttributeSet);
4141         EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to DeleteLocalRef()", FALSE);
4142         return FALSE;
4143     }
4144 
4145     // Release the AttributeSet object
4146     if (decrementReferenceMethod != (jmethodID) 0) {
4147         PrintDebugString("[INFO]:  Decrementing reference to AttributeSet...");
4148         jniEnv->CallVoidMethod(accessBridgeObject,
4149                                decrementReferenceMethod, AttributeSet);
4150         EXCEPTION_CHECK("Releasing AttributeSet object - call to CallVoidMethod()", FALSE);
4151     } else {
4152         PrintDebugString("[ERROR]:  either env == 0 or accessBridgeObject == 0");
4153         jniEnv->DeleteLocalRef(AttributeSet);
4154         EXCEPTION_CHECK("Releasing AttributeSet object - call to DeleteLocalRef()", FALSE);
4155         return FALSE;
4156     }
4157 
4158     // Get the full attributes string at index
4159     if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) {
4160         PrintDebugString("[INFO]:  Getting full attributes string from Context...");
4161         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4162                                                 getAccessibleAttributesAtIndexFromContextMethod,
4163                                                 accessibleContext, index);
4164         EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE);
4165         PrintDebugString("[INFO]:  returned from CallObjectMethod(), js = %p", js);
4166         if (js != (jstring) 0) {
4167             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4168             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE);
4169             wcsncpy(attributes->fullAttributesString, stringBytes, (sizeof(attributes->fullAttributesString) / sizeof(wchar_t)));
4170             length = jniEnv->GetStringLength(js);
4171             attributes->fullAttributesString[length < (sizeof(attributes->fullAttributesString) / sizeof(wchar_t)) ?
4172                                              length : (sizeof(attributes->fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0;
4173             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE);
4174             jniEnv->ReleaseStringChars(js, stringBytes);
4175             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE);
4176             jniEnv->CallVoidMethod(accessBridgeObject,
4177                                    decrementReferenceMethod, js);
4178             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE);
4179             wPrintDebugString(L"[INFO]:   Accessible Text attributes = %ls", attributes->fullAttributesString);
4180             jniEnv->DeleteLocalRef(js);
4181             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
4182         } else {
4183             PrintDebugString("[WARN]:   Accessible Text attributes is null.");
4184             attributes->fullAttributesString[0] = (wchar_t) 0;
4185             jniEnv->DeleteLocalRef(AttributeSet);
4186             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
4187             return FALSE;
4188         }
4189     } else {
4190         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0");
4191         jniEnv->DeleteLocalRef(AttributeSet);
4192         return FALSE;
4193     }
4194 
4195     jniEnv->DeleteLocalRef(AttributeSet);
4196     EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to DeleteLocalRef()", FALSE);
4197     return TRUE;
4198 }
4199 
4200 BOOL
4201 AccessBridgeJavaEntryPoints::getAccessibleTextRect(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) {
4202 
4203     jthrowable exception;
4204 
4205     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextRect(%p), index = %d",
4206                      accessibleContext, index);
4207 
4208     // Verify the Java VM still exists and AccessibleContext is
4209     // an instance of AccessibleText
4210     if (verifyAccessibleText(accessibleContext) == FALSE) {
4211         return FALSE;
4212     }
4213 
4214     // Get the x coord
4215     if (getAccessibleXcoordTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4216         rectInfo->x = jniEnv->CallIntMethod(accessBridgeObject,
4217                                             getAccessibleXcoordTextRectAtIndexFromContextMethod,
4218                                             accessibleContext, index);
4219         EXCEPTION_CHECK("Getting AccessibleXcoordTextRect - call to CallIntMethod()", FALSE);
4220         PrintDebugString("[INFO]:  X coord = %d", rectInfo->x);
4221     } else {
4222         PrintDebugString("[ERROR]: either env == 0 or getAccessibleXcoordTextRectAtIndexFromContextMethod == 0");
4223         return FALSE;
4224     }
4225 
4226     // Get the y coord
4227     if (getAccessibleYcoordTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4228         rectInfo->y = jniEnv->CallIntMethod(accessBridgeObject,
4229                                             getAccessibleYcoordTextRectAtIndexFromContextMethod,
4230                                             accessibleContext, index);
4231         EXCEPTION_CHECK("Getting AccessibleYcoordTextRect - call to CallIntMethod()", FALSE);
4232         PrintDebugString("[INFO]:   Y coord = %d", rectInfo->y);
4233     } else {
4234         PrintDebugString("[INFO]:  either env == 0 or getAccessibleYcoordTextRectAtIndexFromContextMethod == 0");
4235         return FALSE;
4236     }
4237 
4238     // Get the width
4239     if (getAccessibleWidthTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4240         rectInfo->width = jniEnv->CallIntMethod(accessBridgeObject,
4241                                                 getAccessibleWidthTextRectAtIndexFromContextMethod,
4242                                                 accessibleContext, index);
4243         EXCEPTION_CHECK("Getting AccessibleWidthTextRect - call to CallIntMethod()", FALSE);
4244         PrintDebugString("[INFO]: Width = %d", rectInfo->width);
4245     } else {
4246         PrintDebugString("[INFO]: either env == 0 or getAccessibleWidthTextRectAtIndexFromContextMethod == 0");
4247         return FALSE;
4248     }
4249 
4250     // Get the height
4251     if (getAccessibleHeightTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4252         rectInfo->height = jniEnv->CallIntMethod(accessBridgeObject,
4253                                                  getAccessibleHeightTextRectAtIndexFromContextMethod,
4254                                                  accessibleContext, index);
4255         EXCEPTION_CHECK("Getting AccessibleHeightTextRect - call to CallIntMethod()", FALSE);
4256         PrintDebugString("[INFO]: Height = %d", rectInfo->height);
4257     } else {
4258         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleHeightTextRectAtIndexFromContextMethod == 0");
4259         return FALSE;
4260     }
4261 
4262     return TRUE;
4263 }
4264 
4265 // =====
4266 
4267 /**
4268  * gets the bounding rectangle for the text caret
4269  */
4270 BOOL
4271 AccessBridgeJavaEntryPoints::getCaretLocation(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) {
4272 
4273     jthrowable exception;
4274 
4275     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getCaretLocation(%p), index = %d",
4276                      accessibleContext, index);
4277 
4278     // Verify the Java VM still exists and AccessibleContext is
4279     // an instance of AccessibleText
4280     if (verifyAccessibleText(accessibleContext) == FALSE) {
4281         return FALSE;
4282     }
4283 
4284     // Get the x coord
4285     if (getCaretLocationXMethod != (jmethodID) 0) {
4286         rectInfo->x = jniEnv->CallIntMethod(accessBridgeObject,
4287                                             getCaretLocationXMethod,
4288                                             accessibleContext, index);
4289         EXCEPTION_CHECK("Getting caret X coordinate - call to CallIntMethod()", FALSE);
4290         PrintDebugString("[INFO]:   X coord = %d", rectInfo->x);
4291     } else {
4292         PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationXMethod == 0");
4293         return FALSE;
4294     }
4295 
4296     // Get the y coord
4297     if (getCaretLocationYMethod != (jmethodID) 0) {
4298         rectInfo->y = jniEnv->CallIntMethod(accessBridgeObject,
4299                                             getCaretLocationYMethod,
4300                                             accessibleContext, index);
4301         EXCEPTION_CHECK("Getting caret Y coordinate - call to CallIntMethod()", FALSE);
4302         PrintDebugString("[INFO]:   Y coord = %d", rectInfo->y);
4303     } else {
4304         PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationYMethod == 0");
4305         return FALSE;
4306     }
4307 
4308     // Get the width
4309     if (getCaretLocationWidthMethod != (jmethodID) 0) {
4310         rectInfo->width = jniEnv->CallIntMethod(accessBridgeObject,
4311                                                 getCaretLocationWidthMethod,
4312                                                 accessibleContext, index);
4313         EXCEPTION_CHECK("Getting caret width - call to CallIntMethod()", FALSE);
4314         PrintDebugString("[INFO]:   Width = %d", rectInfo->width);
4315     } else {
4316         PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationWidthMethod == 0");
4317         return FALSE;
4318     }
4319 
4320     // Get the height
4321     if (getCaretLocationHeightMethod != (jmethodID) 0) {
4322         rectInfo->height = jniEnv->CallIntMethod(accessBridgeObject,
4323                                                  getCaretLocationHeightMethod,
4324                                                  accessibleContext, index);
4325         EXCEPTION_CHECK("Getting caret height - call to CallIntMethod()", FALSE);
4326         PrintDebugString("[INFO]:   Height = %d", rectInfo->height);
4327     } else {
4328         PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationHeightMethod == 0");
4329         return FALSE;
4330     }
4331 
4332     return TRUE;
4333 }
4334 
4335 // =====
4336 
4337 BOOL
4338 AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(jobject accessibleContext, jint index, jint *startIndex, jint *endIndex) {
4339 
4340     jthrowable exception;
4341 
4342     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(%p):", accessibleContext);
4343 
4344     // Verify the Java VM still exists and AccessibleContext is
4345     // an instance of AccessibleText
4346     if (verifyAccessibleText(accessibleContext) == FALSE) {
4347         return FALSE;
4348     }
4349 
4350     // Get the index of the left boundary of the line containing 'index'
4351     if (getAccessibleTextLineLeftBoundsFromContextMethod != (jmethodID) 0) {
4352         *startIndex = jniEnv->CallIntMethod(accessBridgeObject,
4353                                             getAccessibleTextLineLeftBoundsFromContextMethod,
4354                                             accessibleContext, index);
4355         EXCEPTION_CHECK("Getting AccessibleTextLineLeftBounds - call to CallIntMethod()", FALSE);
4356         PrintDebugString("[INFO]:   startIndex = %d", *startIndex);
4357     } else {
4358         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextLineLeftBoundsFromContextMethod == 0");
4359         return FALSE;
4360     }
4361 
4362     // Get the index of the right boundary of the line containing 'index'
4363     if (getAccessibleTextLineRightBoundsFromContextMethod != (jmethodID) 0) {
4364         *endIndex = jniEnv->CallIntMethod(accessBridgeObject,
4365                                           getAccessibleTextLineRightBoundsFromContextMethod,
4366                                           accessibleContext, index);
4367         EXCEPTION_CHECK("Getting AccessibleTextLineRightBounds - call to CallIntMethod()", FALSE);
4368         PrintDebugString("[INFO]:   endIndex = %d", *endIndex);
4369     } else {
4370         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextLineRightBoundsFromContextMethod == 0");
4371         return FALSE;
4372     }
4373 
4374     return TRUE;
4375 }
4376 
4377 BOOL
4378 AccessBridgeJavaEntryPoints::getAccessibleTextRange(jobject accessibleContext,
4379                                                     jint start, jint end, wchar_t *text, short len) {
4380     jstring js;
4381     const wchar_t *stringBytes;
4382     jthrowable exception;
4383     jsize length;
4384 
4385     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextRange(%p, %d, %d, *text, %d):", accessibleContext, start, end, len);
4386 
4387     // Verify the Java VM still exists and AccessibleContext is
4388     // an instance of AccessibleText
4389     if (verifyAccessibleText(accessibleContext) == FALSE) {
4390         return FALSE;
4391     }
4392 
4393     // range is inclusive
4394     if (end < start) {
4395         PrintDebugString("[ERROR]:  end < start!");
4396         text[0] = (wchar_t) 0;
4397         return FALSE;
4398     }
4399 
4400     // Get the text range within [start, end] inclusive
4401     if (getAccessibleTextRangeFromContextMethod != (jmethodID) 0) {
4402         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4403                                                 getAccessibleTextRangeFromContextMethod,
4404                                                 accessibleContext, start, end);
4405         EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallObjectMethod()", FALSE);
4406         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
4407         if (js != (jstring) 0) {
4408             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4409             EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringChars()", FALSE);
4410             wPrintDebugString(L"[INFO]:   Accessible Text stringBytes returned from Java = %ls", stringBytes);
4411             wcsncpy(text, stringBytes, len);
4412             length = jniEnv->GetStringLength(js);
4413             PrintDebugString("[INFO]:  Accessible Text stringBytes length = %d", length);
4414             text[length < len ? length : len - 2] = (wchar_t) 0;
4415             wPrintDebugString(L"[INFO]:   Accessible Text 'text' after null termination = %ls", text);
4416             EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringLength()", FALSE);
4417             jniEnv->ReleaseStringChars(js, stringBytes);
4418             EXCEPTION_CHECK("Getting AccessibleTextRange - call to ReleaseStringChars()", FALSE);
4419             jniEnv->CallVoidMethod(accessBridgeObject,
4420                                    decrementReferenceMethod, js);
4421             EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallVoidMethod()", FALSE);
4422             wPrintDebugString(L"[INFO]:   Accessible Text range = %ls", text);
4423             jniEnv->DeleteLocalRef(js);
4424             EXCEPTION_CHECK("Getting AccessibleTextRange - call to DeleteLocalRef()", FALSE);
4425         } else {
4426             PrintDebugString("[WARN]:   current Accessible Text range is null.");
4427             text[0] = (wchar_t) 0;
4428             return FALSE;
4429         }
4430     } else {
4431         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextRangeFromContextMethod == 0");
4432         return FALSE;
4433     }
4434     return TRUE;
4435 }
4436 
4437 /********** AccessibleValue routines ***************/
4438 
4439 BOOL
4440 AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) {
4441     jstring js;
4442     const wchar_t *stringBytes;
4443     jthrowable exception;
4444     jsize length;
4445 
4446     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(%p):", accessibleContext);
4447 
4448     // Get the current Accessible Value
4449     if (getCurrentAccessibleValueFromContextMethod != (jmethodID) 0) {
4450         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4451                                                 getCurrentAccessibleValueFromContextMethod,
4452                                                 accessibleContext);
4453         EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallObjectMethod()", FALSE);
4454         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
4455         if (js != (jstring) 0) {
4456             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4457             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringChars()", FALSE);
4458             wcsncpy(value, stringBytes, len);
4459             length = jniEnv->GetStringLength(js);
4460             value[length < len ? length : len - 2] = (wchar_t) 0;
4461             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringLength()", FALSE);
4462             jniEnv->ReleaseStringChars(js, stringBytes);
4463             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to ReleaseStringChars()", FALSE);
4464             jniEnv->CallVoidMethod(accessBridgeObject,
4465                                    decrementReferenceMethod, js);
4466             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallVoidMethod()", FALSE);
4467             PrintDebugString("[INFO]:   current Accessible Value = %s", value);
4468             jniEnv->DeleteLocalRef(js);
4469             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to DeleteLocalRef()", FALSE);
4470         } else {
4471             PrintDebugString("[WARN]:   current Accessible Value is null.");
4472             value[0] = (wchar_t) 0;
4473             return FALSE;
4474         }
4475     } else {
4476         PrintDebugString("[ERROR]:  either env == 0 or getCurrentAccessibleValueFromContextMethod == 0");
4477         return FALSE;
4478     }
4479     return TRUE;
4480 }
4481 
4482 BOOL
4483 AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) {
4484     jstring js;
4485     const wchar_t *stringBytes;
4486     jthrowable exception;
4487     jsize length;
4488 
4489     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(%p):", accessibleContext);
4490 
4491     // Get the maximum Accessible Value
4492     if (getMaximumAccessibleValueFromContextMethod != (jmethodID) 0) {
4493         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4494                                                 getMaximumAccessibleValueFromContextMethod,
4495                                                 accessibleContext);
4496         EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallObjectMethod()", FALSE);
4497         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
4498         if (js != (jstring) 0) {
4499             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4500             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringChars()", FALSE);
4501             wcsncpy(value, stringBytes, len);
4502             length = jniEnv->GetStringLength(js);
4503             value[length < len ? length : len - 2] = (wchar_t) 0;
4504             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringLength()", FALSE);
4505             jniEnv->ReleaseStringChars(js, stringBytes);
4506             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to ReleaseStringChars()", FALSE);
4507             jniEnv->CallVoidMethod(accessBridgeObject,
4508                                    decrementReferenceMethod, js);
4509             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallVoidMethod()", FALSE);
4510             PrintDebugString("[INFO]:   maximum Accessible Value = %s", value);
4511             jniEnv->DeleteLocalRef(js);
4512             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to DeleteLocalRef()", FALSE);
4513         } else {
4514             PrintDebugString("[WARN]:   maximum Accessible Value is null.");
4515             value[0] = (wchar_t) 0;
4516             return FALSE;
4517         }
4518     } else {
4519         PrintDebugString("[ERROR]: either env == 0 or getMaximumAccessibleValueFromContextMethod == 0");
4520         return FALSE;
4521     }
4522     return TRUE;
4523 }
4524 
4525 BOOL
4526 AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) {
4527     jstring js;
4528     const wchar_t *stringBytes;
4529     jthrowable exception;
4530     jsize length;
4531 
4532     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(%p):", accessibleContext);
4533 
4534     // Get the mimimum Accessible Value
4535     if (getMinimumAccessibleValueFromContextMethod != (jmethodID) 0) {
4536         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4537                                                 getMinimumAccessibleValueFromContextMethod,
4538                                                 accessibleContext);
4539         EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallObjectMethod()", FALSE);
4540         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
4541         if (js != (jstring) 0) {
4542             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4543             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringChars()", FALSE);
4544             wcsncpy(value, stringBytes, len);
4545             length = jniEnv->GetStringLength(js);
4546             value[length < len ? length : len - 2] = (wchar_t) 0;
4547             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringLength()", FALSE);
4548             jniEnv->ReleaseStringChars(js, stringBytes);
4549             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to ReleaseStringChars()", FALSE);
4550             jniEnv->CallVoidMethod(accessBridgeObject,
4551                                    decrementReferenceMethod, js);
4552             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallVoidMethod()", FALSE);
4553             PrintDebugString("[INFO]:   mimimum Accessible Value = %s", value);
4554             jniEnv->DeleteLocalRef(js);
4555             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to DeleteLocalRef()", FALSE);
4556         } else {
4557             PrintDebugString("[WARN]:   mimimum Accessible Value is null.");
4558             value[0] = (wchar_t) 0;
4559             return FALSE;
4560         }
4561     } else {
4562         PrintDebugString("[ERROR]: either env == 0 or getMinimumAccessibleValueFromContextMethod == 0");
4563         return FALSE;
4564     }
4565     return TRUE;
4566 }
4567 
4568 
4569 /********** AccessibleSelection routines ***************/
4570 
4571 void
4572 AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(jobject accessibleContext, int i) {
4573     jthrowable exception;
4574 
4575     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(%p):", accessibleContext);
4576 
4577     // Add the child to the AccessibleSelection
4578     if (addAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4579         jniEnv->CallVoidMethod(accessBridgeObject,
4580                                addAccessibleSelectionFromContextMethod,
4581                                accessibleContext, i);
4582         EXCEPTION_CHECK_VOID("Doing addAccessibleSelection - call to CallVoidMethod()");
4583         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4584     } else {
4585         PrintDebugString("[ERROR]:  either env == 0 or addAccessibleSelectionFromContextMethod == 0");
4586     }
4587 }
4588 
4589 void
4590 AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(jobject accessibleContext) {
4591     jthrowable exception;
4592 
4593     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(%p):", accessibleContext);
4594 
4595     // Clearing the Selection of the AccessibleSelection
4596     if (clearAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4597         jniEnv->CallVoidMethod(accessBridgeObject,
4598                                clearAccessibleSelectionFromContextMethod,
4599                                accessibleContext);
4600         EXCEPTION_CHECK_VOID("Doing clearAccessibleSelection - call to CallVoidMethod()");
4601         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4602     } else {
4603         PrintDebugString("[ERROR]:  either env == 0 or clearAccessibleSelectionFromContextMethod == 0");
4604     }
4605 }
4606 
4607 jobject
4608 AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(jobject accessibleContext, int i) {
4609     jobject returnedAccessibleContext;
4610     jobject globalRef;
4611     jthrowable exception;
4612 
4613     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(%p):", accessibleContext);
4614 
4615     if (getAccessibleSelectionContextFromContextMethod != (jmethodID) 0) {
4616         returnedAccessibleContext = jniEnv->CallObjectMethod(
4617                                                              accessBridgeObject,
4618                                                              getAccessibleSelectionContextFromContextMethod,
4619                                                              accessibleContext, i);
4620         EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to CallObjectMethod()", (jobject) 0);
4621         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
4622         EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to NewGlobalRef()", (jobject) 0);
4623         jniEnv->DeleteLocalRef(returnedAccessibleContext);
4624         EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to DeleteLocalRef()", (jobject) 0);
4625         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
4626                          returnedAccessibleContext, globalRef);
4627         return globalRef;
4628     } else {
4629         PrintDebugString("[ERROR]: either env == 0 or getAccessibleSelectionContextFromContextMethod == 0");
4630         return (jobject) 0;
4631     }
4632 }
4633 
4634 int
4635 AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(jobject accessibleContext) {
4636     int count;
4637     jthrowable exception;
4638 
4639     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(%p):", accessibleContext);
4640 
4641     // Get (& return) the # of items selected in the AccessibleSelection
4642     if (getAccessibleSelectionCountFromContextMethod != (jmethodID) 0) {
4643         count = jniEnv->CallIntMethod(accessBridgeObject,
4644                                       getAccessibleSelectionCountFromContextMethod,
4645                                       accessibleContext);
4646         EXCEPTION_CHECK("Getting AccessibleSelectionCount - call to CallIntMethod()", -1);
4647         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4648         return count;
4649     } else {
4650         PrintDebugString("[ERROR]: either env == 0 or getAccessibleSelectionCountFromContextMethod == 0");
4651         return -1;
4652     }
4653 }
4654 
4655 BOOL
4656 AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(jobject accessibleContext, int i) {
4657     jboolean result;
4658     jthrowable exception;
4659 
4660     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(%p):", accessibleContext);
4661 
4662     // Get (& return) the # of items selected in the AccessibleSelection
4663     if (isAccessibleChildSelectedFromContextMethod != (jmethodID) 0) {
4664         result = jniEnv->CallBooleanMethod(accessBridgeObject,
4665                                            isAccessibleChildSelectedFromContextMethod,
4666                                            accessibleContext, i);
4667         EXCEPTION_CHECK("Doing isAccessibleChildSelected - call to CallBooleanMethod()", FALSE);
4668         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4669         if (result != 0) {
4670             return TRUE;
4671         }
4672     } else {
4673         PrintDebugString("[ERROR]: either env == 0 or isAccessibleChildSelectedFromContextMethod == 0");
4674     }
4675     return FALSE;
4676 }
4677 
4678 
4679 void
4680 AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(jobject accessibleContext, int i) {
4681     jthrowable exception;
4682 
4683     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(%p):", accessibleContext);
4684 
4685     // Remove the i-th child from the AccessibleSelection
4686     if (removeAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4687         jniEnv->CallVoidMethod(accessBridgeObject,
4688                                removeAccessibleSelectionFromContextMethod,
4689                                accessibleContext, i);
4690         EXCEPTION_CHECK_VOID("Doing removeAccessibleSelection - call to CallVoidMethod()");
4691         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4692     } else {
4693         PrintDebugString("[ERROR]:  either env == 0 or removeAccessibleSelectionFromContextMethod == 0");
4694     }
4695 }
4696 
4697 void
4698 AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(jobject accessibleContext) {
4699     jthrowable exception;
4700 
4701     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(%p):", accessibleContext);
4702 
4703     // Select all children (if possible) of the AccessibleSelection
4704     if (selectAllAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4705         jniEnv->CallVoidMethod(accessBridgeObject,
4706                                selectAllAccessibleSelectionFromContextMethod,
4707                                accessibleContext);
4708         EXCEPTION_CHECK_VOID("Doing selectAllAccessibleSelection - call to CallVoidMethod()");
4709         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4710     } else {
4711         PrintDebugString("[ERROR]: either env == 0 or selectAllAccessibleSelectionFromContextMethod == 0");
4712     }
4713 }
4714 
4715 
4716 /********** Event Notification Registration routines ***************/
4717 
4718 BOOL
4719 AccessBridgeJavaEntryPoints::addJavaEventNotification(jlong type) {
4720     jthrowable exception;
4721 
4722     PrintDebugString("[INFO]:   in AccessBridgeJavaEntryPoints::addJavaEventNotification(%016I64X);", type);
4723 
4724     // Let AccessBridge know we want to add an event type
4725     if (addJavaEventNotificationMethod != (jmethodID) 0) {
4726         jniEnv->CallVoidMethod(accessBridgeObject,
4727                                addJavaEventNotificationMethod, type);
4728         EXCEPTION_CHECK("Doing addJavaEventNotification - call to CallVoidMethod()", FALSE);
4729     } else {
4730         PrintDebugString("[ERROR]: either env == 0 or addJavaEventNotificationMethod == 0");
4731         return FALSE;
4732     }
4733     return TRUE;
4734 }
4735 
4736 BOOL
4737 AccessBridgeJavaEntryPoints::removeJavaEventNotification(jlong type) {
4738     jthrowable exception;
4739 
4740     PrintDebugString("[INFO]:  in AccessBridgeJavaEntryPoints::removeJavaEventNotification(%016I64X):", type);
4741 
4742     // Let AccessBridge know we want to remove an event type
4743     if (removeJavaEventNotificationMethod != (jmethodID) 0) {
4744         jniEnv->CallVoidMethod(accessBridgeObject,
4745                                removeJavaEventNotificationMethod, type);
4746         EXCEPTION_CHECK("Doing removeJavaEventNotification - call to CallVoidMethod()", FALSE);
4747     } else {
4748         PrintDebugString("[ERROR]: either env == 0 or removeJavaEventNotificationMethod == 0");
4749         return FALSE;
4750     }
4751     return TRUE;
4752 }
4753 
4754 BOOL
4755 AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(jlong type) {
4756     jthrowable exception;
4757 
4758     PrintDebugString("[INFO]:   in AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(%016I64X);", type);
4759 
4760     // Let AccessBridge know we want to add an event type
4761     if (addAccessibilityEventNotificationMethod != (jmethodID) 0) {
4762         PrintDebugString("[INFO]:    addAccessibilityEventNotification: calling void method: accessBridgeObject = %p", accessBridgeObject);
4763         jniEnv->CallVoidMethod(accessBridgeObject,
4764                                addAccessibilityEventNotificationMethod, type);
4765         EXCEPTION_CHECK("Doing addAccessibilityEvent - call to CallVoidMethod()", FALSE);
4766     } else {
4767         PrintDebugString("[ERROR]: either env == 0 or addAccessibilityEventNotificationMethod == 0");
4768         return FALSE;
4769     }
4770     PrintDebugString("[INFO]:     addAccessibilityEventNotification: just returning true");
4771     return TRUE;
4772 }
4773 
4774 BOOL
4775 AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(jlong type) {
4776     jthrowable exception;
4777 
4778     PrintDebugString("[INFO]:  in AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(%016I64X):", type);
4779 
4780     // Let AccessBridge know we want to remove an event type
4781     if (removeAccessibilityEventNotificationMethod != (jmethodID) 0) {
4782         jniEnv->CallVoidMethod(accessBridgeObject,
4783                                removeAccessibilityEventNotificationMethod, type);
4784         EXCEPTION_CHECK("Doing removeAccessibilityEvent - call to CallVoidMethod()", FALSE);
4785     } else {
4786         PrintDebugString("[ERROR]: either env == 0 or removeAccessibilityEventNotificationMethod == 0");
4787         return FALSE;
4788     }
4789     return TRUE;
4790 }
< prev index next >