1 /*
2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
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  */
AccessBridgeJavaEntryPoints(JNIEnv * jniEnvironment,jobject bridgeObject)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  */
~AccessBridgeJavaEntryPoints()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
BuildJavaEntryPoints()98 AccessBridgeJavaEntryPoints::BuildJavaEntryPoints() {
99     jclass localClassRef;
100 
101     PrintDebugString("[INFO]: Calling BuildJavaEntryPoints():");
102 
103     FIND_CLASS(bridgeClass, "com/sun/java/accessibility/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     // GetMethodID(getAccessBridgeVersionMethod)
118     FIND_METHOD(getAccessBridgeVersionMethod, bridgeClass,
119                 "getAccessBridgeVersion",
120                 "()Ljava/lang/String;");
121 
122 
123     // ------- Window methods
124 
125     // GetMethodID(isJavaWindow)
126     FIND_METHOD(isJavaWindowMethod, bridgeClass,
127                 "isJavaWindow",
128                 "(I)Z");
129 
130     // GetMethodID(getAccessibleContextFromHWND)
131     FIND_METHOD(getAccessibleContextFromHWNDMethod, bridgeClass,
132                 "getContextFromNativeWindowHandle",
133                 "(I)Ljavax/accessibility/AccessibleContext;");
134 
135     // GetMethodID(getHWNDFromAccessibleContext)
136     FIND_METHOD(getHWNDFromAccessibleContextMethod, bridgeClass,
137                 "getNativeWindowHandleFromContext",
138                 "(Ljavax/accessibility/AccessibleContext;)I");
139 
140     // GetMethodID(getAccessibleParentFromContext)
141     FIND_METHOD(getAccessibleParentFromContextMethod, bridgeClass,
142                 "getAccessibleParentFromContext",
143                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;");
144 
145     // ===== utility methods ===== */
146 
147     // GetMethodID(setTextContents)
148     FIND_METHOD(setTextContentsMethod, bridgeClass,
149                 "setTextContents",
150                 "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Z");
151 
152     // GetMethodID(getParentWithRole)
153     FIND_METHOD(getParentWithRoleMethod, bridgeClass,
154                 "getParentWithRole",
155                 "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Ljavax/accessibility/AccessibleContext;");
156 
157     // GetMethodID(getTopLevelObject)
158     FIND_METHOD(getTopLevelObjectMethod, bridgeClass,
159                 "getTopLevelObject",
160                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;");
161 
162     // GetMethodID(getParentWithRoleElseRoot)
163     FIND_METHOD(getParentWithRoleElseRootMethod, bridgeClass,
164                 "getParentWithRoleElseRoot",
165                 "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Ljavax/accessibility/AccessibleContext;");
166 
167     // GetMethodID(getObjectDepth)
168     FIND_METHOD(getObjectDepthMethod, bridgeClass,
169                 "getObjectDepth",
170                 "(Ljavax/accessibility/AccessibleContext;)I");
171 
172     // GetMethodID(getActiveDescendent)
173     FIND_METHOD(getActiveDescendentMethod, bridgeClass,
174                 "getActiveDescendent",
175                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;");
176 
177     // ------- AccessibleContext methods
178 
179     // GetMethodID(getAccessibleContextAt)
180     FIND_METHOD(getAccessibleContextAtMethod, bridgeClass,
181                 "getAccessibleContextAt",
182                 "(IILjavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;");
183 
184     // GetMethodID(getAccessibleContextWithFocus)
185     FIND_METHOD(getAccessibleContextWithFocusMethod, bridgeClass,
186                 "getAccessibleContextWithFocus",
187                 "()Ljavax/accessibility/AccessibleContext;");
188 
189     // GetMethodID(getAccessibleNameFromContext)
190     FIND_METHOD(getAccessibleNameFromContextMethod, bridgeClass,
191                 "getAccessibleNameFromContext",
192                 "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;");
193 
194     // GetMethodID(getAccessibleDescriptionFromContext)
195     FIND_METHOD(getAccessibleDescriptionFromContextMethod, bridgeClass,
196                 "getAccessibleDescriptionFromContext",
197                 "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;");
198 
199     // GetMethodID(getAccessibleRoleStringFromContext)
200     FIND_METHOD(getAccessibleRoleStringFromContextMethod, bridgeClass,
201                 "getAccessibleRoleStringFromContext",
202                 "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;");
203 
204     // GetMethodID(getAccessibleRoleStringFromContext_en_US)
205     FIND_METHOD(getAccessibleRoleStringFromContext_en_USMethod, bridgeClass,
206                 "getAccessibleRoleStringFromContext_en_US",
207                 "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;");
208 
209     // GetMethodID(getAccessibleStatesStringFromContext)
210     FIND_METHOD(getAccessibleStatesStringFromContextMethod, bridgeClass,
211                 "getAccessibleStatesStringFromContext",
212                 "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;");
213 
214     // GetMethodID(getAccessibleStatesStringFromContext_en_US)
215     FIND_METHOD(getAccessibleStatesStringFromContext_en_USMethod, bridgeClass,
216                 "getAccessibleStatesStringFromContext_en_US",
217                 "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;");
218 
219     // GetMethodID(getAccessibleParentFromContext)
220     FIND_METHOD(getAccessibleParentFromContextMethod, bridgeClass,
221                 "getAccessibleParentFromContext",
222                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;");
223 
224     // GetMethodID(getAccessibleIndexInParentFromContext)
225     FIND_METHOD(getAccessibleIndexInParentFromContextMethod, bridgeClass,
226                 "getAccessibleIndexInParentFromContext",
227                 "(Ljavax/accessibility/AccessibleContext;)I");
228 
229     // GetMethodID(getAccessibleChildrenCountFromContext)
230     FIND_METHOD(getAccessibleChildrenCountFromContextMethod, bridgeClass,
231                 "getAccessibleChildrenCountFromContext",
232                 "(Ljavax/accessibility/AccessibleContext;)I");
233 
234     // GetMethodID(getAccessibleChildFromContext)
235     FIND_METHOD(getAccessibleChildFromContextMethod, bridgeClass,
236                 "getAccessibleChildFromContext",
237                 "(Ljavax/accessibility/AccessibleContext;I)Ljavax/accessibility/AccessibleContext;");
238 
239     // GetMethodID(getAccessibleBoundsOnScreenFromContext)
240     FIND_METHOD(getAccessibleBoundsOnScreenFromContextMethod, bridgeClass,
241                 "getAccessibleBoundsOnScreenFromContext",
242                 "(Ljavax/accessibility/AccessibleContext;)Ljava/awt/Rectangle;");
243 
244     // GetMethodID(getAccessibleXcoordFromContext)
245     FIND_METHOD(getAccessibleXcoordFromContextMethod, bridgeClass,
246                 "getAccessibleXcoordFromContext",
247                 "(Ljavax/accessibility/AccessibleContext;)I");
248 
249     // GetMethodID(getAccessibleYcoordFromContext)
250     FIND_METHOD(getAccessibleYcoordFromContextMethod, bridgeClass,
251                 "getAccessibleYcoordFromContext",
252                 "(Ljavax/accessibility/AccessibleContext;)I");
253 
254     // GetMethodID(getAccessibleHeightFromContext)
255     FIND_METHOD(getAccessibleHeightFromContextMethod, bridgeClass,
256                 "getAccessibleHeightFromContext",
257                 "(Ljavax/accessibility/AccessibleContext;)I");
258 
259     // GetMethodID(getAccessibleWidthFromContext)
260     FIND_METHOD(getAccessibleWidthFromContextMethod, bridgeClass,
261                 "getAccessibleWidthFromContext",
262                 "(Ljavax/accessibility/AccessibleContext;)I");
263 
264     // GetMethodID(getAccessibleComponentFromContext)
265     FIND_METHOD(getAccessibleComponentFromContextMethod, bridgeClass,
266                 "getAccessibleComponentFromContext",
267                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleComponent;");
268 
269     // GetMethodID(getAccessibleActionFromContext)
270     FIND_METHOD(getAccessibleActionFromContextMethod, bridgeClass,
271                 "getAccessibleActionFromContext",
272                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleAction;");
273 
274     // GetMethodID(getAccessibleSelectionFromContext)
275     FIND_METHOD(getAccessibleSelectionFromContextMethod, bridgeClass,
276                 "getAccessibleSelectionFromContext",
277                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleSelection;");
278 
279     // GetMethodID(getAccessibleTextFromContext)
280     FIND_METHOD(getAccessibleTextFromContextMethod, bridgeClass,
281                 "getAccessibleTextFromContext",
282                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleText;");
283 
284     // GetMethodID(getAccessibleValueFromContext)
285     FIND_METHOD(getAccessibleValueFromContextMethod, bridgeClass,
286                 "getAccessibleValueFromContext",
287                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleValue;");
288 
289 
290     // ------- begin AccessibleTable methods
291 
292     // GetMethodID(getAccessibleTableFromContext)
293     FIND_METHOD(getAccessibleTableFromContextMethod, bridgeClass,
294                 "getAccessibleTableFromContext",
295                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleTable;");
296 
297     // GetMethodID(getContextFromAccessibleTable)
298     FIND_METHOD(getContextFromAccessibleTableMethod, bridgeClass,
299                 "getContextFromAccessibleTable",
300                 "(Ljavax/accessibility/AccessibleTable;)Ljavax/accessibility/AccessibleContext;");
301 
302     // GetMethodID(getAccessibleTableRowHeader)
303     FIND_METHOD(getAccessibleTableRowHeaderMethod, bridgeClass,
304                 "getAccessibleTableRowHeader",
305                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleTable;");
306 
307 
308     // GetMethodID(getAccessibleTableColumnHeader)
309     FIND_METHOD(getAccessibleTableColumnHeaderMethod, bridgeClass,
310                 "getAccessibleTableColumnHeader",
311                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleTable;");
312 
313 
314     // GetMethodID(getAccessibleTableRowCount)
315     FIND_METHOD(getAccessibleTableRowCountMethod, bridgeClass,
316                 "getAccessibleTableRowCount",
317                 "(Ljavax/accessibility/AccessibleContext;)I");
318 
319     // GetMethodID(getAccessibleTableColumnCount)
320     FIND_METHOD(getAccessibleTableColumnCountMethod, bridgeClass,
321                 "getAccessibleTableColumnCount",
322                 "(Ljavax/accessibility/AccessibleContext;)I");
323 
324     // GetMethodID(getAccessibleTableCellAccessibleContext)
325     FIND_METHOD(getAccessibleTableCellAccessibleContextMethod, bridgeClass,
326                 "getAccessibleTableCellAccessibleContext",
327                 "(Ljavax/accessibility/AccessibleTable;II)Ljavax/accessibility/AccessibleContext;");
328 
329     // GetMethodID(getAccessibleTableCellIndex)
330     FIND_METHOD(getAccessibleTableCellIndexMethod, bridgeClass,
331                 "getAccessibleTableCellIndex",
332                 "(Ljavax/accessibility/AccessibleTable;II)I");
333 
334     // GetMethodID(getAccessibleTableCellRowExtent)
335     FIND_METHOD(getAccessibleTableCellRowExtentMethod, bridgeClass,
336                 "getAccessibleTableCellRowExtent",
337                 "(Ljavax/accessibility/AccessibleTable;II)I");
338 
339     // GetMethodID(getAccessibleTableCellColumnExtent)
340     FIND_METHOD(getAccessibleTableCellColumnExtentMethod, bridgeClass,
341                 "getAccessibleTableCellColumnExtent",
342                 "(Ljavax/accessibility/AccessibleTable;II)I");
343 
344     // GetMethodID(isAccessibleTableCellSelected)
345     FIND_METHOD(isAccessibleTableCellSelectedMethod, bridgeClass,
346                 "isAccessibleTableCellSelected",
347                 "(Ljavax/accessibility/AccessibleTable;II)Z");
348 
349     // GetMethodID(getAccessibleTableRowHeaderRowCount)
350     FIND_METHOD(getAccessibleTableRowHeaderRowCountMethod, bridgeClass,
351                 "getAccessibleTableRowHeaderRowCount",
352                 "(Ljavax/accessibility/AccessibleContext;)I");
353 
354     // GetMethodID(getAccessibleTableColumnHeaderRowCount)
355     FIND_METHOD(getAccessibleTableColumnHeaderRowCountMethod, bridgeClass,
356                 "getAccessibleTableColumnHeaderRowCount",
357                 "(Ljavax/accessibility/AccessibleContext;)I");
358 
359     // GetMethodID(getAccessibleTableRowHeaderColumnCount)
360     FIND_METHOD(getAccessibleTableRowHeaderColumnCountMethod, bridgeClass,
361                 "getAccessibleTableRowHeaderColumnCount",
362                 "(Ljavax/accessibility/AccessibleContext;)I");
363 
364     // GetMethodID(getAccessibleTableColumnHeaderColumnCount)
365     FIND_METHOD(getAccessibleTableColumnHeaderColumnCountMethod, bridgeClass,
366                 "getAccessibleTableColumnHeaderColumnCount",
367                 "(Ljavax/accessibility/AccessibleContext;)I");
368 
369     // GetMethodID(getAccessibleTableRowDescription)
370     FIND_METHOD(getAccessibleTableRowDescriptionMethod, bridgeClass,
371                 "getAccessibleTableRowDescription",
372                 "(Ljavax/accessibility/AccessibleTable;I)Ljavax/accessibility/AccessibleContext;");
373 
374     // GetMethodID(getAccessibleTableColumnDescription)
375     FIND_METHOD(getAccessibleTableColumnDescriptionMethod, bridgeClass,
376                 "getAccessibleTableColumnDescription",
377                 "(Ljavax/accessibility/AccessibleTable;I)Ljavax/accessibility/AccessibleContext;");
378 
379     // GetMethodID(getAccessibleTableRowSelectionCount)
380     FIND_METHOD(getAccessibleTableRowSelectionCountMethod, bridgeClass,
381                 "getAccessibleTableRowSelectionCount",
382                 "(Ljavax/accessibility/AccessibleTable;)I");
383 
384     // GetMethodID(isAccessibleTableRowSelected)
385     FIND_METHOD(isAccessibleTableRowSelectedMethod, bridgeClass,
386                 "isAccessibleTableRowSelected",
387                 "(Ljavax/accessibility/AccessibleTable;I)Z");
388 
389     // GetMethodID(getAccessibleTableRowSelections)
390     FIND_METHOD(getAccessibleTableRowSelectionsMethod, bridgeClass,
391                 "getAccessibleTableRowSelections",
392                 "(Ljavax/accessibility/AccessibleTable;I)I");
393 
394     // GetMethodID(getAccessibleTableColumnSelectionCount)
395     FIND_METHOD(getAccessibleTableColumnSelectionCountMethod, bridgeClass,
396                 "getAccessibleTableColumnSelectionCount",
397                 "(Ljavax/accessibility/AccessibleTable;)I");
398 
399     // GetMethodID(isAccessibleTableColumnSelected)
400     FIND_METHOD(isAccessibleTableColumnSelectedMethod, bridgeClass,
401                 "isAccessibleTableColumnSelected",
402                 "(Ljavax/accessibility/AccessibleTable;I)Z");
403 
404     // GetMethodID(getAccessibleTableColumnSelections)
405     FIND_METHOD(getAccessibleTableColumnSelectionsMethod, bridgeClass,
406                 "getAccessibleTableColumnSelections",
407                 "(Ljavax/accessibility/AccessibleTable;I)I");
408 
409     // GetMethodID(getAccessibleTableRow)
410     FIND_METHOD(getAccessibleTableRowMethod, bridgeClass,
411                 "getAccessibleTableRow",
412                 "(Ljavax/accessibility/AccessibleTable;I)I");
413 
414     // GetMethodID(getAccessibleTableColumn)
415     FIND_METHOD(getAccessibleTableColumnMethod, bridgeClass,
416                 "getAccessibleTableColumn",
417                 "(Ljavax/accessibility/AccessibleTable;I)I");
418 
419     // GetMethodID(getAccessibleTableIndex)
420     FIND_METHOD(getAccessibleTableIndexMethod, bridgeClass,
421                 "getAccessibleTableIndex",
422                 "(Ljavax/accessibility/AccessibleTable;II)I");
423 
424     /* ------- end AccessibleTable methods */
425 
426     /* start AccessibleRelationSet methods ----- */
427 
428     // GetMethodID(getAccessibleRelationCount)
429     FIND_METHOD(getAccessibleRelationCountMethod, bridgeClass,
430                 "getAccessibleRelationCount",
431                 "(Ljavax/accessibility/AccessibleContext;)I");
432 
433     // GetMethodID(getAccessibleRelationKey)
434     FIND_METHOD(getAccessibleRelationKeyMethod, bridgeClass,
435                 "getAccessibleRelationKey",
436                 "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;");
437 
438     // GetMethodID(getAccessibleRelationTargetCount)
439     FIND_METHOD(getAccessibleRelationTargetCountMethod, bridgeClass,
440                 "getAccessibleRelationTargetCount",
441                 "(Ljavax/accessibility/AccessibleContext;I)I");
442 
443     // GetMethodID(getAccessibleRelationTarget)
444     FIND_METHOD(getAccessibleRelationTargetMethod, bridgeClass,
445                 "getAccessibleRelationTarget",
446                 "(Ljavax/accessibility/AccessibleContext;II)Ljavax/accessibility/AccessibleContext;");
447 
448 
449     // ------- AccessibleHypertext methods
450 
451     // GetMethodID(getAccessibleHypertext)
452     FIND_METHOD(getAccessibleHypertextMethod, bridgeClass,
453                 "getAccessibleHypertext",
454                 "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleHypertext;");
455 
456     // GetMethodID(activateAccessibleHyperlink)
457     FIND_METHOD(activateAccessibleHyperlinkMethod, bridgeClass,
458                 "activateAccessibleHyperlink",
459                 "(Ljavax/accessibility/AccessibleContext;Ljavax/accessibility/AccessibleHyperlink;)Z");
460 
461     // GetMethodID(getAccessibleHyperlinkCount)
462     FIND_METHOD(getAccessibleHyperlinkCountMethod, bridgeClass,
463                 "getAccessibleHyperlinkCount",
464                 "(Ljavax/accessibility/AccessibleContext;)I");
465 
466     // GetMethodID(getAccessibleHyperlink)
467     FIND_METHOD(getAccessibleHyperlinkMethod, bridgeClass,
468                 "getAccessibleHyperlink",
469                 "(Ljavax/accessibility/AccessibleHypertext;I)Ljavax/accessibility/AccessibleHyperlink;");
470 
471     // GetMethodID(getAccessibleHyperlinkText)
472     FIND_METHOD(getAccessibleHyperlinkTextMethod, bridgeClass,
473                 "getAccessibleHyperlinkText",
474                 "(Ljavax/accessibility/AccessibleHyperlink;)Ljava/lang/String;");
475 
476     // GetMethodID(getAccessibleHyperlinkURL)
477     FIND_METHOD(getAccessibleHyperlinkURLMethod, bridgeClass,
478                 "getAccessibleHyperlinkURL",
479                 "(Ljavax/accessibility/AccessibleHyperlink;)Ljava/lang/String;");
480 
481     // GetMethodID(getAccessibleHyperlinkStartIndex)
482     FIND_METHOD(getAccessibleHyperlinkStartIndexMethod, bridgeClass,
483                 "getAccessibleHyperlinkStartIndex",
484                 "(Ljavax/accessibility/AccessibleHyperlink;)I");
485 
486     // GetMethodID(getAccessibleHyperlinkEndIndex)
487     FIND_METHOD(getAccessibleHyperlinkEndIndexMethod, bridgeClass,
488                 "getAccessibleHyperlinkEndIndex",
489                 "(Ljavax/accessibility/AccessibleHyperlink;)I");
490 
491     // GetMethodID(getAccessibleHypertextLinkIndex)
492     FIND_METHOD(getAccessibleHypertextLinkIndexMethod, bridgeClass,
493                 "getAccessibleHypertextLinkIndex",
494                 "(Ljavax/accessibility/AccessibleHypertext;I)I");
495 
496     // Accessible KeyBinding, Icon and Action ====================
497 
498     // GetMethodID(getAccessibleKeyBindingsCount)
499     FIND_METHOD(getAccessibleKeyBindingsCountMethod, bridgeClass,
500                 "getAccessibleKeyBindingsCount",
501                 "(Ljavax/accessibility/AccessibleContext;)I");
502 
503     // GetMethodID(getAccessibleKeyBindingChar)
504     FIND_METHOD(getAccessibleKeyBindingCharMethod, bridgeClass,
505                 "getAccessibleKeyBindingChar",
506                 "(Ljavax/accessibility/AccessibleContext;I)C");
507 
508     // GetMethodID(getAccessibleKeyBindingModifiers)
509     FIND_METHOD(getAccessibleKeyBindingModifiersMethod, bridgeClass,
510                 "getAccessibleKeyBindingModifiers",
511                 "(Ljavax/accessibility/AccessibleContext;I)I");
512 
513     // GetMethodID(getAccessibleIconsCount)
514     FIND_METHOD(getAccessibleIconsCountMethod, bridgeClass,
515                 "getAccessibleIconsCount",
516                 "(Ljavax/accessibility/AccessibleContext;)I");
517 
518     // GetMethodID(getAccessibleIconDescription)
519     FIND_METHOD(getAccessibleIconDescriptionMethod, bridgeClass,
520                 "getAccessibleIconDescription",
521                 "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;");
522 
523     // GetMethodID(getAccessibleIconHeight)
524     FIND_METHOD(getAccessibleIconHeightMethod, bridgeClass,
525                 "getAccessibleIconHeight",
526                 "(Ljavax/accessibility/AccessibleContext;I)I");
527 
528     // GetMethodID(getAccessibleIconWidth)
529     FIND_METHOD(getAccessibleIconWidthMethod, bridgeClass,
530                 "getAccessibleIconWidth",
531                 "(Ljavax/accessibility/AccessibleContext;I)I");
532 
533     // GetMethodID(getAccessibleActionsCount)
534     FIND_METHOD(getAccessibleActionsCountMethod, bridgeClass,
535                 "getAccessibleActionsCount",
536                 "(Ljavax/accessibility/AccessibleContext;)I");
537 
538     // GetMethodID(getAccessibleActionName)
539     FIND_METHOD(getAccessibleActionNameMethod, bridgeClass,
540                 "getAccessibleActionName",
541                 "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;");
542 
543     // GetMethodID(doAccessibleActions)
544     FIND_METHOD(doAccessibleActionsMethod, bridgeClass,
545                 "doAccessibleActions",
546                 "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Z");
547 
548     // ------- AccessibleText methods
549 
550     // GetMethodID(getAccessibleCharCountFromContext)
551     FIND_METHOD(getAccessibleCharCountFromContextMethod, bridgeClass,
552                 "getAccessibleCharCountFromContext",
553                 "(Ljavax/accessibility/AccessibleContext;)I");
554 
555     // GetMethodID(getAccessibleCaretPositionFromContext)
556     FIND_METHOD(getAccessibleCaretPositionFromContextMethod, bridgeClass,
557                 "getAccessibleCaretPositionFromContext",
558                 "(Ljavax/accessibility/AccessibleContext;)I");
559 
560     // GetMethodID(getAccessibleIndexAtPointFromContext)
561     FIND_METHOD(getAccessibleIndexAtPointFromContextMethod, bridgeClass,
562                 "getAccessibleIndexAtPointFromContext",
563                 "(Ljavax/accessibility/AccessibleContext;II)I");
564 
565     // GetMethodID(getAccessibleLetterAtIndexFromContext)
566     FIND_METHOD(getAccessibleLetterAtIndexFromContextMethod, bridgeClass,
567                 "getAccessibleLetterAtIndexFromContext",
568                 "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;");
569 
570     // GetMethodID(getAccessibleWordAtIndexFromContext)
571     FIND_METHOD(getAccessibleWordAtIndexFromContextMethod, bridgeClass,
572                 "getAccessibleWordAtIndexFromContext",
573                 "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;");
574 
575     // GetMethodID(getAccessibleSentenceAtIndexFromContext)
576     FIND_METHOD(getAccessibleSentenceAtIndexFromContextMethod, bridgeClass,
577                 "getAccessibleSentenceAtIndexFromContext",
578                 "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;");
579 
580     // GetMethodID(getAccessibleTextSelectionStartFromContext)
581     FIND_METHOD(getAccessibleTextSelectionStartFromContextMethod, bridgeClass,
582                 "getAccessibleTextSelectionStartFromContext",
583                 "(Ljavax/accessibility/AccessibleContext;)I");
584 
585     // GetMethodID(getAccessibleTextSelectionEndFromContext)
586     FIND_METHOD(getAccessibleTextSelectionEndFromContextMethod, bridgeClass,
587                 "getAccessibleTextSelectionEndFromContext",
588                 "(Ljavax/accessibility/AccessibleContext;)I");
589 
590     // GetMethodID(getAccessibleTextSelectedTextFromContext)
591     FIND_METHOD(getAccessibleTextSelectedTextFromContextMethod, bridgeClass,
592                 "getAccessibleTextSelectedTextFromContext",
593                 "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;");
594 
595     // GetMethodID(getAccessibleAttributesAtIndexFromContext)
596     FIND_METHOD(getAccessibleAttributesAtIndexFromContextMethod, bridgeClass,
597                 "getAccessibleAttributesAtIndexFromContext",
598                 "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;");
599 
600     // GetMethodID(getAccessibleAttributeSetAtIndexFromContext)
601     FIND_METHOD(getAccessibleAttributeSetAtIndexFromContextMethod, bridgeClass,
602                 "getAccessibleAttributeSetAtIndexFromContext",
603                 "(Ljavax/accessibility/AccessibleContext;I)Ljavax/swing/text/AttributeSet;");
604 
605     // GetMethodID(getAccessibleTextRectAtIndexFromContext)
606     FIND_METHOD(getAccessibleTextRectAtIndexFromContextMethod, bridgeClass,
607                 "getAccessibleTextRectAtIndexFromContext",
608                 "(Ljavax/accessibility/AccessibleContext;I)Ljava/awt/Rectangle;");
609 
610     // GetMethodID(getAccessibleXcoordTextRectAtIndexFromContext)
611     FIND_METHOD(getAccessibleXcoordTextRectAtIndexFromContextMethod, bridgeClass,
612                 "getAccessibleXcoordTextRectAtIndexFromContext",
613                 "(Ljavax/accessibility/AccessibleContext;I)I");
614 
615     // GetMethodID(getAccessibleYcoordTextRectAtIndexFromContext)
616     FIND_METHOD(getAccessibleYcoordTextRectAtIndexFromContextMethod, bridgeClass,
617                 "getAccessibleYcoordTextRectAtIndexFromContext",
618                 "(Ljavax/accessibility/AccessibleContext;I)I");
619 
620     // GetMethodID(getAccessibleHeightTextRectAtIndexFromContext)
621     FIND_METHOD(getAccessibleHeightTextRectAtIndexFromContextMethod, bridgeClass,
622                 "getAccessibleHeightTextRectAtIndexFromContext",
623                 "(Ljavax/accessibility/AccessibleContext;I)I");
624 
625     // GetMethodID(getAccessibleWidthTextRectAtIndexFromContext)
626     FIND_METHOD(getAccessibleWidthTextRectAtIndexFromContextMethod, bridgeClass,
627                 "getAccessibleWidthTextRectAtIndexFromContext",
628                 "(Ljavax/accessibility/AccessibleContext;I)I");
629 
630     // GetMethodID(getCaretLocationX)
631     FIND_METHOD(getCaretLocationXMethod, bridgeClass,
632                 "getCaretLocationX",
633                 "(Ljavax/accessibility/AccessibleContext;)I");
634 
635     // GetMethodID(getCaretLocationY)
636     FIND_METHOD(getCaretLocationYMethod, bridgeClass,
637                 "getCaretLocationY",
638                 "(Ljavax/accessibility/AccessibleContext;)I");
639 
640     // GetMethodID(getCaretLocationHeight)
641     FIND_METHOD(getCaretLocationHeightMethod, bridgeClass,
642                 "getCaretLocationHeight",
643                 "(Ljavax/accessibility/AccessibleContext;)I");
644 
645     // GetMethodID(getCaretLocationWidth)
646     FIND_METHOD(getCaretLocationWidthMethod, bridgeClass,
647                 "getCaretLocationWidth",
648                 "(Ljavax/accessibility/AccessibleContext;)I");
649 
650 
651     // GetMethodID(getAccessibleTextLineLeftBoundsFromContextMethod)
652     FIND_METHOD(getAccessibleTextLineLeftBoundsFromContextMethod, bridgeClass,
653                 "getAccessibleTextLineLeftBoundsFromContext",
654                 "(Ljavax/accessibility/AccessibleContext;I)I");
655 
656     // GetMethodID(getAccessibleTextLineRightBoundsFromContextMethod)
657     FIND_METHOD(getAccessibleTextLineRightBoundsFromContextMethod, bridgeClass,
658                 "getAccessibleTextLineRightBoundsFromContext",
659                 "(Ljavax/accessibility/AccessibleContext;I)I");
660 
661     // GetMethodID(getAccessibleTextRangeFromContextMethod)
662     FIND_METHOD(getAccessibleTextRangeFromContextMethod, bridgeClass,
663                 "getAccessibleTextRangeFromContext",
664                 "(Ljavax/accessibility/AccessibleContext;II)Ljava/lang/String;");
665 
666 
667     // ------- AccessibleValue methods
668 
669     // GetMethodID(getCurrentAccessibleValueFromContext)
670     FIND_METHOD(getCurrentAccessibleValueFromContextMethod, bridgeClass,
671                 "getCurrentAccessibleValueFromContext",
672                 "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;");
673 
674     // GetMethodID(getMaximumAccessibleValueFromContext)
675     FIND_METHOD(getMaximumAccessibleValueFromContextMethod, bridgeClass,
676                 "getMaximumAccessibleValueFromContext",
677                 "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;");
678 
679     // GetMethodID(getMinimumAccessibleValueFromContext)
680     FIND_METHOD(getMinimumAccessibleValueFromContextMethod, bridgeClass,
681                 "getMinimumAccessibleValueFromContext",
682                 "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;");
683 
684 
685     // ------- AccessibleSelection methods
686 
687     // GetMethodID(addAccessibleSelectionFromContext)
688     FIND_METHOD(addAccessibleSelectionFromContextMethod, bridgeClass,
689                 "addAccessibleSelectionFromContext",
690                 "(Ljavax/accessibility/AccessibleContext;I)V");
691 
692     // GetMethodID(clearAccessibleSelectionFromContext)
693     FIND_METHOD(clearAccessibleSelectionFromContextMethod, bridgeClass,
694                 "clearAccessibleSelectionFromContext",
695                 "(Ljavax/accessibility/AccessibleContext;)V");
696 
697     // GetMethodID(getAccessibleSelectionFromContext)
698     FIND_METHOD(getAccessibleSelectionContextFromContextMethod, bridgeClass,
699                 "getAccessibleSelectionFromContext",
700                 "(Ljavax/accessibility/AccessibleContext;I)Ljavax/accessibility/AccessibleContext;");
701 
702     // GetMethodID(getAccessibleSelectionCountFromContext)
703     FIND_METHOD(getAccessibleSelectionCountFromContextMethod, bridgeClass,
704                 "getAccessibleSelectionCountFromContext",
705                 "(Ljavax/accessibility/AccessibleContext;)I");
706 
707     // GetMethodID(isAccessibleChildSelectedFromContext)
708     FIND_METHOD(isAccessibleChildSelectedFromContextMethod, bridgeClass,
709                 "isAccessibleChildSelectedFromContext",
710                 "(Ljavax/accessibility/AccessibleContext;I)Z");
711 
712     // GetMethodID(removeAccessibleSelectionFromContext)
713     FIND_METHOD(removeAccessibleSelectionFromContextMethod, bridgeClass,
714                 "removeAccessibleSelectionFromContext",
715                 "(Ljavax/accessibility/AccessibleContext;I)V");
716 
717     // GetMethodID(selectAllAccessibleSelectionFromContext)
718     FIND_METHOD(selectAllAccessibleSelectionFromContextMethod, bridgeClass,
719                 "selectAllAccessibleSelectionFromContext",
720                 "(Ljavax/accessibility/AccessibleContext;)V");
721 
722 
723     // ------- Event Notification methods
724 
725     // GetMethodID(addJavaEventNotification)
726     FIND_METHOD(addJavaEventNotificationMethod, bridgeClass,
727                 "addJavaEventNotification", "(J)V");
728 
729     // GetMethodID(removeJavaEventNotification)
730     FIND_METHOD(removeJavaEventNotificationMethod, bridgeClass,
731                 "removeJavaEventNotification", "(J)V");
732 
733     // GetMethodID(addAccessibilityEventNotification)
734     FIND_METHOD(addAccessibilityEventNotificationMethod, bridgeClass,
735                 "addAccessibilityEventNotification", "(J)V");
736 
737     // GetMethodID(removeAccessibilityEventNotification)
738     FIND_METHOD(removeAccessibilityEventNotificationMethod, bridgeClass,
739                 "removeAccessibilityEventNotification", "(J)V");
740 
741 
742     // ------- AttributeSet methods
743 
744     // GetMethodID(getBoldFromAttributeSet)
745     FIND_METHOD(getBoldFromAttributeSetMethod, bridgeClass,
746                 "getBoldFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z");
747 
748     // GetMethodID(getItalicFromAttributeSet)
749     FIND_METHOD(getItalicFromAttributeSetMethod, bridgeClass,
750                 "getItalicFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z");
751 
752     // GetMethodID(getUnderlineFromAttributeSet)
753     FIND_METHOD(getUnderlineFromAttributeSetMethod, bridgeClass,
754                 "getUnderlineFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z");
755 
756     // GetMethodID(getStrikethroughFromAttributeSet)
757     FIND_METHOD(getStrikethroughFromAttributeSetMethod, bridgeClass,
758                 "getStrikethroughFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z");
759 
760     // GetMethodID(getSuperscriptFromAttributeSet)
761     FIND_METHOD(getSuperscriptFromAttributeSetMethod, bridgeClass,
762                 "getSuperscriptFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z");
763 
764     // GetMethodID(getSubscriptFromAttributeSet)
765     FIND_METHOD(getSubscriptFromAttributeSetMethod, bridgeClass,
766                 "getSubscriptFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z");
767 
768     // GetMethodID(getBackgroundColorFromAttributeSet)
769     FIND_METHOD(getBackgroundColorFromAttributeSetMethod, bridgeClass,
770                 "getBackgroundColorFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Ljava/lang/String;");
771 
772     // GetMethodID(getForegroundColorFromAttributeSet)
773     FIND_METHOD(getForegroundColorFromAttributeSetMethod, bridgeClass,
774                 "getForegroundColorFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Ljava/lang/String;");
775 
776     // GetMethodID(getFontFamilyFromAttributeSet)
777     FIND_METHOD(getFontFamilyFromAttributeSetMethod, bridgeClass,
778                 "getFontFamilyFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Ljava/lang/String;");
779 
780     // GetMethodID(getFontSizeFromAttributeSet)
781     FIND_METHOD(getFontSizeFromAttributeSetMethod, bridgeClass,
782                 "getFontSizeFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)I");
783 
784     // GetMethodID(getAlignmentFromAttributeSet)
785     FIND_METHOD(getAlignmentFromAttributeSetMethod, bridgeClass,
786                 "getAlignmentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)I");
787 
788     // GetMethodID(getBidiLevelFromAttributeSet)
789     FIND_METHOD(getBidiLevelFromAttributeSetMethod, bridgeClass,
790                 "getBidiLevelFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)I");
791 
792     // GetMethodID(getFirstLineIndentFromAttributeSet)
793     FIND_METHOD(getFirstLineIndentFromAttributeSetMethod, bridgeClass,
794                 "getFirstLineIndentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F");
795 
796     // GetMethodID(getLeftIndentFromAttributeSet)
797     FIND_METHOD(getLeftIndentFromAttributeSetMethod, bridgeClass,
798                 "getLeftIndentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F");
799 
800     // GetMethodID(getRightIndentFromAttributeSet)
801     FIND_METHOD(getRightIndentFromAttributeSetMethod, bridgeClass,
802                 "getRightIndentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F");
803 
804     // GetMethodID(getLineSpacingFromAttributeSet)
805     FIND_METHOD(getLineSpacingFromAttributeSetMethod, bridgeClass,
806                 "getLineSpacingFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F");
807 
808     // GetMethodID(getSpaceAboveFromAttributeSet)
809     FIND_METHOD(getSpaceAboveFromAttributeSetMethod, bridgeClass,
810                 "getSpaceAboveFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F");
811 
812     // GetMethodID(getSpaceBelowFromAttributeSet)
813     FIND_METHOD(getSpaceBelowFromAttributeSetMethod, bridgeClass,
814                 "getSpaceBelowFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F");
815 
816 
817     /**
818      * Additional methods for Teton
819      */
820 
821     // GetMethodID(requestFocus)
822     FIND_METHOD(requestFocusMethod, bridgeClass,
823                 "requestFocus",
824                 "(Ljavax/accessibility/AccessibleContext;)Z");
825 
826     // GetMethodID(selectTextRange)
827     FIND_METHOD(selectTextRangeMethod, bridgeClass,
828                 "selectTextRange",
829                 "(Ljavax/accessibility/AccessibleContext;II)Z");
830 
831     // GetMethodID(getVisibleChildrenCount)
832     FIND_METHOD(getVisibleChildrenCountMethod, bridgeClass,
833                 "getVisibleChildrenCount",
834                 "(Ljavax/accessibility/AccessibleContext;)I");
835 
836     // GetMethodID(getVisibleChild)
837     FIND_METHOD(getVisibleChildMethod, bridgeClass,
838                 "getVisibleChild",
839                 "(Ljavax/accessibility/AccessibleContext;I)Ljavax/accessibility/AccessibleContext;");
840 
841     // GetMethodID(setCaretPosition)
842     FIND_METHOD(setCaretPositionMethod, bridgeClass,
843                 "setCaretPosition",
844                 "(Ljavax/accessibility/AccessibleContext;I)Z");
845 
846     // GetMethodID(getVirtualAccessibleNameFromContextMethod) Ben Key
847     FIND_METHOD(getVirtualAccessibleNameFromContextMethod, bridgeClass,
848                 "getVirtualAccessibleNameFromContext",
849                 "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;");
850 
851     return TRUE;
852 }
853 
854 // Note for the following code which makes JNI upcalls...
855 //
856 // Problem, bug DB 16818166, JBS DB JDK-8015400
857 // AccessibleContext is a JOBJECT64 which is a jobject (32 bit pointer)
858 // for a Legacy (XP) build and a jlong (64 bits) for a -32 or -64 build.
859 // For the -32 build the lower 32 bits needs to be extracted into a jobject.
860 // Otherwise, if AccessibleContext is used directly what happens is that
861 // the JNI code consumes the lower 32 of its 64 bits and that is not a
862 // problem, but then when the JNI code consumes the next 32 bits for the
863 // reference to the role String it gets the higher 0x00000000 bits from
864 // the 64 bit JOBJECT64 AccessibleContext variable and thus a null reference
865 // is passed as the String reference.
866 //
867 // Solution:
868 // Cast the JOBJECT64 to a jobject.  For a 64 bit compile this is basically
869 // a noop, i.e. JOBJECT64 is a 64 bit jlong and a jobject is a 64 bit reference.
870 // For a 32 bit compile the cast drops the high order 32 bits, i.e. JOBJECT64
871 // is a 64 bit jlong and jobject is a 32 bit reference.  For a Legacy build
872 // JOBJECT64 is a jobject so this is also basically a noop.  The casts are
873 // done in the methods in JavaAccessBridge::processPackage.
874 
875 // -----------------------------------
876 
877 /**
878  * isJavaWindow - returns whether the HWND is a Java window or not
879  *
880  */
881 BOOL
isJavaWindow(jint window)882 AccessBridgeJavaEntryPoints::isJavaWindow(jint window) {
883     jthrowable exception;
884     BOOL returnVal;
885 
886     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::isJavaWindow(%X):", window);
887 
888     if (isJavaWindowMethod != (jmethodID) 0) {
889         returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, isJavaWindowMethod, window);
890         EXCEPTION_CHECK("Getting isJavaWindow - call to CallBooleanMethod()", FALSE);
891         return returnVal;
892     } else {
893         PrintDebugString("[ERROR]: either jniEnv == 0 or isJavaWindowMethod == 0");
894         return FALSE;
895     }
896 }
897 
898 // -----------------------------------
899 
900 /**
901  * isSameObject - returns whether two object reference refer to the same object
902  *
903  */
904 BOOL
isSameObject(jobject obj1,jobject obj2)905 AccessBridgeJavaEntryPoints::isSameObject(jobject obj1, jobject obj2) {
906     jthrowable exception;
907     BOOL returnVal;
908 
909     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::isSameObject(%p %p):", obj1, obj2);
910 
911     returnVal = (BOOL) jniEnv->IsSameObject((jobject)obj1, (jobject)obj2);
912     EXCEPTION_CHECK("Calling IsSameObject", FALSE);
913 
914     PrintDebugString("[INFO]:   isSameObject returning %d", returnVal);
915     return returnVal;
916 }
917 
918 // -----------------------------------
919 
920 /**
921  * getAccessibleContextFromHWND - returns the AccessibleContext, if any, for an HWND
922  *
923  */
924 jobject
getAccessibleContextFromHWND(jint window)925 AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(jint window) {
926     jobject returnedAccessibleContext;
927     jobject globalRef;
928     jthrowable exception;
929 
930     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(%X):", window);
931 
932     if (getAccessibleContextFromHWNDMethod != (jmethodID) 0) {
933         returnedAccessibleContext =
934             (jobject)jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleContextFromHWNDMethod,
935                                               window);
936         EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0);
937         globalRef = (jobject)jniEnv->NewGlobalRef((jobject)returnedAccessibleContext);
938         EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0);
939         return globalRef;
940     } else {
941         PrintDebugString("[ERROR]:  either jniEnv == 0 or getAccessibleContextFromHWNDMethod == 0");
942         return (jobject) 0;
943     }
944 }
945 
946 // -----------------------------------
947 
948 /**
949  * getHWNDFromAccessibleContext - returns the HWND for an AccessibleContext, if any
950  *      returns (HWND)0 on error.
951  */
952 HWND
getHWNDFromAccessibleContext(jobject accessibleContext)953 AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(jobject accessibleContext) {
954     jthrowable exception;
955     HWND rHWND;
956 
957     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(%X):",
958                      accessibleContext);
959 
960     if (getHWNDFromAccessibleContextMethod != (jmethodID) 0) {
961         rHWND = (HWND)jniEnv->CallIntMethod(accessBridgeObject, getHWNDFromAccessibleContextMethod,
962                                             accessibleContext);
963         EXCEPTION_CHECK("Getting HWNDFromAccessibleContext - call to CallIntMethod()", (HWND)0);
964         PrintDebugString("[INFO]: rHWND = %X", rHWND);
965         return rHWND;
966     } else {
967         PrintDebugString("[ERROR]: either jniEnv == 0 or getHWNDFromAccessibleContextMethod == 0");
968         return (HWND)0;
969     }
970 }
971 
972 
973 /* ====== Utility methods ===== */
974 
975 /**
976  * Sets a text field to the specified string.  Returns whether successful;
977  */
978 BOOL
setTextContents(const jobject accessibleContext,const wchar_t * text)979 AccessBridgeJavaEntryPoints::setTextContents(const jobject accessibleContext, const wchar_t *text) {
980     jthrowable exception;
981     BOOL result = FALSE;
982 
983     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::setTextContents(%p, %ls):",
984                      accessibleContext, text);
985 
986     if (setTextContentsMethod != (jmethodID) 0) {
987 
988         // create a Java String for the text
989         jstring textString = jniEnv->NewString(text, (jsize)wcslen(text));
990         if (textString == 0) {
991             PrintDebugString("[ERROR]:    NewString failed");
992             return FALSE;
993         }
994 
995         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
996                                                  setTextContentsMethod,
997                                                  accessibleContext, textString);
998         EXCEPTION_CHECK("setTextContents - call to CallBooleanMethod()", FALSE);
999         PrintDebugString("[INFO]:     result = %d", result);
1000         return result;
1001     } else {
1002         PrintDebugString("[ERROR]: either jniEnv == 0 or setTextContentsMethod == 0");
1003         return result;
1004     }
1005 }
1006 
1007 /**
1008  * Returns the Accessible Context of a Page Tab object that is the
1009  * ancestor of a given object.  If the object is a Page Tab object
1010  * or a Page Tab ancestor object was found, returns the object
1011  * AccessibleContext.
1012  * If there is no ancestor object that has an Accessible Role of Page Tab,
1013  * returns (AccessibleContext)0.
1014  */
1015 jobject
getParentWithRole(const jobject accessibleContext,const wchar_t * role)1016 AccessBridgeJavaEntryPoints::getParentWithRole(const jobject accessibleContext, const wchar_t *role) {
1017     jthrowable exception;
1018     jobject rAccessibleContext;
1019 
1020     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getParentWithRole(%p):",
1021                      accessibleContext);
1022 
1023     if (getParentWithRoleMethod != (jmethodID) 0) {
1024         // create a Java String for the role
1025         jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role));
1026         if (roleName == 0) {
1027             PrintDebugString("[ERROR]:     NewString failed");
1028             return FALSE;
1029         }
1030 
1031         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1032                                                       getParentWithRoleMethod,
1033                                                       accessibleContext, roleName);
1034         EXCEPTION_CHECK("Getting ParentWithRole - call to CallObjectMethod()", (AccessibleContext)0);
1035         PrintDebugString("[INFO]:     rAccessibleContext = %p", rAccessibleContext);
1036         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1037         EXCEPTION_CHECK("Getting ParentWithRole - call to NewGlobalRef()", FALSE);
1038         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1039                          rAccessibleContext, globalRef);
1040         return globalRef;
1041     } else {
1042         PrintDebugString("[ERROR]: either jniEnv == 0 or getParentWithRoleMethod == 0");
1043         return 0;
1044     }
1045 }
1046 
1047 /**
1048  * Returns the Accessible Context for the top level object in
1049  * a Java Window.  This is same Accessible Context that is obtained
1050  * from GetAccessibleContextFromHWND for that window.  Returns
1051  * (AccessibleContext)0 on error.
1052  */
1053 jobject
getTopLevelObject(const jobject accessibleContext)1054 AccessBridgeJavaEntryPoints::getTopLevelObject(const jobject accessibleContext) {
1055     jthrowable exception;
1056     jobject rAccessibleContext;
1057 
1058     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getTopLevelObject(%p):",
1059                      accessibleContext);
1060 
1061     if (getTopLevelObjectMethod != (jmethodID) 0) {
1062         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1063                                                       getTopLevelObjectMethod,
1064                                                       accessibleContext);
1065         EXCEPTION_CHECK("Getting TopLevelObject - call to CallObjectMethod()", FALSE);
1066         PrintDebugString("[INFO]:  rAccessibleContext = %p", rAccessibleContext);
1067         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1068         EXCEPTION_CHECK("Getting TopLevelObject - call to NewGlobalRef()", FALSE);
1069         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1070                          rAccessibleContext, globalRef);
1071         return globalRef;
1072     } else {
1073         PrintDebugString("[ERROR]: either jniEnv == 0 or getTopLevelObjectMethod == 0");
1074         return 0;
1075     }
1076 }
1077 
1078 /**
1079  * If there is an Ancestor object that has an Accessible Role of
1080  * Internal Frame, returns the Accessible Context of the Internal
1081  * Frame object.  Otherwise, returns the top level object for that
1082  * Java Window.  Returns (AccessibleContext)0 on error.
1083  */
1084 jobject
getParentWithRoleElseRoot(const jobject accessibleContext,const wchar_t * role)1085 AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(const jobject accessibleContext, const wchar_t *role) {
1086     jthrowable exception;
1087     jobject rAccessibleContext;
1088 
1089     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(%p):",
1090                      accessibleContext);
1091 
1092     if (getParentWithRoleElseRootMethod != (jmethodID) 0) {
1093 
1094         // create a Java String for the role
1095         jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role));
1096         if (roleName == 0) {
1097             PrintDebugString("[ERROR]:     NewString failed");
1098             return FALSE;
1099         }
1100 
1101         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1102                                                       getParentWithRoleElseRootMethod,
1103                                                       accessibleContext, roleName);
1104         EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to CallObjectMethod()", (AccessibleContext)0);
1105         PrintDebugString("[INFO]:     rAccessibleContext = %p", rAccessibleContext);
1106         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1107         EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to NewGlobalRef()", FALSE);
1108         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1109                          rAccessibleContext, globalRef);
1110         return globalRef;
1111     } else {
1112         PrintDebugString("[ERROR]:  either jniEnv == 0 or getParentWithRoleElseRootMethod == 0");
1113         return 0;
1114     }
1115 }
1116 
1117 /**
1118  * Returns how deep in the object hierarchy a given object is.
1119  * The top most object in the object hierarchy has an object depth of 0.
1120  * Returns -1 on error.
1121  */
1122 jint
getObjectDepth(const jobject accessibleContext)1123 AccessBridgeJavaEntryPoints::getObjectDepth(const jobject accessibleContext) {
1124     jthrowable exception;
1125     jint rResult;
1126 
1127     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getObjectDepth(%p):",
1128                      accessibleContext);
1129 
1130     if (getObjectDepthMethod != (jmethodID) 0) {
1131         rResult = jniEnv->CallIntMethod(accessBridgeObject,
1132                                         getObjectDepthMethod,
1133                                         accessibleContext);
1134         EXCEPTION_CHECK("Getting ObjectDepth - call to CallIntMethod()", -1);
1135         PrintDebugString("[INFO]:     rResult = %d", rResult);
1136         return rResult;
1137     } else {
1138         PrintDebugString("[ERROR]: either jniEnv == 0 or getObjectDepthMethod == 0");
1139         return -1;
1140     }
1141 }
1142 
1143 
1144 
1145 /**
1146  * Returns the Accessible Context of the current ActiveDescendent of an object.
1147  * Returns 0 on error.
1148  */
1149 jobject
getActiveDescendent(const jobject accessibleContext)1150 AccessBridgeJavaEntryPoints::getActiveDescendent(const jobject accessibleContext) {
1151     jthrowable exception;
1152     jobject rAccessibleContext;
1153 
1154     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getActiveDescendent(%p):",
1155                      accessibleContext);
1156 
1157     if (getActiveDescendentMethod != (jmethodID) 0) {
1158         rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1159                                                       getActiveDescendentMethod,
1160                                                       accessibleContext);
1161         EXCEPTION_CHECK("Getting ActiveDescendent - call to CallObjectMethod()", (AccessibleContext)0);
1162         PrintDebugString("[INFO]:     rAccessibleContext = %p", rAccessibleContext);
1163         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
1164         EXCEPTION_CHECK("Getting ActiveDescendant - call to NewGlobalRef()", FALSE);
1165         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1166                          rAccessibleContext, globalRef);
1167         return globalRef;
1168     } else {
1169         PrintDebugString("[ERROR]: either jniEnv == 0 or getActiveDescendentMethod == 0");
1170         return (AccessibleContext)0;
1171     }
1172 }
1173 
1174 /**
1175  * Additional methods for Teton
1176  */
1177 
1178 /**
1179  * Returns an AccessibleName for a component using an algorithm optimized
1180  * for the JAWS screen reader by Ben Key (Freedom Scientific).  This method
1181  * is only intended for JAWS. All other uses are entirely optional.
1182  *
1183  * Bug ID 4916682 - Implement JAWS AccessibleName policy
1184  */
1185 BOOL
getVirtualAccessibleName(IN const jobject object,OUT wchar_t * name,IN const int nameSize)1186 AccessBridgeJavaEntryPoints::getVirtualAccessibleName (
1187     IN const jobject object,
1188     OUT wchar_t * name,
1189     IN const int nameSize)
1190 {
1191     /*
1192       +
1193       Parameter validation
1194       +
1195     */
1196     if ((name == 0) || (nameSize == 0))
1197     {
1198         return FALSE;
1199     }
1200     ::memset (name, 0, nameSize * sizeof (wchar_t));
1201     if (0 == object)
1202     {
1203         return FALSE;
1204     }
1205 
1206     jstring js = NULL;
1207     const wchar_t * stringBytes = NULL;
1208     jthrowable exception = NULL;
1209     jsize length = 0;
1210     PrintDebugString("[INFO]:  getVirtualAccessibleName called.");
1211     if (getVirtualAccessibleNameFromContextMethod != (jmethodID) 0)
1212     {
1213         js = (jstring) jniEnv->CallObjectMethod (
1214             accessBridgeObject,
1215             getVirtualAccessibleNameFromContextMethod,
1216             object);
1217         EXCEPTION_CHECK("Getting AccessibleName - call to CallObjectMethod()", FALSE);
1218         if (js != (jstring) 0)
1219         {
1220             stringBytes = (const wchar_t *) jniEnv->GetStringChars (js, 0);
1221             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE);
1222             wcsncpy(name, stringBytes, nameSize - 1);
1223             length = jniEnv->GetStringLength(js);
1224             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE);
1225             jniEnv->ReleaseStringChars(js, stringBytes);
1226             EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE);
1227             jniEnv->CallVoidMethod (
1228                 accessBridgeObject,
1229                 decrementReferenceMethod, js);
1230             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
1231             wPrintDebugString(L"[INFO]:  Accessible Name = %ls", name);
1232             jniEnv->DeleteLocalRef(js);
1233             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
1234         }
1235         else
1236         {
1237             PrintDebugString("[INFO]:   Accessible Name is null.");
1238         }
1239     }
1240     else
1241     {
1242         PrintDebugString("[INFO]: either jniEnv == 0 or getVirtualAccessibleNameFromContextMethod == 0");
1243         return FALSE;
1244     }
1245     if ( 0 != name [0] )
1246     {
1247         return TRUE;
1248     }
1249     return FALSE;
1250 }
1251 
1252 
1253 /**
1254  * Request focus for a component. Returns whether successful;
1255  *
1256  * Bug ID 4944757 - requestFocus method needed
1257  */
1258 BOOL
requestFocus(const jobject accessibleContext)1259 AccessBridgeJavaEntryPoints::requestFocus(const jobject accessibleContext) {
1260 
1261     jthrowable exception;
1262     BOOL result = FALSE;
1263 
1264     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::requestFocus(%p):",
1265                      accessibleContext);
1266 
1267     if (requestFocusMethod != (jmethodID) 0) {
1268         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
1269                                                  requestFocusMethod,
1270                                                  accessibleContext);
1271         EXCEPTION_CHECK("requestFocus - call to CallBooleanMethod()", FALSE);
1272         PrintDebugString("[INFO]:    result = %d", result);
1273         return result;
1274     } else {
1275         PrintDebugString("[ERROR]: either jniEnv == 0 or requestFocusMethod == 0");
1276         return result;
1277     }
1278 }
1279 
1280 /**
1281  * Selects text between two indices.  Selection includes the text at the start index
1282  * and the text at the end index. Returns whether successful;
1283  *
1284  * Bug ID 4944758 - selectTextRange method needed
1285  */
1286 BOOL
selectTextRange(const jobject accessibleContext,int startIndex,int endIndex)1287 AccessBridgeJavaEntryPoints::selectTextRange(const jobject accessibleContext, int startIndex, int endIndex) {
1288 
1289     jthrowable exception;
1290     BOOL result = FALSE;
1291 
1292     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::selectTextRange(%p start = %d end = %d):",
1293                      accessibleContext, startIndex, endIndex);
1294 
1295     if (selectTextRangeMethod != (jmethodID) 0) {
1296         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
1297                                                  selectTextRangeMethod,
1298                                                  accessibleContext,
1299                                                  startIndex, endIndex);
1300         EXCEPTION_CHECK("selectTextRange - call to CallBooleanMethod()", FALSE);
1301         PrintDebugString("[INFO]:     result = %d", result);
1302         return result;
1303     } else {
1304         PrintDebugString("[ERROR]: either jniEnv == 0 or selectTextRangeMethod == 0");
1305         return result;
1306     }
1307 }
1308 
1309 /*
1310  * Returns whether two text attributes are the same.
1311  */
CompareAccessibleTextAttributesInfo(AccessibleTextAttributesInfo * one,AccessibleTextAttributesInfo * two)1312 static BOOL CompareAccessibleTextAttributesInfo(AccessibleTextAttributesInfo *one,
1313                                                 AccessibleTextAttributesInfo *two) {
1314     return(one->bold == two->bold
1315            && one->italic == two->italic
1316            && one->underline == two->underline
1317            && one->strikethrough == two->strikethrough
1318            && one->superscript == two->superscript
1319            && one->subscript == two->subscript
1320            && one->fontSize == two->fontSize
1321            && one->alignment == two->alignment
1322            && one->bidiLevel == two->bidiLevel
1323            && one->firstLineIndent == two->firstLineIndent
1324            && one->leftIndent == two->leftIndent
1325            && one->rightIndent == two->rightIndent
1326            && one->lineSpacing == two->lineSpacing
1327            && one->spaceAbove == two->spaceAbove
1328            && one->spaceBelow == two->spaceBelow
1329            && !wcscmp(one->backgroundColor,two->backgroundColor)
1330            && !wcscmp(one->foregroundColor,two->foregroundColor)
1331            && !wcscmp(one->fullAttributesString,two->fullAttributesString));
1332 }
1333 
1334 /**
1335  * Get text attributes between two indices.
1336  *
1337  * Only one AccessibleTextAttributesInfo structure is passed - which
1338  * contains the attributes for the first character, the function then goes
1339  * through the following characters in the range specified and stops when the
1340  * attributes are different from the first, it then returns in the passed
1341  * parameter len the number of characters with the attributes returned. In most
1342  * situations this will be all the characters, and if not the calling program
1343  * can easily get the attributes for the next characters with different
1344  * attributes
1345  *
1346  * Bug ID 4944761 - getTextAttributes between two indices method needed
1347  */
1348 
1349 /* NEW FASTER CODE!!*/
1350 BOOL
getTextAttributesInRange(const jobject accessibleContext,int startIndex,int endIndex,AccessibleTextAttributesInfo * attributes,short * len)1351 AccessBridgeJavaEntryPoints::getTextAttributesInRange(const jobject accessibleContext,
1352                                                       int startIndex, int endIndex,
1353                                                       AccessibleTextAttributesInfo *attributes, short *len) {
1354 
1355     jstring js;
1356     const wchar_t *stringBytes;
1357     jthrowable exception;
1358     jsize length;
1359     BOOL result = FALSE;
1360 
1361     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getTextAttributesInRange(%p start = %d end = %d):",
1362                      accessibleContext, startIndex, endIndex);
1363 
1364     *len = 0;
1365     result = getAccessibleTextAttributes((jobject)accessibleContext, startIndex, attributes);
1366     if (result != TRUE) {
1367         return FALSE;
1368     }
1369     (*len)++;
1370 
1371     for (jint i = startIndex+1; i <= endIndex; i++) {
1372 
1373         AccessibleTextAttributesInfo test_attributes = *attributes;
1374         // Get the full test_attributes string at i
1375         if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) {
1376             PrintDebugString("[INFO]:  Getting full test_attributes string from Context...");
1377             js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1378                                                     getAccessibleAttributesAtIndexFromContextMethod,
1379                                                     accessibleContext, i);
1380             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE);
1381             PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
1382             if (js != (jstring) 0) {
1383                 stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1384                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE);
1385                 wcsncpy(test_attributes.fullAttributesString, stringBytes, (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t)));
1386                 length = jniEnv->GetStringLength(js);
1387                 test_attributes.fullAttributesString[length < (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t)) ?
1388                                                      length : (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0;
1389                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE);
1390                 jniEnv->ReleaseStringChars(js, stringBytes);
1391                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE);
1392                 jniEnv->CallVoidMethod(accessBridgeObject,
1393                                        decrementReferenceMethod, js);
1394                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE);
1395                 wPrintDebugString(L"[INFO]:  Accessible Text attributes = %ls", test_attributes.fullAttributesString);
1396                 jniEnv->DeleteLocalRef(js);
1397                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
1398             } else {
1399                 PrintDebugString("[WARN]:   Accessible Text attributes is null.");
1400                 test_attributes.fullAttributesString[0] = (wchar_t) 0;
1401                 return FALSE;
1402             }
1403         } else {
1404             PrintDebugString("[ERROR]: either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0");
1405             return FALSE;
1406         }
1407 
1408         if(wcscmp(attributes->fullAttributesString,test_attributes.fullAttributesString))
1409             break;
1410         if (result != TRUE) {
1411             return FALSE;
1412         }
1413         (*len)++;
1414     }
1415     return TRUE;
1416 }
1417 
1418 /*
1419  * Returns the number of visible children of a component
1420  *
1421  * Bug ID 4944762- getVisibleChildren for list-like components needed
1422  */
1423 int
getVisibleChildrenCount(const jobject accessibleContext)1424 AccessBridgeJavaEntryPoints::getVisibleChildrenCount(const jobject accessibleContext) {
1425 
1426     jthrowable exception;
1427     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getVisibleChildrenCount(%p)",
1428                      accessibleContext);
1429 
1430     // get the visible children count
1431     int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod,
1432                                             accessibleContext);
1433     EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE);
1434     PrintDebugString("[INFO]:   ##### visible children count = %d", numChildren);
1435 
1436     return numChildren;
1437 }
1438 
1439 
1440 /*
1441  * This method is used to iterate through the visible children of a component.  It
1442  * returns visible children information for a component starting at nStartIndex.
1443  * No more than MAX_VISIBLE_CHILDREN VisibleChildrenInfo objects will
1444  * be returned for each call to this method. Returns FALSE on error.
1445  *
1446  * Bug ID 4944762- getVisibleChildren for list-like components needed
1447  */
getVisibleChildren(const jobject accessibleContext,const int nStartIndex,VisibleChildrenInfo * visibleChildrenInfo)1448 BOOL AccessBridgeJavaEntryPoints::getVisibleChildren(const jobject accessibleContext,
1449                                                      const int nStartIndex,
1450                                                      /* OUT */ VisibleChildrenInfo *visibleChildrenInfo) {
1451 
1452     jthrowable exception;
1453 
1454     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getVisibleChildren(%p, startIndex = %d)",
1455                      accessibleContext, nStartIndex);
1456 
1457     // get the visible children count
1458     int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod,
1459                                             accessibleContext);
1460     EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE);
1461     PrintDebugString("[INFO]:   ##### visible children count = %d", numChildren);
1462 
1463     if (nStartIndex >= numChildren) {
1464         return FALSE;
1465     }
1466 
1467     // get the visible children
1468     int bufIndex = 0;
1469     for (int i = nStartIndex; (i < numChildren) && (i < nStartIndex + MAX_VISIBLE_CHILDREN); i++) {
1470         PrintDebugString("[INFO]:   getting visible child %d ...", i);
1471 
1472         // get the visible child at index i
1473         jobject ac = jniEnv->CallObjectMethod(accessBridgeObject, getVisibleChildMethod,
1474                                               accessibleContext, i);
1475         EXCEPTION_CHECK("##### getVisibleChildMethod - call to CallObjectMethod()", FALSE);
1476         jobject globalRef = jniEnv->NewGlobalRef(ac);
1477         EXCEPTION_CHECK("##### getVisibleChildMethod - call to NewGlobalRef()", FALSE);
1478         visibleChildrenInfo->children[bufIndex] = (JOBJECT64)globalRef;
1479         PrintDebugString("[INFO]:   ##### visible child = %p", globalRef);
1480 
1481         bufIndex++;
1482     }
1483     visibleChildrenInfo->returnedChildrenCount = bufIndex;
1484 
1485     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getVisibleChildren succeeded");
1486     return TRUE;
1487 }
1488 
1489 /**
1490  * Set the caret to a text position. Returns whether successful;
1491  *
1492  * Bug ID 4944770 - setCaretPosition method needed
1493  */
1494 BOOL
setCaretPosition(const jobject accessibleContext,int position)1495 AccessBridgeJavaEntryPoints::setCaretPosition(const jobject accessibleContext, int position) {
1496 
1497     jthrowable exception;
1498     BOOL result = FALSE;
1499 
1500     PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::setCaretPostion(%p position = %d):",
1501                      accessibleContext, position);
1502 
1503     if (setCaretPositionMethod != (jmethodID) 0) {
1504         result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject,
1505                                                  setCaretPositionMethod,
1506                                                  accessibleContext, position);
1507         EXCEPTION_CHECK("setCaretPostion - call to CallBooleanMethod()", FALSE);
1508         PrintDebugString("[ERROR]:     result = %d", result);
1509         return result;
1510     } else {
1511         PrintDebugString("[ERROR]: either jniEnv == 0 or setCaretPositionMethod == 0");
1512         return result;
1513     }
1514 }
1515 
1516 
1517 // -----------------------------------
1518 
1519 /**
1520  * getVersionInfo - returns the version string of the java.version property
1521  *                  and the AccessBridge.java version
1522  *
1523  */
1524 BOOL
getVersionInfo(AccessBridgeVersionInfo * info)1525 AccessBridgeJavaEntryPoints::getVersionInfo(AccessBridgeVersionInfo *info) {
1526     jstring js;
1527     const wchar_t *stringBytes;
1528     jthrowable exception;
1529     jsize length;
1530 
1531     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getVersionInfo():");
1532 
1533     if (getJavaVersionPropertyMethod != (jmethodID) 0) {
1534         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1535                                                 getJavaVersionPropertyMethod);
1536         EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallObjectMethod()", FALSE);
1537         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
1538         if (js != (jstring) 0) {
1539             length = jniEnv->GetStringLength(js);
1540             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1541             if (stringBytes == NULL) {
1542                 if (!jniEnv->ExceptionCheck()) {
1543                     PrintDebugString("[ERROR]:  *** Exception when getting JavaVersionProperty - call to GetStringChars");
1544                     jniEnv->ExceptionDescribe();
1545                     jniEnv->ExceptionClear();
1546                 }
1547                 return FALSE;
1548             }
1549             wcsncpy(info->bridgeJavaDLLVersion,
1550                     stringBytes,
1551                     sizeof(info->bridgeJavaDLLVersion)  / sizeof(wchar_t));
1552             info->bridgeJavaDLLVersion[length < (sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t)) ?
1553                             length : (sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1554             wcsncpy(info->VMversion,
1555                     stringBytes,
1556                     sizeof(info->VMversion)  / sizeof(wchar_t));
1557             info->VMversion[length < (sizeof(info->VMversion) / sizeof(wchar_t)) ?
1558                             length : (sizeof(info->VMversion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1559             wcsncpy(info->bridgeJavaClassVersion,
1560                     stringBytes,
1561                     sizeof(info->bridgeJavaClassVersion)  / sizeof(wchar_t));
1562             info->bridgeJavaClassVersion[length < (sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t)) ?
1563                                          length : (sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1564             wcsncpy(info->bridgeWinDLLVersion,
1565                     stringBytes,
1566                     sizeof(info->bridgeWinDLLVersion)  / sizeof(wchar_t));
1567             info->bridgeWinDLLVersion[length < (sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t)) ?
1568                                          length : (sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t))-2] = (wchar_t) 0;
1569             jniEnv->ReleaseStringChars(js, stringBytes);
1570             EXCEPTION_CHECK("Getting JavaVersionProperty - call to ReleaseStringChars()", FALSE);
1571             jniEnv->CallVoidMethod(accessBridgeObject,
1572                                    decrementReferenceMethod, js);
1573             EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallVoidMethod()", FALSE);
1574             wPrintDebugString(L"[INFO]:  Java version = %ls", info->VMversion);
1575             jniEnv->DeleteLocalRef(js);
1576             EXCEPTION_CHECK("Getting JavaVersionProperty - call to DeleteLocalRef()", FALSE);
1577         } else {
1578             PrintDebugString("[WARN]:   Java version is null.");
1579             info->VMversion[0] = (wchar_t) 0;
1580             return FALSE;
1581         }
1582     } else {
1583         PrintDebugString("[ERROR]:  either env == 0 or getJavaVersionPropertyMethod == 0");
1584         return FALSE;
1585     }
1586 
1587     return TRUE;
1588 }
1589 
1590 
1591 /*
1592  * Verifies the Java VM still exists and obj is an
1593  * instance of AccessibleText
1594  */
verifyAccessibleText(jobject obj)1595 BOOL AccessBridgeJavaEntryPoints::verifyAccessibleText(jobject obj) {
1596     JavaVM *vm;
1597     BOOL retval;
1598     jthrowable exception;
1599 
1600     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::verifyAccessibleText");
1601 
1602     if (jniEnv->GetJavaVM(&vm) != 0) {
1603         PrintDebugString("[ERROR]:  No Java VM");
1604         return FALSE;
1605     }
1606 
1607     if (obj == (jobject)0) {
1608         PrintDebugString("[ERROR]:  Null jobject");
1609         return FALSE;
1610     }
1611 
1612     // Copied from getAccessibleContextInfo
1613     if (getAccessibleTextFromContextMethod != (jmethodID) 0) {
1614         jobject returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
1615                                                            getAccessibleTextFromContextMethod,
1616                                                            (jobject)obj);
1617         EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE);
1618         PrintDebugString("[ERROR]:   AccessibleText = %p", returnedJobject);
1619         retval = returnedJobject != (jobject) 0;
1620         jniEnv->DeleteLocalRef(returnedJobject);
1621         EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE);
1622     } else {
1623         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextFromContextMethod == 0");
1624         return FALSE;
1625     }
1626     if (retval == FALSE) {
1627         PrintDebugString("[ERROR]:  jobject is not an AccessibleText");
1628     }
1629     return retval;
1630 }
1631 
1632 
1633 /********** AccessibleContext routines ***********************************/
1634 
1635 /**
1636  * getAccessibleContextAt - performs the Java method call:
1637  *   Accessible AccessBridge.getAccessibleContextAt(x, y)
1638  *
1639  * Note: this call explicitly goes through the AccessBridge,
1640  * so that it can keep a reference the returned jobject for the JavaVM.
1641  * You must explicity call INTreleaseJavaObject() when you are through using
1642  * the Accessible returned, to let the AccessBridge know it can release the
1643  * object, so that the can then garbage collect it.
1644  *
1645  */
1646 jobject
getAccessibleContextAt(jint x,jint y,jobject accessibleContext)1647 AccessBridgeJavaEntryPoints::getAccessibleContextAt(jint x, jint y, jobject accessibleContext) {
1648     jobject returnedAccessibleContext;
1649     jobject globalRef;
1650     jthrowable exception;
1651 
1652     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleContextAt(%d, %d, %p):",
1653                      x, y, accessibleContext);
1654 
1655     if (getAccessibleContextAtMethod != (jmethodID) 0) {
1656         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1657                                                              getAccessibleContextAtMethod,
1658                                                              x, y, accessibleContext);
1659         EXCEPTION_CHECK("Getting AccessibleContextAt - call to CallObjectMethod()", FALSE);
1660         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
1661         EXCEPTION_CHECK("Getting AccessibleContextAt - call to NewGlobalRef()", FALSE);
1662         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1663                          returnedAccessibleContext, globalRef);
1664         return globalRef;
1665     } else {
1666         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleContextAtMethod == 0");
1667         return (jobject) 0;
1668     }
1669 }
1670 
1671 /**
1672  * getAccessibleWithFocus - performs the Java method calls:
1673  *   Accessible Translator.getAccessible(SwingEventMonitor.getComponentWithFocus();
1674  *
1675  * Note: this call explicitly goes through the AccessBridge,
1676  * so that the AccessBridge can hide expected changes in how this functions
1677  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1678  * of this functionality may be built into the platform
1679  *
1680  */
1681 jobject
getAccessibleContextWithFocus()1682 AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus() {
1683     jobject returnedAccessibleContext;
1684     jobject globalRef;
1685     jthrowable exception;
1686 
1687     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus()");
1688 
1689     if (getAccessibleContextWithFocusMethod != (jmethodID) 0) {
1690         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
1691                                                              getAccessibleContextWithFocusMethod);
1692         EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to CallObjectMethod()", FALSE);
1693         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
1694         EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to NewGlobalRef()", FALSE);
1695         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
1696                          returnedAccessibleContext, globalRef);
1697         return globalRef;
1698     } else {
1699         PrintDebugString("[ERROR]:  either jniEnv == 0 or getAccessibleContextWithFocusMethod == 0");
1700         return (jobject) 0;
1701     }
1702 }
1703 
1704 /**
1705  * getAccessibleContextInfo - fills a struct with a bunch of information
1706  * contained in the Java Accessibility API
1707  *
1708  * Note: if the AccessibleContext parameter is bogus, this call will blow up
1709  *
1710  * Note: this call explicitly goes through the AccessBridge,
1711  * so that it can keep a reference the returned jobject for the JavaVM.
1712  * You must explicity call releaseJavaObject() when you are through using
1713  * the AccessibleContext returned, to let the AccessBridge know it can release the
1714  * object, so that the JavaVM can then garbage collect it.
1715  */
1716 BOOL
getAccessibleContextInfo(jobject accessibleContext,AccessibleContextInfo * info)1717 AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, AccessibleContextInfo *info) {
1718     jstring js;
1719     const wchar_t *stringBytes;
1720     jobject returnedJobject;
1721     jthrowable exception;
1722     jsize length;
1723 
1724     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleContextInfo(%p):", accessibleContext);
1725 
1726     ZeroMemory(info, sizeof(AccessibleContextInfo));
1727 
1728     if (accessibleContext == (jobject) 0) {
1729         PrintDebugString("[WARN]:  passed in AccessibleContext == null! (oops)");
1730         return (FALSE);
1731     }
1732 
1733     // Get the Accessible Name
1734     if (getAccessibleNameFromContextMethod != (jmethodID) 0) {
1735         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1736                                                 getAccessibleNameFromContextMethod,
1737                                                 accessibleContext);
1738         EXCEPTION_CHECK("Getting AccessibleName - call to CallObjectMethod()", FALSE);
1739         if (js != (jstring) 0) {
1740             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1741             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE);
1742             wcsncpy(info->name, stringBytes, (sizeof(info->name) / sizeof(wchar_t)));
1743             length = jniEnv->GetStringLength(js);
1744             info->name[length < (sizeof(info->name) / sizeof(wchar_t)) ?
1745                        length : (sizeof(info->name) / sizeof(wchar_t))-2] = (wchar_t) 0;
1746             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE);
1747             jniEnv->ReleaseStringChars(js, stringBytes);
1748             EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE);
1749             jniEnv->CallVoidMethod(accessBridgeObject,
1750                                    decrementReferenceMethod, js);
1751             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
1752             wPrintDebugString(L"[INFO]:   Accessible Name = %ls", info->name);
1753             jniEnv->DeleteLocalRef(js);
1754             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
1755         } else {
1756             PrintDebugString("[WARN]:   Accessible Name is null.");
1757             info->name[0] = (wchar_t) 0;
1758         }
1759     } else {
1760         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleNameFromContextMethod == 0");
1761         return FALSE;
1762     }
1763 
1764 
1765     // Get the Accessible Description
1766     if (getAccessibleDescriptionFromContextMethod != (jmethodID) 0) {
1767         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1768                                                 getAccessibleDescriptionFromContextMethod,
1769                                                 accessibleContext);
1770         EXCEPTION_CHECK("Getting AccessibleDescription - call to CallObjectMethod()", FALSE);
1771         if (js != (jstring) 0) {
1772             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1773             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE);
1774             wcsncpy(info->description, stringBytes, (sizeof(info->description) / sizeof(wchar_t)));
1775             length = jniEnv->GetStringLength(js);
1776             info->description[length < (sizeof(info->description) / sizeof(wchar_t)) ?
1777                               length : (sizeof(info->description) / sizeof(wchar_t))-2] = (wchar_t) 0;
1778             EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE);
1779             jniEnv->ReleaseStringChars(js, stringBytes);
1780             EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE);
1781             jniEnv->CallVoidMethod(accessBridgeObject,
1782                                    decrementReferenceMethod, js);
1783             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
1784             wPrintDebugString(L"[INFO]:   Accessible Description = %ls", info->description);
1785             jniEnv->DeleteLocalRef(js);
1786             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
1787         } else {
1788             PrintDebugString("[WARN]:   Accessible Description is null.");
1789             info->description[0] = (wchar_t) 0;
1790         }
1791     } else {
1792         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleDescriptionFromContextMethod == 0");
1793         return FALSE;
1794     }
1795 
1796 
1797     // Get the Accessible Role String
1798     if (getAccessibleRoleStringFromContextMethod != (jmethodID) 0) {
1799         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1800                                                 getAccessibleRoleStringFromContextMethod,
1801                                                 accessibleContext);
1802         EXCEPTION_CHECK("Getting AccessibleRole - call to CallObjectMethod()", FALSE);
1803         if (js != (jstring) 0) {
1804             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1805             EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringChars()", FALSE);
1806             wcsncpy(info->role, stringBytes, (sizeof(info->role) / sizeof(wchar_t)));
1807             length = jniEnv->GetStringLength(js);
1808             info->role[length < (sizeof(info->role) / sizeof(wchar_t)) ?
1809                        length : (sizeof(info->role) / sizeof(wchar_t))-2] = (wchar_t) 0;
1810             EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringLength()", FALSE);
1811             jniEnv->ReleaseStringChars(js, stringBytes);
1812             EXCEPTION_CHECK("Getting AccessibleRole - call to ReleaseStringChars()", FALSE);
1813             jniEnv->CallVoidMethod(accessBridgeObject,
1814                                    decrementReferenceMethod, js);
1815             EXCEPTION_CHECK("Getting AccessibleRole - call to CallVoidMethod()", FALSE);
1816             wPrintDebugString(L"[INFO]:   Accessible Role = %ls", info->role);
1817             jniEnv->DeleteLocalRef(js);
1818             EXCEPTION_CHECK("Getting AccessibleRole - call to DeleteLocalRef()", FALSE);
1819         } else {
1820             PrintDebugString("[WARN]:   Accessible Role is null.");
1821             info->role[0] = (wchar_t) 0;
1822         }
1823     } else {
1824         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleRoleStringFromContextMethod == 0");
1825         return FALSE;
1826     }
1827 
1828 
1829     // Get the Accessible Role String in the en_US locale
1830     if (getAccessibleRoleStringFromContext_en_USMethod != (jmethodID) 0) {
1831         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1832                                                 getAccessibleRoleStringFromContext_en_USMethod,
1833                                                 accessibleContext);
1834         EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallObjectMethod()", FALSE);
1835         if (js != (jstring) 0) {
1836             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1837             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringChars()", FALSE);
1838             wcsncpy(info->role_en_US, stringBytes, (sizeof(info->role_en_US) / sizeof(wchar_t)));
1839             length = jniEnv->GetStringLength(js);
1840             info->role_en_US[length < (sizeof(info->role_en_US) / sizeof(wchar_t)) ?
1841                              length : (sizeof(info->role_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0;
1842             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringLength()", FALSE);
1843             jniEnv->ReleaseStringChars(js, stringBytes);
1844             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to ReleaseStringChars()", FALSE);
1845             jniEnv->CallVoidMethod(accessBridgeObject,
1846                                    decrementReferenceMethod, js);
1847             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallVoidMethod()", FALSE);
1848             wPrintDebugString(L"[INFO]:   Accessible Role en_US = %ls", info->role_en_US);
1849             jniEnv->DeleteLocalRef(js);
1850             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to DeleteLocalRef()", FALSE);
1851         } else {
1852             PrintDebugString("[WARN]:   Accessible Role en_US is null.");
1853             info->role[0] = (wchar_t) 0;
1854         }
1855     } else {
1856         PrintDebugString("[ERROR]: either env == 0 or getAccessibleRoleStringFromContext_en_USMethod == 0");
1857         return FALSE;
1858     }
1859 
1860     // Get the Accessible States String
1861     if (getAccessibleStatesStringFromContextMethod != (jmethodID) 0) {
1862         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1863                                                 getAccessibleStatesStringFromContextMethod,
1864                                                 accessibleContext);
1865         EXCEPTION_CHECK("Getting AccessibleState - call to CallObjectMethod()", FALSE);
1866         if (js != (jstring) 0) {
1867             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1868             EXCEPTION_CHECK("Getting AccessibleState - call to GetStringChars()", FALSE);
1869             wcsncpy(info->states, stringBytes, (sizeof(info->states) / sizeof(wchar_t)));
1870             length = jniEnv->GetStringLength(js);
1871             info->states[length < (sizeof(info->states) / sizeof(wchar_t)) ?
1872                          length : (sizeof(info->states) / sizeof(wchar_t))-2] = (wchar_t) 0;
1873             EXCEPTION_CHECK("Getting AccessibleState - call to GetStringLength()", FALSE);
1874             jniEnv->ReleaseStringChars(js, stringBytes);
1875             EXCEPTION_CHECK("Getting AccessibleState - call to ReleaseStringChars()", FALSE);
1876             jniEnv->CallVoidMethod(accessBridgeObject,
1877                                    decrementReferenceMethod, js);
1878             EXCEPTION_CHECK("Getting AccessibleState - call to CallVoidMethod()", FALSE);
1879             wPrintDebugString(L"[INFO]:   Accessible States = %ls", info->states);
1880             jniEnv->DeleteLocalRef(js);
1881             EXCEPTION_CHECK("Getting AccessibleState - call to DeleteLocalRef()", FALSE);
1882         } else {
1883             PrintDebugString("[WARN]:   Accessible States is null.");
1884             info->states[0] = (wchar_t) 0;
1885         }
1886     } else {
1887         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleStatesStringFromContextMethod == 0");
1888         return FALSE;
1889     }
1890 
1891     // Get the Accessible States String in the en_US locale
1892     if (getAccessibleStatesStringFromContext_en_USMethod != (jmethodID) 0) {
1893         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
1894                                                 getAccessibleStatesStringFromContext_en_USMethod,
1895                                                 accessibleContext);
1896         EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallObjectMethod()", FALSE);
1897         if (js != (jstring) 0) {
1898             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
1899             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringChars()", FALSE);
1900             wcsncpy(info->states_en_US, stringBytes, (sizeof(info->states_en_US) / sizeof(wchar_t)));
1901             length = jniEnv->GetStringLength(js);
1902             info->states_en_US[length < (sizeof(info->states_en_US) / sizeof(wchar_t)) ?
1903                                length : (sizeof(info->states_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0;
1904             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringLength()", FALSE);
1905             jniEnv->ReleaseStringChars(js, stringBytes);
1906             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to ReleaseStringChars()", FALSE);
1907             jniEnv->CallVoidMethod(accessBridgeObject,
1908                                    decrementReferenceMethod, js);
1909             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallVoidMethod()", FALSE);
1910             wPrintDebugString(L"[INFO]:   Accessible States en_US = %ls", info->states_en_US);
1911             jniEnv->DeleteLocalRef(js);
1912             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to DeleteLocalRef()", FALSE);
1913         } else {
1914             PrintDebugString("[WARN]:   Accessible States en_US is null.");
1915             info->states[0] = (wchar_t) 0;
1916         }
1917     } else {
1918         PrintDebugString("[ERROR]: either env == 0 or getAccessibleStatesStringFromContext_en_USMethod == 0");
1919         return FALSE;
1920     }
1921 
1922 
1923     // Get the index in Parent
1924     if (getAccessibleIndexInParentFromContextMethod != (jmethodID) 0) {
1925         info->indexInParent = jniEnv->CallIntMethod(accessBridgeObject,
1926                                                     getAccessibleIndexInParentFromContextMethod,
1927                                                     accessibleContext);
1928         EXCEPTION_CHECK("Getting AccessibleIndexInParent - call to CallIntMethod()", FALSE);
1929         PrintDebugString("[INFO]:   Index in Parent = %d", info->indexInParent);
1930     } else {
1931         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleIndexInParentFromContextMethod == 0");
1932         return FALSE;
1933     }
1934 
1935 
1936     PrintDebugString("[INFO]: *** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %p ***",
1937                      jniEnv, accessBridgeObject, accessibleContext);
1938 
1939     // Get the children count
1940     if (getAccessibleChildrenCountFromContextMethod != (jmethodID) 0) {
1941         info->childrenCount = jniEnv->CallIntMethod(accessBridgeObject,
1942                                                     getAccessibleChildrenCountFromContextMethod,
1943                                                     accessibleContext);
1944         EXCEPTION_CHECK("Getting AccessibleChildrenCount - call to CallIntMethod()", FALSE);
1945         PrintDebugString("[INFO]:   Children count = %d", info->childrenCount);
1946     } else {
1947         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleChildrenCountFromContextMethod == 0");
1948         return FALSE;
1949     }
1950 
1951     PrintDebugString("[INFO]: *** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %X ***",
1952                      jniEnv, accessBridgeObject, accessibleContext);
1953 
1954 
1955     // Get the x coord
1956     if (getAccessibleXcoordFromContextMethod != (jmethodID) 0) {
1957         info->x = jniEnv->CallIntMethod(accessBridgeObject,
1958                                         getAccessibleXcoordFromContextMethod,
1959                                         accessibleContext);
1960         EXCEPTION_CHECK("Getting AccessibleXcoord - call to CallIntMethod()", FALSE);
1961         PrintDebugString("[INFO]:   X coord = %d", info->x);
1962     } else {
1963         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleXcoordFromContextMethod == 0");
1964         return FALSE;
1965     }
1966 
1967     PrintDebugString("[INFO]: *** jniEnv: %X; accessBridgeObject: %X; AccessibleContext: %p ***",
1968                      jniEnv, accessBridgeObject, accessibleContext);
1969 
1970 
1971     // Get the y coord
1972     if (getAccessibleYcoordFromContextMethod != (jmethodID) 0) {
1973         info->y = jniEnv->CallIntMethod(accessBridgeObject,
1974                                         getAccessibleYcoordFromContextMethod,
1975                                         accessibleContext);
1976         EXCEPTION_CHECK("Getting AccessibleYcoord - call to CallIntMethod()", FALSE);
1977         PrintDebugString("[INFO]:   Y coord = %d", info->y);
1978     } else {
1979         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleYcoordFromContextMethod == 0");
1980         return FALSE;
1981     }
1982 
1983     // Get the width
1984     if (getAccessibleWidthFromContextMethod != (jmethodID) 0) {
1985         info->width = jniEnv->CallIntMethod(accessBridgeObject,
1986                                             getAccessibleWidthFromContextMethod,
1987                                             accessibleContext);
1988         EXCEPTION_CHECK("Getting AccessibleWidth - call to CallIntMethod()", FALSE);
1989         PrintDebugString("[INFO]:   Width = %d", info->width);
1990     } else {
1991         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleWidthFromContextMethod == 0");
1992         return FALSE;
1993     }
1994 
1995     // Get the height
1996     if (getAccessibleHeightFromContextMethod != (jmethodID) 0) {
1997         info->height = jniEnv->CallIntMethod(accessBridgeObject,
1998                                              getAccessibleHeightFromContextMethod,
1999                                              accessibleContext);
2000         EXCEPTION_CHECK("Getting AccessibleHeight - call to CallIntMethod()", FALSE);
2001         PrintDebugString("[INFO]:   Height = %d", info->height);
2002     } else {
2003         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleHeightFromContextMethod == 0");
2004         return FALSE;
2005     }
2006 
2007     // Get the AccessibleComponent
2008     if (getAccessibleComponentFromContextMethod != (jmethodID) 0) {
2009         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2010                                                    getAccessibleComponentFromContextMethod,
2011                                                    accessibleContext);
2012         EXCEPTION_CHECK("Getting AccessibleComponent - call to CallObjectMethod()", FALSE);
2013         PrintDebugString("[INFO]:   AccessibleComponent = %p", returnedJobject);
2014         info->accessibleComponent = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2015         jniEnv->DeleteLocalRef(returnedJobject);
2016         EXCEPTION_CHECK("Getting AccessibleComponent - call to DeleteLocalRef()", FALSE);
2017     } else {
2018         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleComponentFromContextMethod == 0");
2019         return FALSE;
2020     }
2021 
2022     // Get the AccessibleAction
2023     if (getAccessibleActionFromContextMethod != (jmethodID) 0) {
2024         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2025                                                    getAccessibleActionFromContextMethod,
2026                                                    accessibleContext);
2027         EXCEPTION_CHECK("Getting AccessibleAction - call to CallObjectMethod()", FALSE);
2028         PrintDebugString("[INFO]:   AccessibleAction = %p", returnedJobject);
2029         info->accessibleAction = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2030         jniEnv->DeleteLocalRef(returnedJobject);
2031         EXCEPTION_CHECK("Getting AccessibleAction - call to DeleteLocalRef()", FALSE);
2032     } else {
2033         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleActionFromContextMethod == 0");
2034         return FALSE;
2035     }
2036 
2037     // Get the AccessibleSelection
2038     if (getAccessibleSelectionFromContextMethod != (jmethodID) 0) {
2039         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2040                                                    getAccessibleSelectionFromContextMethod,
2041                                                    accessibleContext);
2042         EXCEPTION_CHECK("Getting AccessibleSelection - call to CallObjectMethod()", FALSE);
2043         PrintDebugString("[INFO]:   AccessibleSelection = %p", returnedJobject);
2044         info->accessibleSelection = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2045         jniEnv->DeleteLocalRef(returnedJobject);
2046         EXCEPTION_CHECK("Getting AccessibleSelection - call to DeleteLocalRef()", FALSE);
2047     } else {
2048         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleSelectionFromContextMethod == 0");
2049         return FALSE;
2050     }
2051 
2052     // Get the AccessibleTable
2053     if (getAccessibleTableFromContextMethod != (jmethodID) 0) {
2054         PrintDebugString("[INFO]: ##### Calling getAccessibleTableFromContextMethod ...");
2055         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2056                                                    getAccessibleTableFromContextMethod,
2057                                                    accessibleContext);
2058         PrintDebugString("[INFO]: ##### ... Returned from getAccessibleTableFromContextMethod");
2059         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2060         PrintDebugString("[INFO]:   ##### AccessibleTable = %p", returnedJobject);
2061         if (returnedJobject != (jobject) 0) {
2062             info->accessibleInterfaces |= cAccessibleTableInterface;
2063         }
2064         jniEnv->DeleteLocalRef(returnedJobject);
2065         EXCEPTION_CHECK("##### Getting AccessibleTable - call to DeleteLocalRef()", FALSE);
2066 
2067         /*
2068           returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2069           getAccessibleTableFromContextMethod,
2070           AccessibleContext);
2071           PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod");
2072           EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2073           PrintDebugString("  ##### AccessibleTable = %X", returnedJobject);
2074           info->accessibleTable = returnedJobject;
2075         */
2076 
2077     } else {
2078         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableFromContextMethod == 0");
2079         return FALSE;
2080     }
2081 
2082     // Get the AccessibleText
2083     if (getAccessibleTextFromContextMethod != (jmethodID) 0) {
2084         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2085                                                    getAccessibleTextFromContextMethod,
2086                                                    accessibleContext);
2087         EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE);
2088         PrintDebugString("[INFO]:   AccessibleText = %p", returnedJobject);
2089         info->accessibleText = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
2090         jniEnv->DeleteLocalRef(returnedJobject);
2091         EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE);
2092     } else {
2093         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextFromContextMethod == 0");
2094         return FALSE;
2095     }
2096 
2097     // Get the AccessibleValue
2098     if (getAccessibleValueFromContextMethod != (jmethodID) 0) {
2099         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2100                                                    getAccessibleValueFromContextMethod,
2101                                                    accessibleContext);
2102         EXCEPTION_CHECK("Getting AccessibleValue - call to CallObjectMethod()", FALSE);
2103         PrintDebugString("[INFO]:   AccessibleValue = %p", returnedJobject);
2104         if (returnedJobject != (jobject) 0) {
2105             info->accessibleInterfaces |= cAccessibleValueInterface;
2106         }
2107         jniEnv->DeleteLocalRef(returnedJobject);
2108         EXCEPTION_CHECK("Getting AccessibleValue - call to DeleteLocalRef()", FALSE);
2109     } else {
2110         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleValueFromContextMethod == 0");
2111         return FALSE;
2112     }
2113 
2114     // FIX
2115     // get the AccessibleHypertext
2116     if (getAccessibleHypertextMethod != (jmethodID) 0 &&
2117         getAccessibleHyperlinkCountMethod != (jmethodID) 0 &&
2118         getAccessibleHyperlinkMethod != (jmethodID) 0 &&
2119         getAccessibleHyperlinkTextMethod != (jmethodID) 0 &&
2120         getAccessibleHyperlinkStartIndexMethod != (jmethodID) 0 &&
2121         getAccessibleHyperlinkEndIndexMethod != (jmethodID) 0) {
2122         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
2123                                                    getAccessibleHypertextMethod,
2124                                                    accessibleContext);
2125         EXCEPTION_CHECK("Getting AccessibleHypertext - call to CallObjectMethod()", FALSE);
2126         PrintDebugString("[INFO]:   AccessibleHypertext = %p",
2127                          returnedJobject);
2128         if (returnedJobject != (jobject) 0) {
2129             info->accessibleInterfaces |= cAccessibleHypertextInterface;
2130         }
2131         jniEnv->DeleteLocalRef(returnedJobject);
2132         EXCEPTION_CHECK("Getting AccessibleHypertext - call to DeleteLocalRef()", FALSE);
2133     }
2134 
2135     // set new accessibleInterfaces flags from old BOOL values
2136     if(info->accessibleComponent)
2137         info->accessibleInterfaces |= cAccessibleComponentInterface;
2138     if(info->accessibleAction)
2139         info->accessibleInterfaces |= cAccessibleActionInterface;
2140     if(info->accessibleSelection)
2141         info->accessibleInterfaces |= cAccessibleSelectionInterface;
2142     if(info->accessibleText)
2143         info->accessibleInterfaces |= cAccessibleTextInterface;
2144     // FIX END
2145 
2146     return TRUE;
2147 }
2148 
2149 /**
2150  * getAccessibleChildFromContext - performs the Java method call:
2151  *   AccessibleContext AccessBridge.getAccessibleChildContext(AccessibleContext)
2152  *
2153  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2154  *
2155  * Note: this call explicitly goes through the AccessBridge,
2156  * so that it can keep a reference the returned jobject for the JavaVM.
2157  * You must explicity call releaseJavaObject() when you are through using
2158  * the AccessibleContext returned, to let the AccessBridge know it can release the
2159  * object, so that the JavaVM can then garbage collect it.
2160  */
2161 jobject
getAccessibleChildFromContext(jobject accessibleContext,jint childIndex)2162 AccessBridgeJavaEntryPoints::getAccessibleChildFromContext(jobject accessibleContext, jint childIndex) {
2163     jobject returnedAccessibleContext;
2164     jobject globalRef;
2165     jthrowable exception;
2166 
2167     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleChildContext(%p, %d):",
2168                      accessibleContext, childIndex);
2169 
2170     if (getAccessibleChildFromContextMethod != (jmethodID) 0) {
2171         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
2172                                                              getAccessibleChildFromContextMethod,
2173                                                              accessibleContext, childIndex);
2174         EXCEPTION_CHECK("Getting AccessibleChild - call to CallObjectMethod()", FALSE);
2175         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2176         EXCEPTION_CHECK("Getting AccessibleChild - call to NewGlobalRef()", FALSE);
2177         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2178         EXCEPTION_CHECK("Getting AccessibleChild - call to DeleteLocalRef()", FALSE);
2179         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
2180                          returnedAccessibleContext, globalRef);
2181         return globalRef;
2182     } else {
2183         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleChildContextMethod == 0");
2184         return (jobject) 0;
2185     }
2186 }
2187 
2188 /**
2189  * getAccessibleParentFromContext - returns the AccessibleContext parent
2190  *
2191  */
2192 jobject
getAccessibleParentFromContext(jobject accessibleContext)2193 AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(jobject accessibleContext)
2194 {
2195     jobject returnedAccessibleContext;
2196     jobject globalRef;
2197     jthrowable exception;
2198 
2199     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(%p):", accessibleContext);
2200 
2201     if (getAccessibleParentFromContextMethod != (jmethodID) 0) {
2202         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
2203                                                              getAccessibleParentFromContextMethod,
2204                                                              accessibleContext);
2205         EXCEPTION_CHECK("Getting AccessibleParent - call to CallObjectMethod()", FALSE);
2206         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2207         EXCEPTION_CHECK("Getting AccessibleParent - call to NewGlobalRef()", FALSE);
2208         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2209         EXCEPTION_CHECK("Getting AccessibleParent - call to DeleteLocalRef()", FALSE);
2210         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
2211                          returnedAccessibleContext, globalRef);
2212         return globalRef;
2213     } else {
2214         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleParentFromContextMethod == 0");
2215         return (jobject) 0;
2216     }
2217 }
2218 
2219 
2220 /********** AccessibleTable routines **********************************/
2221 
2222 BOOL
getAccessibleTableInfo(jobject accessibleContext,AccessibleTableInfo * tableInfo)2223 AccessBridgeJavaEntryPoints::getAccessibleTableInfo(jobject accessibleContext,
2224                                                     AccessibleTableInfo *tableInfo) {
2225 
2226     jthrowable exception;
2227 
2228     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo(%p):",
2229                      accessibleContext);
2230 
2231     // get the table row count
2232     if (getAccessibleTableRowCountMethod != (jmethodID) 0) {
2233         tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject,
2234                                                     getAccessibleTableRowCountMethod,
2235                                                     accessibleContext);
2236         EXCEPTION_CHECK("##### Getting AccessibleTableRowCount - call to CallIntMethod()", FALSE);
2237         PrintDebugString("[INFO]:   ##### table row count = %d", tableInfo->rowCount);
2238     } else {
2239         PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowCountMethod == 0");
2240         return FALSE;
2241     }
2242 
2243     // get the table column count
2244     if (getAccessibleTableColumnCountMethod != (jmethodID) 0) {
2245         tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject,
2246                                                        getAccessibleTableColumnCountMethod,
2247                                                        accessibleContext);
2248         EXCEPTION_CHECK("Getting AccessibleTableColumnCount - call to CallIntMethod()", FALSE);
2249         PrintDebugString("[INFO]:   ##### table column count = %d", tableInfo->columnCount);
2250     } else {
2251         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnCountMethod == 0");
2252         return FALSE;
2253     }
2254 
2255     // get the AccessibleTable
2256     if (getAccessibleTableFromContextMethod != (jmethodID) 0) {
2257         PrintDebugString("[INFO]: ##### Calling getAccessibleTableFromContextMethod ...");
2258         jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject,
2259                                                     getAccessibleTableFromContextMethod,
2260                                                     accessibleContext);
2261         PrintDebugString("[INFO]: ##### ... Returned from getAccessibleTableFromContextMethod");
2262         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2263         jobject globalRef = jniEnv->NewGlobalRef(accTable);
2264         EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE);
2265         tableInfo->accessibleTable = (JOBJECT64)globalRef;
2266         PrintDebugString("[INFO]:   ##### accessibleTable = %p", globalRef);
2267     } else {
2268         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableFromContextMethod == 0");
2269         return FALSE;
2270     }
2271 
2272     // cache the AccessibleContext
2273     if (getContextFromAccessibleTableMethod != (jmethodID) 0) {
2274         PrintDebugString("[INFO]: ##### Calling getContextFromAccessibleTable Method ...");
2275         jobject ac = jniEnv->CallObjectMethod(accessBridgeObject,
2276                                               getContextFromAccessibleTableMethod,
2277                                               accessibleContext);
2278         PrintDebugString("[INFO]: ##### ... Returned from getContextFromAccessibleTable Method");
2279         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
2280         jobject globalRef = jniEnv->NewGlobalRef(ac);
2281         EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE);
2282         tableInfo->accessibleContext = (JOBJECT64)globalRef;
2283         PrintDebugString("[INFO]:   ##### accessibleContext = %p", globalRef);
2284     } else {
2285         PrintDebugString("[ERROR]: either env == 0 or getContextFromAccessibleTable Method == 0");
2286         return FALSE;
2287     }
2288 
2289     // FIX - set unused elements
2290     tableInfo->caption = NULL;
2291     tableInfo->summary = NULL;
2292 
2293     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo succeeded");
2294     return TRUE;
2295 }
2296 
2297 BOOL
getAccessibleTableCellInfo(jobject accessibleTable,jint row,jint column,AccessibleTableCellInfo * tableCellInfo)2298 AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(jobject accessibleTable, jint row, jint column,
2299                                                         AccessibleTableCellInfo *tableCellInfo) {
2300 
2301     jthrowable exception;
2302 
2303     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(%p): row=%d, column=%d",
2304                      accessibleTable, row, column);
2305 
2306     // FIX
2307     ZeroMemory(tableCellInfo, sizeof(AccessibleTableCellInfo));
2308     tableCellInfo->row = row;
2309     tableCellInfo->column = column;
2310     // FIX END
2311 
2312     // get the table cell index
2313     if (getAccessibleTableCellIndexMethod != (jmethodID) 0) {
2314         tableCellInfo->index = jniEnv->CallIntMethod(accessBridgeObject,
2315                                                      getAccessibleTableCellIndexMethod,
2316                                                      accessibleTable, row, column);
2317         EXCEPTION_CHECK("##### Getting AccessibleTableCellIndex - call to CallIntMethod()", FALSE);
2318         PrintDebugString("[INFO]:   ##### table cell index = %d", tableCellInfo->index);
2319     } else {
2320         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellIndexMethod == 0");
2321         return FALSE;
2322     }
2323 
2324     // get the table cell row extent
2325     if (getAccessibleTableCellRowExtentMethod != (jmethodID) 0) {
2326         tableCellInfo->rowExtent = jniEnv->CallIntMethod(accessBridgeObject,
2327                                                          getAccessibleTableCellRowExtentMethod,
2328                                                          accessibleTable, row, column);
2329         EXCEPTION_CHECK("##### Getting AccessibleTableCellRowExtentCount - call to CallIntMethod()", FALSE);
2330         PrintDebugString("[INFO]:   ##### table cell row extent = %d", tableCellInfo->rowExtent);
2331     } else {
2332         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellRowExtentMethod == 0");
2333         return FALSE;
2334     }
2335 
2336     // get the table cell column extent
2337     if (getAccessibleTableCellColumnExtentMethod != (jmethodID) 0) {
2338         tableCellInfo->columnExtent = jniEnv->CallIntMethod(accessBridgeObject,
2339                                                             getAccessibleTableCellColumnExtentMethod,
2340                                                             accessibleTable, row, column);
2341         EXCEPTION_CHECK("##### Getting AccessibleTableCellColumnExtentCount - call to CallIntMethod()", FALSE);
2342         PrintDebugString("[INFO]:  ##### table cell column extent = %d", tableCellInfo->columnExtent);
2343     } else {
2344         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellColumnExtentMethod == 0");
2345         return FALSE;
2346     }
2347 
2348     // get whether the table cell is selected
2349     if (isAccessibleTableCellSelectedMethod != (jmethodID) 0) {
2350         tableCellInfo->isSelected = jniEnv->CallBooleanMethod(accessBridgeObject,
2351                                                               isAccessibleTableCellSelectedMethod,
2352                                                               accessibleTable, row, column);
2353         EXCEPTION_CHECK("##### Getting isAccessibleTableCellSelected - call to CallBooleanMethod()", FALSE);
2354         PrintDebugString("[INFO]:   ##### table cell isSelected = %d", tableCellInfo->isSelected);
2355     } else {
2356         PrintDebugString("[ERROR]: either env == 0 or isAccessibleTableCellSelectedMethod == 0");
2357         return FALSE;
2358     }
2359 
2360     // get the table cell AccessibleContext
2361     if (getAccessibleTableCellAccessibleContextMethod != (jmethodID) 0) {
2362         jobject tableCellAC = jniEnv->CallObjectMethod(accessBridgeObject,
2363                                                        getAccessibleTableCellAccessibleContextMethod,
2364                                                        accessibleTable, row, column);
2365         EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to CallObjectMethod()", FALSE);
2366         jobject globalRef = jniEnv->NewGlobalRef(tableCellAC);
2367         EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to NewGlobalRef()", FALSE);
2368         tableCellInfo->accessibleContext = (JOBJECT64)globalRef;
2369         PrintDebugString("[INFO]:   ##### table cell AccessibleContext = %p", globalRef);
2370     } else {
2371         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellAccessibleContextMethod == 0");
2372         return FALSE;
2373     }
2374 
2375     PrintDebugString("[INFO]:  ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo succeeded");
2376     return TRUE;
2377 }
2378 
2379 BOOL
getAccessibleTableRowHeader(jobject acParent,AccessibleTableInfo * tableInfo)2380 AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(jobject acParent, AccessibleTableInfo *tableInfo) {
2381 
2382     jthrowable exception;
2383 
2384     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(%p):",
2385                      acParent);
2386 
2387     // get the header row count
2388     if (getAccessibleTableRowHeaderRowCountMethod != (jmethodID) 0) {
2389         tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject,
2390                                                     getAccessibleTableRowHeaderRowCountMethod,
2391                                                     acParent);
2392         EXCEPTION_CHECK("##### Getting AccessibleTableRowHeaderRowCount - call to CallIntMethod()", FALSE);
2393         PrintDebugString("[INFO]:   ##### table row count = %d", tableInfo->rowCount);
2394     } else {
2395         PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowHeaderRowCountMethod == 0");
2396         return FALSE;
2397     }
2398 
2399     // get the header column count
2400     if (getAccessibleTableRowHeaderColumnCountMethod != (jmethodID) 0) {
2401         tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject,
2402                                                        getAccessibleTableRowHeaderColumnCountMethod,
2403                                                        acParent);
2404         EXCEPTION_CHECK("Getting AccessibleTableRowHeaderColumnCount - call to CallIntMethod()", FALSE);
2405         PrintDebugString("[INFO]:   ##### table column count = %d", tableInfo->columnCount);
2406     } else {
2407         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowHeaderColumnCountMethod == 0");
2408         return FALSE;
2409     }
2410 
2411     // get the header AccessibleTable
2412     if (getAccessibleTableRowHeaderMethod != (jmethodID) 0) {
2413         jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject,
2414                                                     getAccessibleTableRowHeaderMethod,
2415                                                     acParent);
2416         EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to CallObjectMethod()", FALSE);
2417         jobject globalRef = jniEnv->NewGlobalRef(accTable);
2418         EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to NewGlobalRef()", FALSE);
2419         tableInfo->accessibleTable = (JOBJECT64)globalRef;
2420         PrintDebugString("[INFO]:   ##### row header AccessibleTable = %p", globalRef);
2421     } else {
2422         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowHeaderMethod == 0");
2423         return FALSE;
2424     }
2425 
2426     // FIX - set unused elements
2427     tableInfo->caption = NULL;
2428     tableInfo->summary = NULL;
2429     tableInfo->accessibleContext = NULL;
2430 
2431     PrintDebugString("[INFO]:   ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader succeeded");
2432     return TRUE;
2433 }
2434 
2435 BOOL
getAccessibleTableColumnHeader(jobject acParent,AccessibleTableInfo * tableInfo)2436 AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(jobject acParent, AccessibleTableInfo *tableInfo) {
2437     jthrowable exception;
2438 
2439     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(%p):",
2440                      acParent);
2441 
2442     // get the header row count
2443     if (getAccessibleTableColumnHeaderRowCountMethod != (jmethodID) 0) {
2444         tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject,
2445                                                     getAccessibleTableColumnHeaderRowCountMethod,
2446                                                     acParent);
2447         EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeaderRowCount - call to CallIntMethod()", FALSE);
2448         PrintDebugString("[INFO]:   ##### table row count = %d", tableInfo->rowCount);
2449     } else {
2450         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleColumnHeaderRowCountMethod == 0");
2451         return FALSE;
2452     }
2453 
2454     // get the header column count
2455     if (getAccessibleTableColumnHeaderColumnCountMethod != (jmethodID) 0) {
2456         tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject,
2457                                                        getAccessibleTableColumnHeaderColumnCountMethod,
2458                                                        acParent);
2459         EXCEPTION_CHECK("Getting AccessibleTableColumnHeaderColumnCount - call to CallIntMethod()", FALSE);
2460         PrintDebugString("[INFO]:   ##### table column count = %d", tableInfo->columnCount);
2461     } else {
2462         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnHeaderColumnCountMethod == 0");
2463         return FALSE;
2464     }
2465     // get the header AccessibleTable
2466     if (getAccessibleTableColumnHeaderMethod != (jmethodID) 0) {
2467         jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject,
2468                                                     getAccessibleTableColumnHeaderMethod,
2469                                                     acParent);
2470         EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to CallObjectMethod()", FALSE);
2471         jobject globalRef = jniEnv->NewGlobalRef(accTable);
2472         EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to NewGlobalRef()", FALSE);
2473         tableInfo->accessibleTable = (JOBJECT64)globalRef;
2474         PrintDebugString("[INFO]:   ##### column header AccessibleTable = %p", globalRef);
2475     } else {
2476         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnHeaderMethod == 0");
2477         return FALSE;
2478     }
2479 
2480     // FIX - set unused elements
2481     tableInfo->caption = NULL;
2482     tableInfo->summary = NULL;
2483     tableInfo->accessibleContext = NULL;
2484 
2485     PrintDebugString("[INFO]:   ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader succeeded");
2486     return TRUE;
2487 }
2488 
2489 jobject
getAccessibleTableRowDescription(jobject acParent,jint row)2490 AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(jobject acParent, jint row) {
2491 
2492     jobject returnedAccessibleContext;
2493     jobject globalRef;
2494     jthrowable exception;
2495 
2496     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(%p):",
2497                      acParent);
2498 
2499     if (getAccessibleTableRowDescriptionMethod != (jmethodID) 0) {
2500         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
2501                                                              getAccessibleTableRowDescriptionMethod,
2502                                                              acParent, row);
2503         EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to CallObjectMethod()", FALSE);
2504         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2505         EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to NewGlobalRef()", FALSE);
2506         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2507         EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to DeleteLocalRef()", FALSE);
2508         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
2509                          returnedAccessibleContext, globalRef);
2510         return globalRef;
2511     } else {
2512         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowDescriptionMethod == 0");
2513         return (jobject) 0;
2514     }
2515 }
2516 
2517 jobject
getAccessibleTableColumnDescription(jobject acParent,jint column)2518 AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(jobject acParent, jint column) {
2519 
2520     jobject returnedAccessibleContext;
2521     jobject globalRef;
2522     jthrowable exception;
2523 
2524     PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(%p):",
2525                      acParent);
2526 
2527     if (getAccessibleTableColumnDescriptionMethod != (jmethodID) 0) {
2528         returnedAccessibleContext = jniEnv->CallObjectMethod(
2529                                                              accessBridgeObject,
2530                                                              getAccessibleTableColumnDescriptionMethod,
2531                                                              acParent, column);
2532         EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to CallObjectMethod()", FALSE);
2533         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
2534         EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to NewGlobalRef()", FALSE);
2535         jniEnv->DeleteLocalRef(returnedAccessibleContext);
2536         EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to DeleteLocalRef()", FALSE);
2537         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
2538                          returnedAccessibleContext, globalRef);
2539         return globalRef;
2540     } else {
2541         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnDescriptionMethod == 0");
2542         return (jobject) 0;
2543     }
2544 }
2545 
2546 jint
getAccessibleTableRowSelectionCount(jobject accessibleTable)2547 AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(jobject accessibleTable) {
2548 
2549     jthrowable exception;
2550     jint count;
2551 
2552     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(%p)",
2553                      accessibleTable);
2554 
2555     // Get the table row selection count
2556     if (getAccessibleTableRowSelectionCountMethod != (jmethodID) 0) {
2557         count = jniEnv->CallIntMethod(accessBridgeObject,
2558                                       getAccessibleTableRowSelectionCountMethod,
2559                                       accessibleTable);
2560         EXCEPTION_CHECK("##### Getting AccessibleTableRowSelectionCount - call to CallIntMethod()", FALSE);
2561         PrintDebugString("[INFO]:   ##### table row selection count = %d", count);
2562         return count;
2563     } else {
2564         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowSelectionCountMethod == 0");
2565         return 0;
2566     }
2567 
2568     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount failed");
2569     return 0;
2570 }
2571 
2572 BOOL
isAccessibleTableRowSelected(jobject accessibleTable,jint row)2573 AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(jobject accessibleTable, jint row) {
2574     jthrowable exception;
2575     BOOL result;
2576 
2577     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(%p, %d)",
2578                      accessibleTable, row);
2579 
2580     if (isAccessibleTableRowSelectedMethod != (jmethodID) 0) {
2581         result = jniEnv->CallBooleanMethod(accessBridgeObject,
2582                                            isAccessibleTableRowSelectedMethod,
2583                                            accessibleTable, row);
2584         EXCEPTION_CHECK("##### Getting isAccessibleTableRowSelected - call to CallBooleanMethod()", FALSE);
2585         PrintDebugString("[INFO]:   ##### table row isSelected = %d", result);
2586         return result;
2587     } else {
2588         PrintDebugString("[ERROR]: either env == 0 or isAccessibleTableRowSelectedMethod == 0");
2589         return FALSE;
2590     }
2591 
2592     PrintDebugString("[ERROR]:  AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected failed");
2593     return FALSE;
2594 }
2595 
2596 BOOL
getAccessibleTableRowSelections(jobject accessibleTable,jint count,jint * selections)2597 AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(jobject accessibleTable, jint count,
2598                                                              jint *selections) {
2599 
2600     jthrowable exception;
2601 
2602     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(%p, %d %p)",
2603                      accessibleTable, count, selections);
2604 
2605     if (getAccessibleTableRowSelectionsMethod == (jmethodID) 0) {
2606         return FALSE;
2607     }
2608     // Get the table row selections
2609     for (int i = 0; i < count; i++) {
2610 
2611         selections[i] = jniEnv->CallIntMethod(accessBridgeObject,
2612                                               getAccessibleTableRowSelectionsMethod,
2613                                               accessibleTable,
2614                                               i);
2615         EXCEPTION_CHECK("##### Getting AccessibleTableRowSelections - call to CallIntMethod()", FALSE);
2616         PrintDebugString("[INFO]:   ##### table row selection[%d] = %d", i, selections[i]);
2617     }
2618 
2619     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections succeeded");
2620     return TRUE;
2621 }
2622 
2623 
2624 jint
getAccessibleTableColumnSelectionCount(jobject accessibleTable)2625 AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(jobject accessibleTable) {
2626 
2627     jthrowable exception;
2628     jint count;
2629 
2630     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(%p)",
2631                      accessibleTable);
2632 
2633     // Get the table column selection count
2634     if (getAccessibleTableColumnSelectionCountMethod != (jmethodID) 0) {
2635         count = jniEnv->CallIntMethod(accessBridgeObject,
2636                                       getAccessibleTableColumnSelectionCountMethod,
2637                                       accessibleTable);
2638         EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelectionCount - call to CallIntMethod()", FALSE);
2639         PrintDebugString("[INFO]:   ##### table column selection count = %d", count);
2640         return count;
2641     } else {
2642         PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowCountMethod == 0");
2643         return 0;
2644     }
2645 
2646     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount failed");
2647     return 0;
2648 }
2649 
2650 BOOL
isAccessibleTableColumnSelected(jobject accessibleTable,jint column)2651 AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(jobject accessibleTable, jint column) {
2652     jthrowable exception;
2653     BOOL result;
2654 
2655     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(%p, %d)",
2656                      accessibleTable, column);
2657 
2658     if (isAccessibleTableColumnSelectedMethod != (jmethodID) 0) {
2659         result = jniEnv->CallBooleanMethod(accessBridgeObject,
2660                                            isAccessibleTableColumnSelectedMethod,
2661                                            accessibleTable, column);
2662         EXCEPTION_CHECK("##### Getting isAccessibleTableColumnSelected - call to CallBooleanMethod()", FALSE);
2663         PrintDebugString("[INFO]:   ##### table column isSelected = %d", result);
2664         return result;
2665     } else {
2666         PrintDebugString("[ERROR]:  either env == 0 or isAccessibleTableColumnSelectedMethod == 0");
2667         return FALSE;
2668     }
2669 
2670     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected failed");
2671     return FALSE;
2672 }
2673 
2674 BOOL
getAccessibleTableColumnSelections(jobject accessibleTable,jint count,jint * selections)2675 AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(jobject accessibleTable, jint count,
2676                                                                 jint *selections) {
2677     jthrowable exception;
2678 
2679     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(%p, %d, %p)",
2680                      accessibleTable, count, selections);
2681 
2682     if (getAccessibleTableColumnSelectionsMethod == (jmethodID) 0) {
2683         return FALSE;
2684     }
2685     // Get the table column selections
2686     for (int i = 0; i < count; i++) {
2687 
2688         selections[i] = jniEnv->CallIntMethod(accessBridgeObject,
2689                                               getAccessibleTableColumnSelectionsMethod,
2690                                               accessibleTable,
2691                                               i);
2692         EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelections - call to CallIntMethod()", FALSE);
2693         PrintDebugString("[INFO]:   ##### table Column selection[%d] = %d", i, selections[i]);
2694     }
2695 
2696     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections succeeded");
2697     return TRUE;
2698 }
2699 
2700 
2701 jint
getAccessibleTableRow(jobject accessibleTable,jint index)2702 AccessBridgeJavaEntryPoints::getAccessibleTableRow(jobject accessibleTable, jint index) {
2703     jthrowable exception;
2704     jint result;
2705 
2706     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow(%p, index=%d)",
2707                      accessibleTable, index);
2708 
2709     if (getAccessibleTableRowMethod != (jmethodID) 0) {
2710         result = jniEnv->CallIntMethod(accessBridgeObject,
2711                                        getAccessibleTableRowMethod,
2712                                        accessibleTable, index);
2713         EXCEPTION_CHECK("##### Getting AccessibleTableRow - call to CallIntMethod()", FALSE);
2714         PrintDebugString("[INFO]:   ##### table row = %d", result);
2715         return result;
2716     } else {
2717         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowMethod == 0");
2718         return -1;
2719     }
2720 
2721     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow failed");
2722     return -1;
2723 }
2724 
2725 jint
getAccessibleTableColumn(jobject accessibleTable,jint index)2726 AccessBridgeJavaEntryPoints::getAccessibleTableColumn(jobject accessibleTable, jint index) {
2727     jthrowable exception;
2728     jint result;
2729 
2730     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn(%p, index=%d)",
2731                      accessibleTable, index);
2732 
2733     if (getAccessibleTableColumnMethod != (jmethodID) 0) {
2734         result = jniEnv->CallIntMethod(accessBridgeObject,
2735                                        getAccessibleTableColumnMethod,
2736                                        accessibleTable, index);
2737         EXCEPTION_CHECK("##### Getting AccessibleTableColumn - call to CallIntMethod()", FALSE);
2738         PrintDebugString("[INFO]:   ##### table column = %d", result);
2739         return result;
2740     } else {
2741         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnMethod == 0");
2742         return -1;
2743     }
2744 
2745     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn failed");
2746     return -1;
2747 }
2748 
2749 jint
getAccessibleTableIndex(jobject accessibleTable,jint row,jint column)2750 AccessBridgeJavaEntryPoints::getAccessibleTableIndex(jobject accessibleTable, jint row, jint column) {
2751     jthrowable exception;
2752     jint result;
2753 
2754     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex(%p, row=%d, col=%d)",
2755                      accessibleTable, row, column);
2756 
2757     if (getAccessibleTableIndexMethod != (jmethodID) 0) {
2758         result = jniEnv->CallIntMethod(accessBridgeObject,
2759                                        getAccessibleTableIndexMethod,
2760                                        accessibleTable, row, column);
2761         EXCEPTION_CHECK("##### Getting getAccessibleTableIndex - call to CallIntMethod()", FALSE);
2762         PrintDebugString("[INFO]:   ##### table index = %d", result);
2763         return result;
2764     } else {
2765         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableIndexMethod == 0");
2766         return -1;
2767     }
2768 
2769     PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex failed");
2770     return -1;
2771 }
2772 
2773 /********** end AccessibleTable routines ******************************/
2774 
2775 
2776 /********** begin AccessibleRelationSet routines **********************/
2777 
2778 BOOL
getAccessibleRelationSet(jobject accessibleContext,AccessibleRelationSetInfo * relationSet)2779 AccessBridgeJavaEntryPoints::getAccessibleRelationSet(jobject accessibleContext,
2780                                                       AccessibleRelationSetInfo *relationSet) {
2781 
2782     jthrowable exception;
2783     const wchar_t *stringBytes;
2784     jsize length;
2785 
2786     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet(%p, %p)",
2787                      accessibleContext, relationSet);
2788 
2789     if (getAccessibleRelationCountMethod == (jmethodID) 0 ||
2790         getAccessibleRelationKeyMethod == (jmethodID) 0 ||
2791         getAccessibleRelationTargetCountMethod == (jmethodID) 0 ||
2792         getAccessibleRelationTargetMethod == (jmethodID) 0) {
2793         return FALSE;
2794     }
2795 
2796     // Get the relations set count
2797     relationSet->relationCount = jniEnv->CallIntMethod(accessBridgeObject,
2798                                                        getAccessibleRelationCountMethod,
2799                                                        accessibleContext);
2800     EXCEPTION_CHECK("##### Getting AccessibleRelationCount - call to CallIntMethod()", FALSE);
2801     PrintDebugString("[INFO]:   ##### AccessibleRelation count = %d", relationSet->relationCount);
2802 
2803 
2804     // Get the relation set
2805     for (int i = 0; i < relationSet->relationCount && i < MAX_RELATIONS; i++) {
2806 
2807         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
2808                                                        getAccessibleRelationKeyMethod,
2809                                                        accessibleContext,
2810                                                        i);
2811 
2812         EXCEPTION_CHECK("Getting AccessibleRelationKey - call to CallObjectMethod()", FALSE);
2813         if (js != (jstring) 0) {
2814             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
2815             EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringChars()", FALSE);
2816             wcsncpy(relationSet->relations[i].key, stringBytes, (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t)));
2817             length = jniEnv->GetStringLength(js);
2818             relationSet->relations[i].key [length < (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t)) ?
2819                                            length : (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t))-2] = (wchar_t) 0;
2820             EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringLength()", FALSE);
2821             jniEnv->ReleaseStringChars(js, stringBytes);
2822             EXCEPTION_CHECK("Getting AccessibleRelation key - call to ReleaseStringChars()", FALSE);
2823             // jniEnv->CallVoidMethod(accessBridgeObject,
2824             //                        decrementReferenceMethod, js);
2825             //EXCEPTION_CHECK("Getting AccessibleRelation key - call to CallVoidMethod()", FALSE);
2826             PrintDebugString("[INFO]: ##### AccessibleRelation key = %ls", relationSet->relations[i].key );
2827             jniEnv->DeleteLocalRef(js);
2828             EXCEPTION_CHECK("Getting AccessibleRelation key - call to DeleteLocalRef()", FALSE);
2829         } else {
2830             PrintDebugString("[WARN]:   AccessibleRelation key is null.");
2831             relationSet->relations[i].key [0] = (wchar_t) 0;
2832         }
2833 
2834         relationSet->relations[i].targetCount = jniEnv->CallIntMethod(accessBridgeObject,
2835                                                                       getAccessibleRelationTargetCountMethod,
2836                                                                       accessibleContext,
2837                                                                       i);
2838 
2839         for (int j = 0; j < relationSet->relations[i].targetCount && j < MAX_RELATION_TARGETS; j++) {
2840             jobject target = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleRelationTargetMethod,
2841                                                       accessibleContext, i, j);
2842             EXCEPTION_CHECK("Getting AccessibleRelationSet - call to CallObjectMethod()", FALSE);
2843             jobject globalRef = jniEnv->NewGlobalRef(target);
2844             EXCEPTION_CHECK("Getting AccessibleRelationSet - call to NewGlobalRef()", FALSE);
2845             relationSet->relations[i].targets[j] = (JOBJECT64)globalRef;
2846             PrintDebugString("[INFO]:   relation set item: %p", globalRef);
2847         }
2848     }
2849 
2850     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet succeeded");
2851     return TRUE;
2852 }
2853 
2854 
2855 /********** end AccessibleRelationSet routines ************************/
2856 
2857 
2858 /********** begin AccessibleHypertext routines **********************/
2859 
2860 BOOL
getAccessibleHypertext(jobject accessibleContext,AccessibleHypertextInfo * hypertext)2861 AccessBridgeJavaEntryPoints::getAccessibleHypertext(jobject accessibleContext,
2862                                                     AccessibleHypertextInfo *hypertext) {
2863 
2864     jthrowable exception;
2865     const wchar_t *stringBytes;
2866     jsize length;
2867 
2868     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext(%p, %p)",
2869                      accessibleContext, hypertext);
2870 
2871     // get the AccessibleHypertext
2872     jobject ht = jniEnv->CallObjectMethod(accessBridgeObject,
2873                                           getAccessibleHypertextMethod,
2874                                           accessibleContext);
2875     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to CallObjectMethod()", FALSE);
2876     jobject globalRef = jniEnv->NewGlobalRef(ht);
2877     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE);
2878     hypertext->accessibleHypertext = (JOBJECT64)globalRef;
2879     PrintDebugString("[INFO]:   ##### AccessibleHypertext = %p", globalRef);
2880 
2881     if (hypertext->accessibleHypertext == 0) {
2882         PrintDebugString("[WARN]:   ##### null AccessibleHypertext; returning FALSE");
2883         return false;
2884     }
2885 
2886     // get the hyperlink count
2887     hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject,
2888                                                  getAccessibleHyperlinkCountMethod,accessibleContext);
2889 
2890     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE);
2891     PrintDebugString("[INFO]:   ##### hyperlink count = %d", hypertext->linkCount);
2892 
2893 
2894     // get the hypertext links
2895     for (int i = 0; i < hypertext->linkCount && i < MAX_HYPERLINKS; i++) {
2896 
2897         // get the hyperlink
2898         jobject hl = jniEnv->CallObjectMethod(accessBridgeObject,
2899                                               getAccessibleHyperlinkMethod,
2900                                               accessibleContext,
2901                                               i);
2902         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE);
2903         jobject globalRef = jniEnv->NewGlobalRef(hl);
2904         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
2905         hypertext->links[i].accessibleHyperlink = (JOBJECT64)globalRef;
2906         PrintDebugString("[INFO]:   ##### AccessibleHyperlink = %p", globalRef);
2907 
2908         // get the hyperlink text
2909         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
2910                                                        getAccessibleHyperlinkTextMethod,
2911                                                        hypertext->links[i].accessibleHyperlink,
2912                                                        i);
2913 
2914         EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE);
2915         if (js != (jstring) 0) {
2916             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
2917             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE);
2918             wcsncpy(hypertext->links[i].text, stringBytes, (sizeof(hypertext->links[i].text) / sizeof(wchar_t)));
2919             length = jniEnv->GetStringLength(js);
2920             if (length >= (sizeof(hypertext->links[i].text) / sizeof(wchar_t))) {
2921                 length = (sizeof(hypertext->links[i].text) / sizeof(wchar_t)) - 2;
2922             }
2923             hypertext->links[i].text[length] = (wchar_t) 0;
2924             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE);
2925             jniEnv->ReleaseStringChars(js, stringBytes);
2926             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE);
2927             // jniEnv->CallVoidMethod(accessBridgeObject,
2928             //                                     decrementReferenceMethod, js);
2929             //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
2930             PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", hypertext->links[i].text );
2931             jniEnv->DeleteLocalRef(js);
2932             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
2933         } else {
2934             PrintDebugString("[WARN]:   AccessibleHyperlink text is null.");
2935             hypertext->links[i].text[0] = (wchar_t) 0;
2936         }
2937 
2938         hypertext->links[i].startIndex = jniEnv->CallIntMethod(accessBridgeObject,
2939                                                                getAccessibleHyperlinkStartIndexMethod,
2940                                                                hypertext->links[i].accessibleHyperlink,
2941                                                                i);
2942         EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
2943         PrintDebugString("[INFO]:   ##### hyperlink start index = %d", hypertext->links[i].startIndex);
2944 
2945 
2946         hypertext->links[i].endIndex = jniEnv->CallIntMethod(accessBridgeObject,
2947                                                              getAccessibleHyperlinkEndIndexMethod,
2948                                                              hypertext->links[i].accessibleHyperlink,
2949                                                              i);
2950         EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
2951         PrintDebugString("[INFO]:   ##### hyperlink end index = %d", hypertext->links[i].endIndex);
2952 
2953     }
2954 
2955     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext succeeded");
2956     return TRUE;
2957 }
2958 
2959 /*
2960  * Activates an AccessibleHyperlink
2961  */
2962 BOOL
activateAccessibleHyperlink(jobject accessibleContext,jobject accessibleHyperlink)2963 AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(jobject accessibleContext,
2964                                                          jobject accessibleHyperlink) {
2965 
2966     jthrowable exception;
2967     BOOL returnVal;
2968 
2969     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(%p, %p):",
2970                      accessibleContext, accessibleHyperlink);
2971 
2972     if (activateAccessibleHyperlinkMethod != (jmethodID) 0) {
2973         returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, activateAccessibleHyperlinkMethod,
2974                                                      accessibleContext, accessibleHyperlink);
2975         EXCEPTION_CHECK("activateAccessibleHyperlink - call to CallBooleanMethod()", FALSE);
2976         return returnVal;
2977     } else {
2978         PrintDebugString("[ERROR]: either jniEnv == 0 or activateAccessibleHyperlinkMethod == 0");
2979         return FALSE;
2980     }
2981 }
2982 
2983 
2984 /*
2985  * This method is used to iterate through the hyperlinks in a component.  It
2986  * returns hypertext information for a component starting at hyperlink index
2987  * nStartIndex.  No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will
2988  * be returned for each call to this method.
2989  * returns FALSE on error.
2990  */
2991 BOOL
getAccessibleHypertextExt(const jobject accessibleContext,const jint nStartIndex,AccessibleHypertextInfo * hypertext)2992 AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(const jobject accessibleContext,
2993                                                        const jint nStartIndex,
2994                                                        /* OUT */ AccessibleHypertextInfo *hypertext) {
2995 
2996     jthrowable exception;
2997     const wchar_t *stringBytes;
2998     jsize length;
2999     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(%p, %p, startIndex = %d)",
3000                      accessibleContext, hypertext, nStartIndex);
3001 
3002     // get the AccessibleHypertext
3003     jobject ht = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleHypertextMethod,
3004                                                               accessibleContext);
3005     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to CallObjectMethod()", FALSE);
3006     jobject globalRef = jniEnv->NewGlobalRef(ht);
3007     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE);
3008     hypertext->accessibleHypertext = (JOBJECT64)globalRef;
3009     PrintDebugString("[INFO]:   ##### AccessibleHypertext = %p", globalRef);
3010     if (hypertext->accessibleHypertext == 0) {
3011         PrintDebugString("[WARN]:   ##### null AccessibleHypertext; returning FALSE");
3012         return FALSE;
3013     }
3014 
3015     // get the hyperlink count
3016     hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod,
3017                                                  accessibleContext);
3018     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE);
3019     PrintDebugString("[INFO]:   ##### hyperlink count = %d", hypertext->linkCount);
3020 
3021     if (nStartIndex >= hypertext->linkCount) {
3022         return FALSE;
3023     }
3024 
3025     // get the hypertext links
3026     // NOTE: To avoid a crash when there are more than MAX_HYPERLINKS (64) links
3027     // in the document, test for i < MAX_HYPERLINKS in addition to
3028     // i < hypertext->linkCount
3029     int bufIndex = 0;
3030     for (int i = nStartIndex; (i < hypertext->linkCount) && (i < nStartIndex + MAX_HYPERLINKS); i++) {
3031         PrintDebugString("[INFO]:   getting hyperlink %d ...", i);
3032 
3033         // get the hyperlink
3034         jobject hl = jniEnv->CallObjectMethod(accessBridgeObject,
3035                                               getAccessibleHyperlinkMethod,
3036                                               hypertext->accessibleHypertext,
3037                                               i);
3038         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE);
3039         jobject globalRef = jniEnv->NewGlobalRef(hl);
3040         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
3041         hypertext->links[bufIndex].accessibleHyperlink = (JOBJECT64)globalRef;
3042         PrintDebugString("[INFO]:   ##### AccessibleHyperlink = %p", globalRef);
3043 
3044         // get the hyperlink text
3045         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3046                                                        getAccessibleHyperlinkTextMethod,
3047                                                        hypertext->links[bufIndex].accessibleHyperlink,
3048                                                        i);
3049 
3050         EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE);
3051         if (js != (jstring) 0) {
3052             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3053             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE);
3054             wcsncpy(hypertext->links[bufIndex].text, stringBytes,
3055                     (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t)));
3056             length = jniEnv->GetStringLength(js);
3057             if (length >= (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t))) {
3058                 length = (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t)) - 2;
3059             }
3060             hypertext->links[bufIndex].text[length] = (wchar_t) 0;
3061             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE);
3062             jniEnv->ReleaseStringChars(js, stringBytes);
3063             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE);
3064             // jniEnv->CallVoidMethod(accessBridgeObject,
3065             //                        decrementReferenceMethod, js);
3066             //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
3067             PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", hypertext->links[bufIndex].text );
3068             jniEnv->DeleteLocalRef(js);
3069             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
3070 
3071         } else {
3072             PrintDebugString("[WARN]:   AccessibleHyperlink text is null.");
3073             hypertext->links[bufIndex].text[0] = (wchar_t) 0;
3074         }
3075 
3076         hypertext->links[bufIndex].startIndex = jniEnv->CallIntMethod(accessBridgeObject,
3077                                                                       getAccessibleHyperlinkStartIndexMethod,
3078                                                                       hypertext->links[bufIndex].accessibleHyperlink,
3079                                                                       i);
3080         EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
3081         PrintDebugString("[INFO]:   ##### hyperlink start index = %d", hypertext->links[bufIndex].startIndex);
3082 
3083         hypertext->links[bufIndex].endIndex = jniEnv->CallIntMethod(accessBridgeObject,
3084                                                                     getAccessibleHyperlinkEndIndexMethod,
3085                                                                     hypertext->links[bufIndex].accessibleHyperlink,
3086                                                                     i);
3087         EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
3088         PrintDebugString("[INFO]:   ##### hyperlink end index = %d", hypertext->links[bufIndex].endIndex);
3089 
3090         bufIndex++;
3091     }
3092 
3093     PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt succeeded");
3094     return TRUE;
3095 }
3096 
getAccessibleHyperlinkCount(const jobject accessibleContext)3097 jint AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(const jobject accessibleContext) {
3098 
3099     jthrowable exception;
3100 
3101     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(%X)",
3102                      accessibleContext);
3103 
3104     if (getAccessibleHyperlinkCountMethod == (jmethodID)0) {
3105         return -1;
3106     }
3107 
3108     // get the hyperlink count
3109     jint linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod,
3110                                            accessibleContext);
3111     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", -1);
3112     PrintDebugString("[INFO]:   ##### hyperlink count = %d", linkCount);
3113 
3114     return linkCount;
3115 }
3116 
3117 
getAccessibleHypertextLinkIndex(const jobject hypertext,const jint nIndex)3118 jint AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(const jobject hypertext,
3119                                                                   const jint nIndex) {
3120 
3121     jthrowable exception;
3122 
3123     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(%p, index = %d)",
3124                      hypertext, nIndex);
3125 
3126     if (getAccessibleHypertextLinkIndexMethod == (jmethodID)0) {
3127         return -1;
3128     }
3129 
3130     // get the hyperlink index
3131     jint index = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHypertextLinkIndexMethod,
3132                                        hypertext, nIndex);
3133 
3134     EXCEPTION_CHECK("##### Getting hyperlink index - call to CallIntMethod()", -1);
3135     PrintDebugString("[INFO]:   ##### hyperlink index = %d", index);
3136 
3137     return index;
3138 }
3139 
getAccessibleHyperlink(jobject hypertext,const jint index,AccessibleHyperlinkInfo * info)3140 BOOL AccessBridgeJavaEntryPoints::getAccessibleHyperlink(jobject hypertext,
3141                                                          const jint index,
3142                                                          /* OUT */ AccessibleHyperlinkInfo *info) {
3143 
3144     jthrowable exception;
3145     const wchar_t *stringBytes;
3146     jsize length;
3147 
3148     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHyperlink(%p, index = %d)",
3149                      hypertext, index);
3150 
3151 
3152     // get the hyperlink
3153     jobject hl = jniEnv->CallObjectMethod(accessBridgeObject,
3154                                           getAccessibleHyperlinkMethod,
3155                                           hypertext,
3156                                           index);
3157     EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE);
3158     jobject globalRef = jniEnv->NewGlobalRef(hl);
3159     EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
3160     info->accessibleHyperlink = (JOBJECT64)globalRef;
3161     PrintDebugString("[INFO]:   ##### AccessibleHyperlink = %p", globalRef);
3162 
3163     // get the hyperlink text
3164     jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3165                                                    getAccessibleHyperlinkTextMethod,
3166                                                    info->accessibleHyperlink,
3167                                                    index);
3168 
3169     EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE);
3170     if (js != (jstring) 0) {
3171         stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3172         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE);
3173         wcsncpy(info->text, stringBytes,
3174                 (sizeof(info->text) / sizeof(wchar_t)));
3175         length = jniEnv->GetStringLength(js);
3176         if (length >= (sizeof(info->text) / sizeof(wchar_t))) {
3177             length = (sizeof(info->text) / sizeof(wchar_t)) - 2;
3178         }
3179         info->text[length] = (wchar_t) 0;
3180         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE);
3181         jniEnv->ReleaseStringChars(js, stringBytes);
3182         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE);
3183         // jniEnv->CallVoidMethod(accessBridgeObject,
3184         //                        decrementReferenceMethod, js);
3185         //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
3186         PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", info->text );
3187         jniEnv->DeleteLocalRef(js);
3188         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
3189 
3190     } else {
3191         PrintDebugString("[WARN]:   AccessibleHyperlink text is null.");
3192         info->text[0] = (wchar_t) 0;
3193     }
3194 
3195     info->startIndex = jniEnv->CallIntMethod(accessBridgeObject,
3196                                              getAccessibleHyperlinkStartIndexMethod,
3197                                              info->accessibleHyperlink,
3198                                              index);
3199     EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
3200     PrintDebugString("[INFO]:   ##### hyperlink start index = %d", info->startIndex);
3201 
3202     info->endIndex = jniEnv->CallIntMethod(accessBridgeObject,
3203                                            getAccessibleHyperlinkEndIndexMethod,
3204                                            info->accessibleHyperlink,
3205                                            index);
3206     EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
3207     PrintDebugString("[INFO]:   ##### hyperlink end index = %d", info->endIndex);
3208 
3209     return TRUE;
3210 }
3211 
3212 
3213 /********** end AccessibleHypertext routines ************************/
3214 
3215 // Accessible Keybinding methods
getAccessibleKeyBindings(jobject accessibleContext,AccessibleKeyBindings * keyBindings)3216 BOOL AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(jobject accessibleContext,
3217                                                            AccessibleKeyBindings *keyBindings) {
3218 
3219     jthrowable exception;
3220 
3221     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(%p, %p)",
3222                      accessibleContext, keyBindings);
3223 
3224     if (getAccessibleKeyBindingsCountMethod == (jmethodID) 0 ||
3225         getAccessibleKeyBindingCharMethod == (jmethodID) 0 ||
3226         getAccessibleKeyBindingModifiersMethod == (jmethodID) 0) {
3227         return FALSE;
3228     }
3229 
3230     // get the key binding count
3231     keyBindings->keyBindingsCount = jniEnv->CallIntMethod(accessBridgeObject,
3232                                                           getAccessibleKeyBindingsCountMethod, accessibleContext);
3233 
3234     EXCEPTION_CHECK("##### Getting key bindings count - call to CallIntMethod()", FALSE);
3235 
3236     PrintDebugString("[INFO]:   ##### key bindings count = %d", keyBindings->keyBindingsCount);
3237 
3238     // get the key bindings
3239     for (int i = 0; i < keyBindings->keyBindingsCount && i < MAX_KEY_BINDINGS; i++) {
3240 
3241         // get the key binding character
3242         keyBindings->keyBindingInfo[i].character = jniEnv->CallCharMethod(accessBridgeObject,
3243                                                                           getAccessibleKeyBindingCharMethod,
3244                                                                           accessibleContext,
3245                                                                           i);
3246         EXCEPTION_CHECK("##### Getting key binding character - call to CallCharMethod()", FALSE);
3247         PrintDebugString("[INFO]:   ##### key binding character = %c"\
3248                          "          ##### key binding character in hex = %hx"\
3249                          , keyBindings->keyBindingInfo[i].character, keyBindings->keyBindingInfo[i].character);
3250 
3251         // get the key binding modifiers
3252         keyBindings->keyBindingInfo[i].modifiers = jniEnv->CallIntMethod(accessBridgeObject,
3253                                                                          getAccessibleKeyBindingModifiersMethod,
3254                                                                          accessibleContext,
3255                                                                          i);
3256         EXCEPTION_CHECK("##### Getting key binding modifiers - call to CallIntMethod()", FALSE);
3257         PrintDebugString("[INFO]:  ##### key binding modifiers = %x", keyBindings->keyBindingInfo[i].modifiers);
3258     }
3259     return FALSE;
3260 }
3261 
3262 // AccessibleIcon methods
getAccessibleIcons(jobject accessibleContext,AccessibleIcons * icons)3263 BOOL AccessBridgeJavaEntryPoints::getAccessibleIcons(jobject accessibleContext,
3264                                                      AccessibleIcons *icons) {
3265 
3266     jthrowable exception;
3267     const wchar_t *stringBytes;
3268     jsize length;
3269 
3270     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)",
3271                      accessibleContext, icons);
3272 
3273     if (getAccessibleIconsCountMethod == (jmethodID) 0 ||
3274         getAccessibleIconDescriptionMethod == (jmethodID) 0 ||
3275         getAccessibleIconHeightMethod == (jmethodID) 0 ||
3276         getAccessibleIconWidthMethod == (jmethodID) 0) {
3277         PrintDebugString("[WARN]:   ##### missing method(s) !!!");
3278         return FALSE;
3279     }
3280 
3281 
3282     // get the icons count
3283     icons->iconsCount = jniEnv->CallIntMethod(accessBridgeObject,
3284                                               getAccessibleIconsCountMethod, accessibleContext);
3285 
3286     EXCEPTION_CHECK("##### Getting icons count - call to CallIntMethod()", FALSE);
3287     PrintDebugString("[INFO]:   ##### icons count = %d", icons->iconsCount);
3288 
3289 
3290     // get the icons
3291     for (int i = 0; i < icons->iconsCount && i < MAX_ICON_INFO; i++) {
3292 
3293         // get the icon description
3294         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3295                                                        getAccessibleIconDescriptionMethod,
3296                                                        accessibleContext,
3297                                                        i);
3298 
3299         EXCEPTION_CHECK("Getting icon description - call to CallObjectMethod()", FALSE);
3300         if (js != (jstring) 0) {
3301             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3302             EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringChars()", FALSE);
3303             wcsncpy(icons->iconInfo[i].description, stringBytes, (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t)));
3304             length = jniEnv->GetStringLength(js);
3305             if (length >= (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t))) {
3306                 length = (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t)) - 2;
3307             }
3308             icons->iconInfo[i].description[length] = (wchar_t) 0;
3309             EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringLength()", FALSE);
3310             jniEnv->ReleaseStringChars(js, stringBytes);
3311             EXCEPTION_CHECK("Getting AccessibleIcon description - call to ReleaseStringChars()", FALSE);
3312             // jniEnv->CallVoidMethod(accessBridgeObject,
3313             //                        decrementReferenceMethod, js);
3314             //EXCEPTION_CHECK("Getting AccessibleIcon description - call to CallVoidMethod()", FALSE);
3315             PrintDebugString("[INFO]: ##### AccessibleIcon description = %ls", icons->iconInfo[i].description );
3316             jniEnv->DeleteLocalRef(js);
3317             EXCEPTION_CHECK("Getting AccessibleIcon description - call to DeleteLocalRef()", FALSE);
3318         } else {
3319             PrintDebugString("[WARN]:   AccessibleIcon description is null.");
3320             icons->iconInfo[i].description[0] = (wchar_t) 0;
3321         }
3322 
3323 
3324         // get the icon height
3325         icons->iconInfo[i].height = jniEnv->CallIntMethod(accessBridgeObject,
3326                                                           getAccessibleIconHeightMethod,
3327                                                           accessibleContext,
3328                                                           i);
3329         EXCEPTION_CHECK("##### Getting icon height - call to CallIntMethod()", FALSE);
3330         PrintDebugString("[INFO]:   ##### icon height = %d", icons->iconInfo[i].height);
3331 
3332         // get the icon width
3333         icons->iconInfo[i].width = jniEnv->CallIntMethod(accessBridgeObject,
3334                                                          getAccessibleIconWidthMethod,
3335                                                          accessibleContext,
3336                                                          i);
3337         EXCEPTION_CHECK("##### Getting icon width - call to CallIntMethod()", FALSE);
3338         PrintDebugString("[INFO]:   ##### icon width = %d", icons->iconInfo[i].width);
3339     }
3340     return FALSE;
3341 }
3342 
3343 // AccessibleActionMethods
getAccessibleActions(jobject accessibleContext,AccessibleActions * actions)3344 BOOL AccessBridgeJavaEntryPoints::getAccessibleActions(jobject accessibleContext,
3345                                                        AccessibleActions *actions) {
3346 
3347     jthrowable exception;
3348     const wchar_t *stringBytes;
3349     jsize length;
3350 
3351     PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)",
3352                      accessibleContext, actions);
3353 
3354     if (getAccessibleActionsCountMethod == (jmethodID) 0 ||
3355         getAccessibleActionNameMethod == (jmethodID) 0) {
3356         PrintDebugString("[WARN]:   ##### missing method(s) !!!");
3357         return FALSE;
3358     }
3359 
3360 
3361     // get the icons count
3362     actions->actionsCount = jniEnv->CallIntMethod(accessBridgeObject,
3363                                                   getAccessibleActionsCountMethod,accessibleContext);
3364 
3365     EXCEPTION_CHECK("##### Getting actions count - call to CallIntMethod()", FALSE);
3366     PrintDebugString("[INFO]:   ##### key actions count = %d", actions->actionsCount);
3367 
3368 
3369     // get the actions
3370     for (int i = 0; i < actions->actionsCount && i < MAX_ACTION_INFO; i++) {
3371 
3372         // get the action name
3373         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
3374                                                        getAccessibleActionNameMethod,
3375                                                        accessibleContext,
3376                                                        i);
3377 
3378         EXCEPTION_CHECK("Getting Action Name  - call to CallObjectMethod()", FALSE);
3379         if (js != (jstring) 0) {
3380             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3381             EXCEPTION_CHECK("Getting AccessibleAction Name  - call to GetStringChars()", FALSE);
3382             wcsncpy(actions->actionInfo[i].name , stringBytes, (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t)));
3383             length = jniEnv->GetStringLength(js);
3384             if (length >= (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t))) {
3385                 length = (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t)) - 2;
3386             }
3387             actions->actionInfo[i].name [length] = (wchar_t) 0;
3388             EXCEPTION_CHECK("Getting AccessibleAction name  - call to GetStringLength()", FALSE);
3389             jniEnv->ReleaseStringChars(js, stringBytes);
3390             EXCEPTION_CHECK("Getting AccessibleAction name  - call to ReleaseStringChars()", FALSE);
3391             // jniEnv->CallVoidMethod(accessBridgeObject,
3392             //                        decrementReferenceMethod, js);
3393             //EXCEPTION_CHECK("Getting AccessibleAction name  - call to CallVoidMethod()", FALSE);
3394             PrintDebugString("[INFO]: ##### AccessibleAction name  = %ls", actions->actionInfo[i].name  );
3395             jniEnv->DeleteLocalRef(js);
3396             EXCEPTION_CHECK("Getting AccessibleAction name  - call to DeleteLocalRef()", FALSE);
3397         } else {
3398             PrintDebugString("[WARN]:   AccessibleAction name  is null.");
3399             actions->actionInfo[i].name [0] = (wchar_t) 0;
3400         }
3401     }
3402     return FALSE;
3403 }
3404 
doAccessibleActions(jobject accessibleContext,AccessibleActionsToDo * actionsToDo,jint * failure)3405 BOOL AccessBridgeJavaEntryPoints::doAccessibleActions(jobject accessibleContext,
3406                                                       AccessibleActionsToDo *actionsToDo,
3407                                                       jint *failure) {
3408 
3409     jthrowable exception;
3410     BOOL returnVal;
3411 
3412     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::doAccessibleActions(%p, #actions %d %s):",
3413                      accessibleContext,
3414                      actionsToDo->actionsCount,
3415                      actionsToDo->actions[0].name);
3416 
3417     if (doAccessibleActionsMethod == (jmethodID) 0) {
3418         *failure = 0;
3419         return FALSE;
3420     }
3421 
3422     PrintDebugString("[INFO]:     doing %d actions ...", actionsToDo->actionsCount);
3423     for (int i = 0; i < actionsToDo->actionsCount && i < MAX_ACTIONS_TO_DO; i++) {
3424         PrintDebugString("[INFO]:     doing action %d: %s ...", i, actionsToDo->actions[i].name);
3425 
3426         // create a Java String for the action name
3427         wchar_t *actionName = (wchar_t *)actionsToDo->actions[i].name;
3428         jstring javaName = jniEnv->NewString(actionName, (jsize)wcslen(actionName));
3429         if (javaName == 0) {
3430             PrintDebugString("[ERROR]:     NewString failed");
3431             *failure = i;
3432             return FALSE;
3433         }
3434 
3435         returnVal = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, doAccessibleActionsMethod,
3436                                                     accessibleContext, javaName);
3437         jniEnv->DeleteLocalRef(javaName);
3438         EXCEPTION_CHECK("doAccessibleActions - call to CallBooleanMethod()", FALSE);
3439 
3440         if (returnVal != TRUE) {
3441             PrintDebugString("[ERROR]:     Action %d failed", i);
3442             *failure = i;
3443             return FALSE;
3444         }
3445     }
3446     *failure = -1;
3447     return TRUE;
3448 }
3449 
3450 
3451 /********** AccessibleText routines ***********************************/
3452 
3453 BOOL
getAccessibleTextInfo(jobject accessibleContext,AccessibleTextInfo * textInfo,jint x,jint y)3454 AccessBridgeJavaEntryPoints::getAccessibleTextInfo(jobject accessibleContext,
3455                                                    AccessibleTextInfo *textInfo,
3456                                                    jint x, jint y) {
3457     jthrowable exception;
3458 
3459     // Verify the Java VM still exists and AccessibleContext is
3460     // an instance of AccessibleText
3461     if (verifyAccessibleText(accessibleContext) == FALSE) {
3462         return FALSE;
3463     }
3464 
3465     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextInfo(%p, %d, %d):",
3466                      accessibleContext, x, y);
3467 
3468     // Get the character count
3469     if (getAccessibleCharCountFromContextMethod != (jmethodID) 0) {
3470         textInfo->charCount = jniEnv->CallIntMethod(accessBridgeObject,
3471                                                     getAccessibleCharCountFromContextMethod,
3472                                                     accessibleContext);
3473         EXCEPTION_CHECK("Getting AccessibleCharCount - call to CallIntMethod()", FALSE);
3474         PrintDebugString("[INFO]:   Char count = %d", textInfo->charCount);
3475     } else {
3476         PrintDebugString("[ERROR]: either env == 0 or getAccessibleCharCountFromContextMethod == 0");
3477         return FALSE;
3478     }
3479 
3480     // Get the index of the caret
3481     if (getAccessibleCaretPositionFromContextMethod != (jmethodID) 0) {
3482         textInfo->caretIndex = jniEnv->CallIntMethod(accessBridgeObject,
3483                                                      getAccessibleCaretPositionFromContextMethod,
3484                                                      accessibleContext);
3485         EXCEPTION_CHECK("Getting AccessibleCaretPosition - call to CallIntMethod()", FALSE);
3486         PrintDebugString("[INFO]:   Index at caret = %d", textInfo->caretIndex);
3487     } else {
3488         PrintDebugString("[ERROR]: either env == 0 or getAccessibleCaretPositionFromContextMethod == 0");
3489         return FALSE;
3490     }
3491 
3492     // Get the index at the given point
3493     if (getAccessibleIndexAtPointFromContextMethod != (jmethodID) 0) {
3494         textInfo->indexAtPoint = jniEnv->CallIntMethod(accessBridgeObject,
3495                                                        getAccessibleIndexAtPointFromContextMethod,
3496                                                        accessibleContext, x, y);
3497         EXCEPTION_CHECK("Getting AccessibleIndexAtPoint - call to CallIntMethod()", FALSE);
3498         PrintDebugString("[INFO]:  Index at point = %d", textInfo->indexAtPoint);
3499     } else {
3500         PrintDebugString("[ERROR]:  Error! either env == 0 or getAccessibleIndexAtPointFromContextMethod == 0");
3501         return FALSE;
3502     }
3503     return TRUE;
3504 }
3505 
3506 BOOL
getAccessibleTextItems(jobject accessibleContext,AccessibleTextItemsInfo * textItems,jint index)3507 AccessBridgeJavaEntryPoints::getAccessibleTextItems(jobject accessibleContext,
3508                                                     AccessibleTextItemsInfo *textItems, jint index) {
3509     jstring js;
3510     const wchar_t *stringBytes;
3511     jthrowable exception;
3512     jsize length;
3513 
3514     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextItems(%p):", accessibleContext);
3515 
3516     // Verify the Java VM still exists and AccessibleContext is
3517     // an instance of AccessibleText
3518     if (verifyAccessibleText(accessibleContext) == FALSE) {
3519         return FALSE;
3520     }
3521 
3522     // Get the letter at index
3523     if (getAccessibleLetterAtIndexFromContextMethod != (jmethodID) 0) {
3524         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3525                                                 getAccessibleLetterAtIndexFromContextMethod,
3526                                                 accessibleContext, index);
3527         EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallIntMethod()", FALSE);
3528         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
3529         if (js != (jstring) 0) {
3530             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3531             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to GetStringChars()", FALSE);
3532             textItems->letter = stringBytes[0];
3533             jniEnv->ReleaseStringChars(js, stringBytes);
3534             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to ReleaseStringChars()", FALSE);
3535             jniEnv->CallVoidMethod(accessBridgeObject,
3536                                    decrementReferenceMethod, js);
3537             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallVoidMethod()", FALSE);
3538             PrintDebugString("[INFO]:   Accessible Text letter = %c", textItems->letter);
3539             jniEnv->DeleteLocalRef(js);
3540             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to DeleteLocalRef()", FALSE);
3541         } else {
3542             PrintDebugString("[WARN]:   Accessible Text letter is null.");
3543             textItems->letter = (wchar_t) 0;
3544         }
3545     } else {
3546         PrintDebugString("[ERROR]: either env == 0 or getAccessibleLetterAtIndexFromContextMethod == 0");
3547         return FALSE;
3548     }
3549 
3550 
3551     // Get the word at index
3552     if (getAccessibleWordAtIndexFromContextMethod != (jmethodID) 0) {
3553         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3554                                                 getAccessibleWordAtIndexFromContextMethod,
3555                                                 accessibleContext, index);
3556         EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallIntMethod()", FALSE);
3557         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
3558         if (js != (jstring) 0) {
3559             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3560             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringChars()", FALSE);
3561             wcsncpy(textItems->word, stringBytes, (sizeof(textItems->word) / sizeof(wchar_t)));
3562             length = jniEnv->GetStringLength(js);
3563             textItems->word[length < (sizeof(textItems->word) / sizeof(wchar_t)) ?
3564                             length : (sizeof(textItems->word) / sizeof(wchar_t))-2] = (wchar_t) 0;
3565             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringLength()", FALSE);
3566             jniEnv->ReleaseStringChars(js, stringBytes);
3567             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to ReleaseStringChars()", FALSE);
3568             jniEnv->CallVoidMethod(accessBridgeObject,
3569                                    decrementReferenceMethod, js);
3570             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallVoidMethod()", FALSE);
3571             wPrintDebugString(L"[INFO]:   Accessible Text word = %ls", textItems->word);
3572             jniEnv->DeleteLocalRef(js);
3573             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to DeleteLocalRef()", FALSE);
3574         } else {
3575             PrintDebugString("[WARN]:   Accessible Text word is null.");
3576             textItems->word[0] = (wchar_t) 0;
3577         }
3578     } else {
3579         PrintDebugString("[ERROR]: either env == 0 or getAccessibleWordAtIndexFromContextMethod == 0");
3580         return FALSE;
3581     }
3582 
3583     // Get the sentence at index
3584     if (getAccessibleSentenceAtIndexFromContextMethod != (jmethodID) 0) {
3585         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3586                                                 getAccessibleSentenceAtIndexFromContextMethod,
3587                                                 accessibleContext, index);
3588         EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallObjectMethod()", FALSE);
3589         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
3590         if (js != (jstring) 0) {
3591             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3592             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringChars()", FALSE);
3593             wcsncpy(textItems->sentence, stringBytes, (sizeof(textItems->sentence) / sizeof(wchar_t))-2);
3594             length = jniEnv->GetStringLength(js);
3595 
3596             if (length < sizeof(textItems->sentence) / sizeof(wchar_t)) {
3597                 textItems->sentence[length] = (wchar_t) 0;
3598             } else {
3599                 textItems->sentence[(sizeof(textItems->sentence) / sizeof(wchar_t))-2] = (wchar_t) 0;
3600             }
3601             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringLength()", FALSE);
3602             jniEnv->ReleaseStringChars(js, stringBytes);
3603             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to ReleaseStringChars()", FALSE);
3604             jniEnv->CallVoidMethod(accessBridgeObject,
3605                                    decrementReferenceMethod, js);
3606             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallVoidMethod()", FALSE);
3607             wPrintDebugString(L"[INFO]:   Accessible Text sentence = %ls", textItems->sentence);
3608             jniEnv->DeleteLocalRef(js);
3609             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to DeleteLocalRef()", FALSE);
3610         } else {
3611             PrintDebugString("[WARN]:   Accessible Text sentence is null.");
3612             textItems->sentence[0] = (wchar_t) 0;
3613         }
3614     } else {
3615         PrintDebugString("[ERROR]: either env == 0 or getAccessibleSentenceAtIndexFromContextMethod == 0");
3616         return FALSE;
3617     }
3618 
3619     return TRUE;
3620 }
3621 
3622 BOOL
getAccessibleTextSelectionInfo(jobject accessibleContext,AccessibleTextSelectionInfo * selectionInfo)3623 AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(jobject accessibleContext,
3624                                                             AccessibleTextSelectionInfo *selectionInfo) {
3625     jstring js;
3626     const wchar_t *stringBytes;
3627     jthrowable exception;
3628     jsize length;
3629 
3630     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(%p):",
3631                      accessibleContext);
3632 
3633     // Verify the Java VM still exists and AccessibleContext is
3634     // an instance of AccessibleText
3635     if (verifyAccessibleText(accessibleContext) == FALSE) {
3636         return FALSE;
3637     }
3638 
3639     // Get the selection start index
3640     if (getAccessibleTextSelectionStartFromContextMethod != (jmethodID) 0) {
3641         selectionInfo->selectionStartIndex = jniEnv->CallIntMethod(accessBridgeObject,
3642                                                                    getAccessibleTextSelectionStartFromContextMethod,
3643                                                                    accessibleContext);
3644         EXCEPTION_CHECK("Getting AccessibleTextSelectionStart - call to CallIntMethod()", FALSE);
3645         PrintDebugString("[INFO]:   Selection start = %d", selectionInfo->selectionStartIndex);
3646     } else {
3647         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextSelectionStartFromContextMethod == 0");
3648         return FALSE;
3649     }
3650 
3651     // Get the selection end index
3652     if (getAccessibleTextSelectionEndFromContextMethod != (jmethodID) 0) {
3653         selectionInfo->selectionEndIndex = jniEnv->CallIntMethod(accessBridgeObject,
3654                                                                  getAccessibleTextSelectionEndFromContextMethod,
3655                                                                  accessibleContext);
3656         EXCEPTION_CHECK("Getting AccessibleTextSelectionEnd - call to CallIntMethod()", FALSE);
3657         PrintDebugString("[INFO]:   Selection end = %d", selectionInfo->selectionEndIndex);
3658     } else {
3659         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextSelectionEndFromContextMethod == 0");
3660         return FALSE;
3661     }
3662 
3663     // Get the selected text
3664     if (getAccessibleTextSelectedTextFromContextMethod != (jmethodID) 0) {
3665         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3666                                                 getAccessibleTextSelectedTextFromContextMethod,
3667                                                 accessibleContext);
3668         EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallObjectMethod()", FALSE);
3669         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
3670         if (js != (jstring) 0) {
3671             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3672             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringChars()", FALSE);
3673             wcsncpy(selectionInfo->selectedText, stringBytes, (sizeof(selectionInfo->selectedText) / sizeof(wchar_t)));
3674             length = jniEnv->GetStringLength(js);
3675             selectionInfo->selectedText[length < (sizeof(selectionInfo->selectedText) / sizeof(wchar_t)) ?
3676                                         length : (sizeof(selectionInfo->selectedText) / sizeof(wchar_t))-2] = (wchar_t) 0;
3677             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringLength()", FALSE);
3678             jniEnv->ReleaseStringChars(js, stringBytes);
3679             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to ReleaseStringChars()", FALSE);
3680             jniEnv->CallVoidMethod(accessBridgeObject,
3681                                    decrementReferenceMethod, js);
3682             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallVoidMethod()", FALSE);
3683             PrintDebugString("[INFO]:   Accessible's selected text = %s", selectionInfo->selectedText);
3684             jniEnv->DeleteLocalRef(js);
3685             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to DeleteLocalRef()", FALSE);
3686         } else {
3687             PrintDebugString("[WARN]:   Accessible's selected text is null.");
3688             selectionInfo->selectedText[0] = (wchar_t) 0;
3689         }
3690     } else {
3691         PrintDebugString("[WARN]: either env == 0 or getAccessibleTextSelectedTextFromContextMethod == 0");
3692         return FALSE;
3693     }
3694     return TRUE;
3695 }
3696 
3697 BOOL
getAccessibleTextAttributes(jobject accessibleContext,jint index,AccessibleTextAttributesInfo * attributes)3698 AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleContext, jint index, AccessibleTextAttributesInfo *attributes) {
3699     jstring js;
3700     const wchar_t *stringBytes;
3701     jobject AttributeSet;
3702     jthrowable exception;
3703     jsize length;
3704 
3705     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(%p):", accessibleContext);
3706 
3707     // Verify the Java VM still exists and AccessibleContext is
3708     // an instance of AccessibleText
3709     if (verifyAccessibleText(accessibleContext) == FALSE) {
3710         return FALSE;
3711     }
3712 
3713     if (accessibleContext == (jobject) 0) {
3714         PrintDebugString("[WARN]:  passed in AccessibleContext == null! (oops)");
3715 
3716         attributes->bold = FALSE;
3717         attributes->italic = FALSE;
3718         attributes->underline = FALSE;
3719         attributes->strikethrough = FALSE;
3720         attributes->superscript = FALSE;
3721         attributes->subscript = FALSE;
3722         attributes->backgroundColor[0] = (wchar_t) 0;
3723         attributes->foregroundColor[0] = (wchar_t) 0;
3724         attributes->fontFamily[0] = (wchar_t) 0;
3725         attributes->fontSize = -1;
3726         attributes->alignment = -1;
3727         attributes->bidiLevel = -1;
3728         attributes->firstLineIndent = -1;
3729         attributes->leftIndent = -1;
3730         attributes->rightIndent = -1;
3731         attributes->lineSpacing = -1;
3732         attributes->spaceAbove = -1;
3733         attributes->spaceBelow = -1;
3734         attributes->fullAttributesString[0] = (wchar_t) 0;
3735 
3736         return (FALSE);
3737     }
3738 
3739     // Get the AttributeSet
3740     if (getAccessibleAttributeSetAtIndexFromContextMethod != (jmethodID) 0) {
3741         PrintDebugString("[INFO]:  Getting AttributeSet at index...");
3742         AttributeSet = jniEnv->CallObjectMethod(accessBridgeObject,
3743                                                 getAccessibleAttributeSetAtIndexFromContextMethod,
3744                                                 accessibleContext, index);
3745         EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to CallObjectMethod()", FALSE);
3746     } else {
3747         PrintDebugString("[ERROR]: either env == 0 or getAccessibleAttributeSetAtIndexFromContextMethod == 0");
3748         return FALSE;
3749     }
3750 
3751     // It is legal for the AttributeSet object to be null, in which case we return false!
3752     if (AttributeSet == (jobject) 0) {
3753         PrintDebugString("[WARN]:  AttributeSet returned at index is null (this is legal! - see AWT in J2SE 1.3");
3754 
3755         attributes->bold = FALSE;
3756         attributes->italic = FALSE;
3757         attributes->underline = FALSE;
3758         attributes->strikethrough = FALSE;
3759         attributes->superscript = FALSE;
3760         attributes->subscript = FALSE;
3761         attributes->backgroundColor[0] = (wchar_t) 0;
3762         attributes->foregroundColor[0] = (wchar_t) 0;
3763         attributes->fontFamily[0] = (wchar_t) 0;
3764         attributes->fontSize = -1;
3765         attributes->alignment = -1;
3766         attributes->bidiLevel = -1;
3767         attributes->firstLineIndent = -1;
3768         attributes->leftIndent = -1;
3769         attributes->rightIndent = -1;
3770         attributes->lineSpacing = -1;
3771         attributes->spaceAbove = -1;
3772         attributes->spaceBelow = -1;
3773         attributes->fullAttributesString[0] = (wchar_t) 0;
3774 
3775         return (FALSE);
3776     }
3777 
3778     // Get the bold setting
3779     if (getBoldFromAttributeSetMethod != (jmethodID) 0) {
3780         PrintDebugString("[INFO]:  Getting bold from AttributeSet...");
3781         attributes->bold = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3782                                                             getBoldFromAttributeSetMethod,
3783                                                             AttributeSet);
3784         EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallBooleanMethod()", FALSE);
3785     } else {
3786         PrintDebugString("[ERROR]: either env == 0 or getBoldFromAttributeSetMethod == 0");
3787         jniEnv->CallVoidMethod(accessBridgeObject,
3788                                decrementReferenceMethod, AttributeSet);
3789         EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallVoidMethod()", FALSE);
3790         jniEnv->DeleteLocalRef(AttributeSet);
3791         EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to DeleteLocalRef()", FALSE);
3792         return FALSE;
3793     }
3794 
3795     // Get the italic setting
3796     if (getItalicFromAttributeSetMethod != (jmethodID) 0) {
3797         PrintDebugString("[INFO]:  Getting italic from AttributeSet...");
3798         attributes->italic = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3799                                                               getItalicFromAttributeSetMethod,
3800                                                               AttributeSet);
3801         EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallBooleanMethod()", FALSE);
3802     } else {
3803         PrintDebugString("[ERROR]: either env == 0 or getItalicdFromAttributeSetMethod == 0");
3804         jniEnv->CallVoidMethod(accessBridgeObject,
3805                                decrementReferenceMethod, AttributeSet);
3806         EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallVoidMethod()", FALSE);
3807         jniEnv->DeleteLocalRef(AttributeSet);
3808         EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to DeleteLocalRef()", FALSE);
3809         return FALSE;
3810     }
3811 
3812     // Get the underline setting
3813     if (getUnderlineFromAttributeSetMethod != (jmethodID) 0) {
3814         PrintDebugString("[INFO]:  Getting underline from AttributeSet...");
3815         attributes->underline = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3816                                                                  getUnderlineFromAttributeSetMethod,
3817                                                                  AttributeSet);
3818         EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallBooleanMethod()", FALSE);
3819     } else {
3820         PrintDebugString("[ERROR]:  either env == 0 or getUnderlineFromAttributeSetMethod == 0");
3821         jniEnv->CallVoidMethod(accessBridgeObject,
3822                                decrementReferenceMethod, AttributeSet);
3823         EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallVoidMethod()", FALSE);
3824         jniEnv->DeleteLocalRef(AttributeSet);
3825         EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to DeleteLocalRef()", FALSE);
3826         return FALSE;
3827     }
3828 
3829     // Get the strikethrough setting
3830     if (getStrikethroughFromAttributeSetMethod != (jmethodID) 0) {
3831         PrintDebugString("[INFO]:  Getting strikethrough from AttributeSet...");
3832         attributes->strikethrough = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3833                                                                      getStrikethroughFromAttributeSetMethod,
3834                                                                      AttributeSet);
3835         EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallBooleanMethod()", FALSE);
3836     } else {
3837         PrintDebugString("[ERROR]: either env == 0 or getStrikethroughFromAttributeSetMethod == 0");
3838         jniEnv->CallVoidMethod(accessBridgeObject,
3839                                decrementReferenceMethod, AttributeSet);
3840         EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallVoidMethod()", FALSE);
3841         jniEnv->DeleteLocalRef(AttributeSet);
3842         EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to DeleteLocalRef()", FALSE);
3843         return FALSE;
3844     }
3845 
3846     // Get the superscript setting
3847     if (getSuperscriptFromAttributeSetMethod != (jmethodID) 0) {
3848         PrintDebugString("[INFO]:  Getting superscript from AttributeSet...");
3849         attributes->superscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3850                                                                    getSuperscriptFromAttributeSetMethod,
3851                                                                    AttributeSet);
3852         EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallBooleanMethod()", FALSE);
3853     } else {
3854         PrintDebugString("[ERROR]: either env == 0 or getSuperscripteFromAttributeSetMethod == 0");
3855         jniEnv->CallVoidMethod(accessBridgeObject,
3856                                decrementReferenceMethod, AttributeSet);
3857         EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallVoidMethod()", FALSE);
3858         jniEnv->DeleteLocalRef(AttributeSet);
3859         EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to DeleteLocalRef()", FALSE);
3860         return FALSE;
3861     }
3862 
3863     // Get the subscript setting
3864     if (getSubscriptFromAttributeSetMethod != (jmethodID) 0) {
3865         PrintDebugString("[INFO]:  Getting subscript from AttributeSet...");
3866         attributes->subscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
3867                                                                  getSubscriptFromAttributeSetMethod,
3868                                                                  AttributeSet);
3869         EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallBooleanMethod()", FALSE);
3870     } else {
3871         PrintDebugString("[ERROR]: either env == 0 or getSubscriptFromAttributeSetMethod == 0");
3872         jniEnv->CallVoidMethod(accessBridgeObject,
3873                                decrementReferenceMethod, AttributeSet);
3874         EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallVoidMethod()", FALSE);
3875         jniEnv->DeleteLocalRef(AttributeSet);
3876         EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to DeleteLocalRef()", FALSE);
3877         return FALSE;
3878     }
3879 
3880     // Get the backgroundColor setting
3881     if (getBackgroundColorFromAttributeSetMethod != (jmethodID) 0) {
3882         PrintDebugString("[INFO]:  Getting backgroundColor from AttributeSet...");
3883         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3884                                                 getBackgroundColorFromAttributeSetMethod,
3885                                                 AttributeSet);
3886         EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallObjectMethod()", FALSE);
3887         if (js != (jstring) 0) {
3888             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3889             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringChars()", FALSE);
3890             wcsncpy(attributes->backgroundColor, stringBytes, (sizeof(attributes->backgroundColor) / sizeof(wchar_t)));
3891             length = jniEnv->GetStringLength(js);
3892             attributes->backgroundColor[length < (sizeof(attributes->backgroundColor) / sizeof(wchar_t)) ?
3893                                         length : (sizeof(attributes->backgroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0;
3894             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringLength()", FALSE);
3895             jniEnv->ReleaseStringChars(js, stringBytes);
3896             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE);
3897             jniEnv->CallVoidMethod(accessBridgeObject,
3898                                    decrementReferenceMethod, js);
3899             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3900             wPrintDebugString(L"[INFO]:   AttributeSet's background color = %ls", attributes->backgroundColor);
3901             jniEnv->DeleteLocalRef(js);
3902             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3903         } else {
3904             PrintDebugString("[WARN]:   AttributeSet's background color is null.");
3905             attributes->backgroundColor[0] = (wchar_t) 0;
3906         }
3907     } else {
3908         PrintDebugString("[ERROR]: either env == 0 or getBackgroundColorFromAttributeSetMethod == 0");
3909         jniEnv->CallVoidMethod(accessBridgeObject,
3910                                decrementReferenceMethod, AttributeSet);
3911         EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3912         jniEnv->DeleteLocalRef(AttributeSet);
3913         EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3914         return FALSE;
3915     }
3916 
3917     // Get the foregroundColor setting
3918     if (getForegroundColorFromAttributeSetMethod != (jmethodID) 0) {
3919         PrintDebugString("[INFO]:  Getting foregroundColor from AttributeSet...");
3920         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3921                                                 getForegroundColorFromAttributeSetMethod,
3922                                                 AttributeSet);
3923         EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallObjectMethod()", FALSE);
3924         if (js != (jstring) 0) {
3925             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3926             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringChars()", FALSE);
3927             wcsncpy(attributes->foregroundColor, stringBytes, (sizeof(attributes->foregroundColor) / sizeof(wchar_t)));
3928             length = jniEnv->GetStringLength(js);
3929             attributes->foregroundColor[length < (sizeof(attributes->foregroundColor) / sizeof(wchar_t)) ?
3930                                         length : (sizeof(attributes->foregroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0;
3931             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringLength()", FALSE);
3932             jniEnv->ReleaseStringChars(js, stringBytes);
3933             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE);
3934             jniEnv->CallVoidMethod(accessBridgeObject,
3935                                    decrementReferenceMethod, js);
3936             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3937             wPrintDebugString(L"[INFO]:   AttributeSet's foreground color = %ls", attributes->foregroundColor);
3938             jniEnv->DeleteLocalRef(js);
3939             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3940         } else {
3941             PrintDebugString("[WARN]:   AttributeSet's foreground color is null.");
3942             attributes->foregroundColor[0] = (wchar_t) 0;
3943         }
3944     } else {
3945         PrintDebugString("[ERROR]: either env == 0 or getForegroundColorFromAttributeSetMethod == 0");
3946         jniEnv->CallVoidMethod(accessBridgeObject,
3947                                decrementReferenceMethod, AttributeSet);
3948         EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
3949         jniEnv->DeleteLocalRef(AttributeSet);
3950         EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
3951         return FALSE;
3952     }
3953 
3954     // Get the fontFamily setting
3955     if (getFontFamilyFromAttributeSetMethod != (jmethodID) 0) {
3956         PrintDebugString("[INFO]:  Getting fontFamily from AttributeSet...");
3957         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
3958                                                 getFontFamilyFromAttributeSetMethod,
3959                                                 AttributeSet);
3960         EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallObjectMethod()", FALSE);
3961         if (js != (jstring) 0) {
3962             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
3963             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringChars()", FALSE);
3964             wcsncpy(attributes->fontFamily, stringBytes, (sizeof(attributes->fontFamily) / sizeof(wchar_t)));
3965             length = jniEnv->GetStringLength(js);
3966             attributes->fontFamily[length < (sizeof(attributes->fontFamily) / sizeof(wchar_t)) ?
3967                                    length : (sizeof(attributes->fontFamily) / sizeof(wchar_t))-2] = (wchar_t) 0;
3968             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringLength()", FALSE);
3969             jniEnv->ReleaseStringChars(js, stringBytes);
3970             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to ReleaseStringChars()", FALSE);
3971             jniEnv->CallVoidMethod(accessBridgeObject,
3972                                    decrementReferenceMethod, js);
3973             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE);
3974             wPrintDebugString(L"[INFO]:   AttributeSet's fontFamily = %ls", attributes->fontFamily);
3975             jniEnv->DeleteLocalRef(js);
3976             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE);
3977         } else {
3978             PrintDebugString("[WARN]:   AttributeSet's fontFamily is null.");
3979             attributes->backgroundColor[0] = (wchar_t) 0;
3980         }
3981     } else {
3982         PrintDebugString("[ERROR]: either env == 0 or getFontFamilyFromAttributeSetMethod == 0");
3983         jniEnv->CallVoidMethod(accessBridgeObject,
3984                                decrementReferenceMethod, AttributeSet);
3985         EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE);
3986         jniEnv->DeleteLocalRef(AttributeSet);
3987         EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE);
3988         return FALSE;
3989     }
3990 
3991     // Get the font size
3992     if (getFontSizeFromAttributeSetMethod != (jmethodID) 0) {
3993         PrintDebugString("[INFO]:  Getting font size from AttributeSet...");
3994         attributes->fontSize = jniEnv->CallIntMethod(accessBridgeObject,
3995                                                      getFontSizeFromAttributeSetMethod,
3996                                                      AttributeSet);
3997         EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallIntMethod()", FALSE);
3998         PrintDebugString("[INFO]:   AttributeSet's font size = %d", attributes->fontSize);
3999     } else {
4000         PrintDebugString("[ERROR]: either env == 0 or getAlignmentFromAttributeSetMethod == 0");
4001         jniEnv->CallVoidMethod(accessBridgeObject,
4002                                decrementReferenceMethod, AttributeSet);
4003         EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallVoidMethod()", FALSE);
4004         jniEnv->DeleteLocalRef(AttributeSet);
4005         EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to DeleteLocalRef()", FALSE);
4006         return FALSE;
4007     }
4008 
4009 
4010     // Get the alignment setting
4011     if (getAlignmentFromAttributeSetMethod != (jmethodID) 0) {
4012         PrintDebugString("[INFO]: Getting alignment from AttributeSet...");
4013         attributes->alignment = jniEnv->CallIntMethod(accessBridgeObject,
4014                                                       getAlignmentFromAttributeSetMethod,
4015                                                       AttributeSet);
4016         EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallIntMethod()", FALSE);
4017     } else {
4018         PrintDebugString("[ERROR]: either env == 0 or getAlignmentFromAttributeSetMethod == 0");
4019         jniEnv->CallVoidMethod(accessBridgeObject,
4020                                decrementReferenceMethod, AttributeSet);
4021         EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallVoidMethod()", FALSE);
4022         jniEnv->DeleteLocalRef(AttributeSet);
4023         EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4024         return FALSE;
4025     }
4026 
4027     // Get the bidiLevel setting
4028     if (getBidiLevelFromAttributeSetMethod != (jmethodID) 0) {
4029         PrintDebugString("[INFO]:  Getting bidiLevel from AttributeSet...");
4030         attributes->bidiLevel = jniEnv->CallIntMethod(accessBridgeObject,
4031                                                       getBidiLevelFromAttributeSetMethod,
4032                                                       AttributeSet);
4033         EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallIntMethod()", FALSE);
4034     } else {
4035         PrintDebugString("[ERROR]: either env == 0 or getBidiLevelFromAttributeSetMethod == 0");
4036         jniEnv->CallVoidMethod(accessBridgeObject,
4037                                decrementReferenceMethod, AttributeSet);
4038         EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallVoidMethod()", FALSE);
4039         jniEnv->DeleteLocalRef(AttributeSet);
4040         EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to DeleteLocalRef()", FALSE);
4041         return FALSE;
4042     }
4043 
4044     // Get the firstLineIndent setting
4045     if (getFirstLineIndentFromAttributeSetMethod != (jmethodID) 0) {
4046         PrintDebugString("[ERROR]:  Getting firstLineIndent from AttributeSet...");
4047         attributes->firstLineIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4048                                                                        getFirstLineIndentFromAttributeSetMethod,
4049                                                                        AttributeSet);
4050         EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallIntMethod()", FALSE);
4051     } else {
4052         PrintDebugString("[ERROR]: either env == 0 or getFirstLineIndentFromAttributeSetMethod == 0");
4053         jniEnv->CallVoidMethod(accessBridgeObject,
4054                                decrementReferenceMethod, AttributeSet);
4055         EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
4056         jniEnv->DeleteLocalRef(AttributeSet);
4057         EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4058         return FALSE;
4059     }
4060 
4061     // Get the leftIndent setting
4062     if (getLeftIndentFromAttributeSetMethod != (jmethodID) 0) {
4063         PrintDebugString("[INFO]:  Getting leftIndent from AttributeSet...");
4064         attributes->leftIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4065                                                                   getLeftIndentFromAttributeSetMethod,
4066                                                                   AttributeSet);
4067         EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallIntMethod()", FALSE);
4068     } else {
4069         PrintDebugString("[ERROR]: either env == 0 or getLeftIndentFromAttributeSetMethod == 0");
4070         jniEnv->CallVoidMethod(accessBridgeObject,
4071                                decrementReferenceMethod, AttributeSet);
4072         EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
4073         jniEnv->DeleteLocalRef(AttributeSet);
4074         EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4075         return FALSE;
4076     }
4077 
4078     // Get the rightIndent setting
4079     if (getRightIndentFromAttributeSetMethod != (jmethodID) 0) {
4080         PrintDebugString("[INFO]:  Getting rightIndent from AttributeSet...");
4081         attributes->rightIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4082                                                                    getRightIndentFromAttributeSetMethod,
4083                                                                    AttributeSet);
4084         EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallIntMethod()", FALSE);
4085     } else {
4086         PrintDebugString("[ERROR]: either env == 0 or getRightIndentFromAttributeSetMethod == 0");
4087         jniEnv->CallVoidMethod(accessBridgeObject,
4088                                decrementReferenceMethod, AttributeSet);
4089         EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
4090         jniEnv->DeleteLocalRef(AttributeSet);
4091         EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to DeleteLocalRef()", FALSE);
4092         return FALSE;
4093     }
4094 
4095     // Get the lineSpacing setting
4096     if (getLineSpacingFromAttributeSetMethod != (jmethodID) 0) {
4097         PrintDebugString("[INFO]:  Getting lineSpacing from AttributeSet...");
4098         attributes->lineSpacing = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4099                                                                    getLineSpacingFromAttributeSetMethod,
4100                                                                    AttributeSet);
4101         EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallIntMethod()", FALSE);
4102     } else {
4103         PrintDebugString("[ERROR]:  either env == 0 or getLineSpacingFromAttributeSetMethod == 0");
4104         jniEnv->CallVoidMethod(accessBridgeObject,
4105                                decrementReferenceMethod, AttributeSet);
4106         EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallVoidMethod()", FALSE);
4107         jniEnv->DeleteLocalRef(AttributeSet);
4108         EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to DeleteLocalRef()", FALSE);
4109         return FALSE;
4110     }
4111 
4112     // Get the spaceAbove setting
4113     if (getSpaceAboveFromAttributeSetMethod != (jmethodID) 0) {
4114         PrintDebugString("[INFO]:  Getting spaceAbove from AttributeSet...");
4115         attributes->spaceAbove = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4116                                                                   getSpaceAboveFromAttributeSetMethod,
4117                                                                   AttributeSet);
4118         EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallIntMethod()", FALSE);
4119     } else {
4120         PrintDebugString("[ERROR]:  either env == 0 or getSpaceAboveFromAttributeSetMethod == 0");
4121         jniEnv->CallVoidMethod(accessBridgeObject,
4122                                decrementReferenceMethod, AttributeSet);
4123         EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallVoidMethod()", FALSE);
4124         jniEnv->DeleteLocalRef(AttributeSet);
4125         EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to DeleteLocalRef()", FALSE);
4126         return FALSE;
4127     }
4128 
4129     // Get the spaceBelow setting
4130     if (getSpaceBelowFromAttributeSetMethod != (jmethodID) 0) {
4131         PrintDebugString("[INFO]:  Getting spaceBelow from AttributeSet...");
4132         attributes->spaceBelow = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
4133                                                                   getSpaceBelowFromAttributeSetMethod,
4134                                                                   AttributeSet);
4135         EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallIntMethod()", FALSE);
4136     } else {
4137         PrintDebugString("[ERROR]:  either env == 0 or getSpaceBelowFromAttributeSetMethod == 0");
4138         jniEnv->CallVoidMethod(accessBridgeObject,
4139                                decrementReferenceMethod, AttributeSet);
4140         EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallVoidMethod()", FALSE);
4141         jniEnv->DeleteLocalRef(AttributeSet);
4142         EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to DeleteLocalRef()", FALSE);
4143         return FALSE;
4144     }
4145 
4146     // Release the AttributeSet object
4147     if (decrementReferenceMethod != (jmethodID) 0) {
4148         PrintDebugString("[INFO]:  Decrementing reference to AttributeSet...");
4149         jniEnv->CallVoidMethod(accessBridgeObject,
4150                                decrementReferenceMethod, AttributeSet);
4151         EXCEPTION_CHECK("Releasing AttributeSet object - call to CallVoidMethod()", FALSE);
4152     } else {
4153         PrintDebugString("[ERROR]:  either env == 0 or accessBridgeObject == 0");
4154         jniEnv->DeleteLocalRef(AttributeSet);
4155         EXCEPTION_CHECK("Releasing AttributeSet object - call to DeleteLocalRef()", FALSE);
4156         return FALSE;
4157     }
4158 
4159     // Get the full attributes string at index
4160     if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) {
4161         PrintDebugString("[INFO]:  Getting full attributes string from Context...");
4162         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4163                                                 getAccessibleAttributesAtIndexFromContextMethod,
4164                                                 accessibleContext, index);
4165         EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE);
4166         PrintDebugString("[INFO]:  returned from CallObjectMethod(), js = %p", js);
4167         if (js != (jstring) 0) {
4168             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4169             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE);
4170             wcsncpy(attributes->fullAttributesString, stringBytes, (sizeof(attributes->fullAttributesString) / sizeof(wchar_t)));
4171             length = jniEnv->GetStringLength(js);
4172             attributes->fullAttributesString[length < (sizeof(attributes->fullAttributesString) / sizeof(wchar_t)) ?
4173                                              length : (sizeof(attributes->fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0;
4174             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE);
4175             jniEnv->ReleaseStringChars(js, stringBytes);
4176             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE);
4177             jniEnv->CallVoidMethod(accessBridgeObject,
4178                                    decrementReferenceMethod, js);
4179             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE);
4180             wPrintDebugString(L"[INFO]:   Accessible Text attributes = %ls", attributes->fullAttributesString);
4181             jniEnv->DeleteLocalRef(js);
4182             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
4183         } else {
4184             PrintDebugString("[WARN]:   Accessible Text attributes is null.");
4185             attributes->fullAttributesString[0] = (wchar_t) 0;
4186             jniEnv->DeleteLocalRef(AttributeSet);
4187             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
4188             return FALSE;
4189         }
4190     } else {
4191         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0");
4192         jniEnv->DeleteLocalRef(AttributeSet);
4193         return FALSE;
4194     }
4195 
4196     jniEnv->DeleteLocalRef(AttributeSet);
4197     EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to DeleteLocalRef()", FALSE);
4198     return TRUE;
4199 }
4200 
4201 BOOL
getAccessibleTextRect(jobject accessibleContext,AccessibleTextRectInfo * rectInfo,jint index)4202 AccessBridgeJavaEntryPoints::getAccessibleTextRect(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) {
4203 
4204     jthrowable exception;
4205 
4206     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextRect(%p), index = %d",
4207                      accessibleContext, index);
4208 
4209     // Verify the Java VM still exists and AccessibleContext is
4210     // an instance of AccessibleText
4211     if (verifyAccessibleText(accessibleContext) == FALSE) {
4212         return FALSE;
4213     }
4214 
4215     // Get the x coord
4216     if (getAccessibleXcoordTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4217         rectInfo->x = jniEnv->CallIntMethod(accessBridgeObject,
4218                                             getAccessibleXcoordTextRectAtIndexFromContextMethod,
4219                                             accessibleContext, index);
4220         EXCEPTION_CHECK("Getting AccessibleXcoordTextRect - call to CallIntMethod()", FALSE);
4221         PrintDebugString("[INFO]:  X coord = %d", rectInfo->x);
4222     } else {
4223         PrintDebugString("[ERROR]: either env == 0 or getAccessibleXcoordTextRectAtIndexFromContextMethod == 0");
4224         return FALSE;
4225     }
4226 
4227     // Get the y coord
4228     if (getAccessibleYcoordTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4229         rectInfo->y = jniEnv->CallIntMethod(accessBridgeObject,
4230                                             getAccessibleYcoordTextRectAtIndexFromContextMethod,
4231                                             accessibleContext, index);
4232         EXCEPTION_CHECK("Getting AccessibleYcoordTextRect - call to CallIntMethod()", FALSE);
4233         PrintDebugString("[INFO]:   Y coord = %d", rectInfo->y);
4234     } else {
4235         PrintDebugString("[INFO]:  either env == 0 or getAccessibleYcoordTextRectAtIndexFromContextMethod == 0");
4236         return FALSE;
4237     }
4238 
4239     // Get the width
4240     if (getAccessibleWidthTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4241         rectInfo->width = jniEnv->CallIntMethod(accessBridgeObject,
4242                                                 getAccessibleWidthTextRectAtIndexFromContextMethod,
4243                                                 accessibleContext, index);
4244         EXCEPTION_CHECK("Getting AccessibleWidthTextRect - call to CallIntMethod()", FALSE);
4245         PrintDebugString("[INFO]: Width = %d", rectInfo->width);
4246     } else {
4247         PrintDebugString("[INFO]: either env == 0 or getAccessibleWidthTextRectAtIndexFromContextMethod == 0");
4248         return FALSE;
4249     }
4250 
4251     // Get the height
4252     if (getAccessibleHeightTextRectAtIndexFromContextMethod != (jmethodID) 0) {
4253         rectInfo->height = jniEnv->CallIntMethod(accessBridgeObject,
4254                                                  getAccessibleHeightTextRectAtIndexFromContextMethod,
4255                                                  accessibleContext, index);
4256         EXCEPTION_CHECK("Getting AccessibleHeightTextRect - call to CallIntMethod()", FALSE);
4257         PrintDebugString("[INFO]: Height = %d", rectInfo->height);
4258     } else {
4259         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleHeightTextRectAtIndexFromContextMethod == 0");
4260         return FALSE;
4261     }
4262 
4263     return TRUE;
4264 }
4265 
4266 // =====
4267 
4268 /**
4269  * gets the bounding rectangle for the text caret
4270  */
4271 BOOL
getCaretLocation(jobject accessibleContext,AccessibleTextRectInfo * rectInfo,jint index)4272 AccessBridgeJavaEntryPoints::getCaretLocation(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) {
4273 
4274     jthrowable exception;
4275 
4276     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getCaretLocation(%p), index = %d",
4277                      accessibleContext, index);
4278 
4279     // Verify the Java VM still exists and AccessibleContext is
4280     // an instance of AccessibleText
4281     if (verifyAccessibleText(accessibleContext) == FALSE) {
4282         return FALSE;
4283     }
4284 
4285     // Get the x coord
4286     if (getCaretLocationXMethod != (jmethodID) 0) {
4287         rectInfo->x = jniEnv->CallIntMethod(accessBridgeObject,
4288                                             getCaretLocationXMethod,
4289                                             accessibleContext, index);
4290         EXCEPTION_CHECK("Getting caret X coordinate - call to CallIntMethod()", FALSE);
4291         PrintDebugString("[INFO]:   X coord = %d", rectInfo->x);
4292     } else {
4293         PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationXMethod == 0");
4294         return FALSE;
4295     }
4296 
4297     // Get the y coord
4298     if (getCaretLocationYMethod != (jmethodID) 0) {
4299         rectInfo->y = jniEnv->CallIntMethod(accessBridgeObject,
4300                                             getCaretLocationYMethod,
4301                                             accessibleContext, index);
4302         EXCEPTION_CHECK("Getting caret Y coordinate - call to CallIntMethod()", FALSE);
4303         PrintDebugString("[INFO]:   Y coord = %d", rectInfo->y);
4304     } else {
4305         PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationYMethod == 0");
4306         return FALSE;
4307     }
4308 
4309     // Get the width
4310     if (getCaretLocationWidthMethod != (jmethodID) 0) {
4311         rectInfo->width = jniEnv->CallIntMethod(accessBridgeObject,
4312                                                 getCaretLocationWidthMethod,
4313                                                 accessibleContext, index);
4314         EXCEPTION_CHECK("Getting caret width - call to CallIntMethod()", FALSE);
4315         PrintDebugString("[INFO]:   Width = %d", rectInfo->width);
4316     } else {
4317         PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationWidthMethod == 0");
4318         return FALSE;
4319     }
4320 
4321     // Get the height
4322     if (getCaretLocationHeightMethod != (jmethodID) 0) {
4323         rectInfo->height = jniEnv->CallIntMethod(accessBridgeObject,
4324                                                  getCaretLocationHeightMethod,
4325                                                  accessibleContext, index);
4326         EXCEPTION_CHECK("Getting caret height - call to CallIntMethod()", FALSE);
4327         PrintDebugString("[INFO]:   Height = %d", rectInfo->height);
4328     } else {
4329         PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationHeightMethod == 0");
4330         return FALSE;
4331     }
4332 
4333     return TRUE;
4334 }
4335 
4336 // =====
4337 
4338 BOOL
getAccessibleTextLineBounds(jobject accessibleContext,jint index,jint * startIndex,jint * endIndex)4339 AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(jobject accessibleContext, jint index, jint *startIndex, jint *endIndex) {
4340 
4341     jthrowable exception;
4342 
4343     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(%p):", accessibleContext);
4344 
4345     // Verify the Java VM still exists and AccessibleContext is
4346     // an instance of AccessibleText
4347     if (verifyAccessibleText(accessibleContext) == FALSE) {
4348         return FALSE;
4349     }
4350 
4351     // Get the index of the left boundary of the line containing 'index'
4352     if (getAccessibleTextLineLeftBoundsFromContextMethod != (jmethodID) 0) {
4353         *startIndex = jniEnv->CallIntMethod(accessBridgeObject,
4354                                             getAccessibleTextLineLeftBoundsFromContextMethod,
4355                                             accessibleContext, index);
4356         EXCEPTION_CHECK("Getting AccessibleTextLineLeftBounds - call to CallIntMethod()", FALSE);
4357         PrintDebugString("[INFO]:   startIndex = %d", *startIndex);
4358     } else {
4359         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextLineLeftBoundsFromContextMethod == 0");
4360         return FALSE;
4361     }
4362 
4363     // Get the index of the right boundary of the line containing 'index'
4364     if (getAccessibleTextLineRightBoundsFromContextMethod != (jmethodID) 0) {
4365         *endIndex = jniEnv->CallIntMethod(accessBridgeObject,
4366                                           getAccessibleTextLineRightBoundsFromContextMethod,
4367                                           accessibleContext, index);
4368         EXCEPTION_CHECK("Getting AccessibleTextLineRightBounds - call to CallIntMethod()", FALSE);
4369         PrintDebugString("[INFO]:   endIndex = %d", *endIndex);
4370     } else {
4371         PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextLineRightBoundsFromContextMethod == 0");
4372         return FALSE;
4373     }
4374 
4375     return TRUE;
4376 }
4377 
4378 BOOL
getAccessibleTextRange(jobject accessibleContext,jint start,jint end,wchar_t * text,short len)4379 AccessBridgeJavaEntryPoints::getAccessibleTextRange(jobject accessibleContext,
4380                                                     jint start, jint end, wchar_t *text, short len) {
4381     jstring js;
4382     const wchar_t *stringBytes;
4383     jthrowable exception;
4384     jsize length;
4385 
4386     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextRange(%p, %d, %d, *text, %d):", accessibleContext, start, end, len);
4387 
4388     // Verify the Java VM still exists and AccessibleContext is
4389     // an instance of AccessibleText
4390     if (verifyAccessibleText(accessibleContext) == FALSE) {
4391         return FALSE;
4392     }
4393 
4394     // range is inclusive
4395     if (end < start) {
4396         PrintDebugString("[ERROR]:  end < start!");
4397         text[0] = (wchar_t) 0;
4398         return FALSE;
4399     }
4400 
4401     // Get the text range within [start, end] inclusive
4402     if (getAccessibleTextRangeFromContextMethod != (jmethodID) 0) {
4403         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4404                                                 getAccessibleTextRangeFromContextMethod,
4405                                                 accessibleContext, start, end);
4406         EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallObjectMethod()", FALSE);
4407         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
4408         if (js != (jstring) 0) {
4409             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4410             EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringChars()", FALSE);
4411             wPrintDebugString(L"[INFO]:   Accessible Text stringBytes returned from Java = %ls", stringBytes);
4412             wcsncpy(text, stringBytes, len);
4413             length = jniEnv->GetStringLength(js);
4414             PrintDebugString("[INFO]:  Accessible Text stringBytes length = %d", length);
4415             text[length < len ? length : len - 2] = (wchar_t) 0;
4416             wPrintDebugString(L"[INFO]:   Accessible Text 'text' after null termination = %ls", text);
4417             EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringLength()", FALSE);
4418             jniEnv->ReleaseStringChars(js, stringBytes);
4419             EXCEPTION_CHECK("Getting AccessibleTextRange - call to ReleaseStringChars()", FALSE);
4420             jniEnv->CallVoidMethod(accessBridgeObject,
4421                                    decrementReferenceMethod, js);
4422             EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallVoidMethod()", FALSE);
4423             wPrintDebugString(L"[INFO]:   Accessible Text range = %ls", text);
4424             jniEnv->DeleteLocalRef(js);
4425             EXCEPTION_CHECK("Getting AccessibleTextRange - call to DeleteLocalRef()", FALSE);
4426         } else {
4427             PrintDebugString("[WARN]:   current Accessible Text range is null.");
4428             text[0] = (wchar_t) 0;
4429             return FALSE;
4430         }
4431     } else {
4432         PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextRangeFromContextMethod == 0");
4433         return FALSE;
4434     }
4435     return TRUE;
4436 }
4437 
4438 /********** AccessibleValue routines ***************/
4439 
4440 BOOL
getCurrentAccessibleValueFromContext(jobject accessibleContext,wchar_t * value,short len)4441 AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) {
4442     jstring js;
4443     const wchar_t *stringBytes;
4444     jthrowable exception;
4445     jsize length;
4446 
4447     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(%p):", accessibleContext);
4448 
4449     // Get the current Accessible Value
4450     if (getCurrentAccessibleValueFromContextMethod != (jmethodID) 0) {
4451         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4452                                                 getCurrentAccessibleValueFromContextMethod,
4453                                                 accessibleContext);
4454         EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallObjectMethod()", FALSE);
4455         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
4456         if (js != (jstring) 0) {
4457             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4458             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringChars()", FALSE);
4459             wcsncpy(value, stringBytes, len);
4460             length = jniEnv->GetStringLength(js);
4461             value[length < len ? length : len - 2] = (wchar_t) 0;
4462             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringLength()", FALSE);
4463             jniEnv->ReleaseStringChars(js, stringBytes);
4464             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to ReleaseStringChars()", FALSE);
4465             jniEnv->CallVoidMethod(accessBridgeObject,
4466                                    decrementReferenceMethod, js);
4467             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallVoidMethod()", FALSE);
4468             PrintDebugString("[INFO]:   current Accessible Value = %s", value);
4469             jniEnv->DeleteLocalRef(js);
4470             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to DeleteLocalRef()", FALSE);
4471         } else {
4472             PrintDebugString("[WARN]:   current Accessible Value is null.");
4473             value[0] = (wchar_t) 0;
4474             return FALSE;
4475         }
4476     } else {
4477         PrintDebugString("[ERROR]:  either env == 0 or getCurrentAccessibleValueFromContextMethod == 0");
4478         return FALSE;
4479     }
4480     return TRUE;
4481 }
4482 
4483 BOOL
getMaximumAccessibleValueFromContext(jobject accessibleContext,wchar_t * value,short len)4484 AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) {
4485     jstring js;
4486     const wchar_t *stringBytes;
4487     jthrowable exception;
4488     jsize length;
4489 
4490     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(%p):", accessibleContext);
4491 
4492     // Get the maximum Accessible Value
4493     if (getMaximumAccessibleValueFromContextMethod != (jmethodID) 0) {
4494         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4495                                                 getMaximumAccessibleValueFromContextMethod,
4496                                                 accessibleContext);
4497         EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallObjectMethod()", FALSE);
4498         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
4499         if (js != (jstring) 0) {
4500             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4501             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringChars()", FALSE);
4502             wcsncpy(value, stringBytes, len);
4503             length = jniEnv->GetStringLength(js);
4504             value[length < len ? length : len - 2] = (wchar_t) 0;
4505             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringLength()", FALSE);
4506             jniEnv->ReleaseStringChars(js, stringBytes);
4507             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to ReleaseStringChars()", FALSE);
4508             jniEnv->CallVoidMethod(accessBridgeObject,
4509                                    decrementReferenceMethod, js);
4510             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallVoidMethod()", FALSE);
4511             PrintDebugString("[INFO]:   maximum Accessible Value = %s", value);
4512             jniEnv->DeleteLocalRef(js);
4513             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to DeleteLocalRef()", FALSE);
4514         } else {
4515             PrintDebugString("[WARN]:   maximum Accessible Value is null.");
4516             value[0] = (wchar_t) 0;
4517             return FALSE;
4518         }
4519     } else {
4520         PrintDebugString("[ERROR]: either env == 0 or getMaximumAccessibleValueFromContextMethod == 0");
4521         return FALSE;
4522     }
4523     return TRUE;
4524 }
4525 
4526 BOOL
getMinimumAccessibleValueFromContext(jobject accessibleContext,wchar_t * value,short len)4527 AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) {
4528     jstring js;
4529     const wchar_t *stringBytes;
4530     jthrowable exception;
4531     jsize length;
4532 
4533     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(%p):", accessibleContext);
4534 
4535     // Get the mimimum Accessible Value
4536     if (getMinimumAccessibleValueFromContextMethod != (jmethodID) 0) {
4537         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
4538                                                 getMinimumAccessibleValueFromContextMethod,
4539                                                 accessibleContext);
4540         EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallObjectMethod()", FALSE);
4541         PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
4542         if (js != (jstring) 0) {
4543             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
4544             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringChars()", FALSE);
4545             wcsncpy(value, stringBytes, len);
4546             length = jniEnv->GetStringLength(js);
4547             value[length < len ? length : len - 2] = (wchar_t) 0;
4548             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringLength()", FALSE);
4549             jniEnv->ReleaseStringChars(js, stringBytes);
4550             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to ReleaseStringChars()", FALSE);
4551             jniEnv->CallVoidMethod(accessBridgeObject,
4552                                    decrementReferenceMethod, js);
4553             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallVoidMethod()", FALSE);
4554             PrintDebugString("[INFO]:   mimimum Accessible Value = %s", value);
4555             jniEnv->DeleteLocalRef(js);
4556             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to DeleteLocalRef()", FALSE);
4557         } else {
4558             PrintDebugString("[WARN]:   mimimum Accessible Value is null.");
4559             value[0] = (wchar_t) 0;
4560             return FALSE;
4561         }
4562     } else {
4563         PrintDebugString("[ERROR]: either env == 0 or getMinimumAccessibleValueFromContextMethod == 0");
4564         return FALSE;
4565     }
4566     return TRUE;
4567 }
4568 
4569 
4570 /********** AccessibleSelection routines ***************/
4571 
4572 void
addAccessibleSelectionFromContext(jobject accessibleContext,int i)4573 AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(jobject accessibleContext, int i) {
4574     jthrowable exception;
4575 
4576     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(%p):", accessibleContext);
4577 
4578     // Add the child to the AccessibleSelection
4579     if (addAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4580         jniEnv->CallVoidMethod(accessBridgeObject,
4581                                addAccessibleSelectionFromContextMethod,
4582                                accessibleContext, i);
4583         EXCEPTION_CHECK_VOID("Doing addAccessibleSelection - call to CallVoidMethod()");
4584         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4585     } else {
4586         PrintDebugString("[ERROR]:  either env == 0 or addAccessibleSelectionFromContextMethod == 0");
4587     }
4588 }
4589 
4590 void
clearAccessibleSelectionFromContext(jobject accessibleContext)4591 AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(jobject accessibleContext) {
4592     jthrowable exception;
4593 
4594     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(%p):", accessibleContext);
4595 
4596     // Clearing the Selection of the AccessibleSelection
4597     if (clearAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4598         jniEnv->CallVoidMethod(accessBridgeObject,
4599                                clearAccessibleSelectionFromContextMethod,
4600                                accessibleContext);
4601         EXCEPTION_CHECK_VOID("Doing clearAccessibleSelection - call to CallVoidMethod()");
4602         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4603     } else {
4604         PrintDebugString("[ERROR]:  either env == 0 or clearAccessibleSelectionFromContextMethod == 0");
4605     }
4606 }
4607 
4608 jobject
getAccessibleSelectionFromContext(jobject accessibleContext,int i)4609 AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(jobject accessibleContext, int i) {
4610     jobject returnedAccessibleContext;
4611     jobject globalRef;
4612     jthrowable exception;
4613 
4614     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(%p):", accessibleContext);
4615 
4616     if (getAccessibleSelectionContextFromContextMethod != (jmethodID) 0) {
4617         returnedAccessibleContext = jniEnv->CallObjectMethod(
4618                                                              accessBridgeObject,
4619                                                              getAccessibleSelectionContextFromContextMethod,
4620                                                              accessibleContext, i);
4621         EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to CallObjectMethod()", (jobject) 0);
4622         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
4623         EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to NewGlobalRef()", (jobject) 0);
4624         jniEnv->DeleteLocalRef(returnedAccessibleContext);
4625         EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to DeleteLocalRef()", (jobject) 0);
4626         PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
4627                          returnedAccessibleContext, globalRef);
4628         return globalRef;
4629     } else {
4630         PrintDebugString("[ERROR]: either env == 0 or getAccessibleSelectionContextFromContextMethod == 0");
4631         return (jobject) 0;
4632     }
4633 }
4634 
4635 int
getAccessibleSelectionCountFromContext(jobject accessibleContext)4636 AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(jobject accessibleContext) {
4637     int count;
4638     jthrowable exception;
4639 
4640     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(%p):", accessibleContext);
4641 
4642     // Get (& return) the # of items selected in the AccessibleSelection
4643     if (getAccessibleSelectionCountFromContextMethod != (jmethodID) 0) {
4644         count = jniEnv->CallIntMethod(accessBridgeObject,
4645                                       getAccessibleSelectionCountFromContextMethod,
4646                                       accessibleContext);
4647         EXCEPTION_CHECK("Getting AccessibleSelectionCount - call to CallIntMethod()", -1);
4648         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4649         return count;
4650     } else {
4651         PrintDebugString("[ERROR]: either env == 0 or getAccessibleSelectionCountFromContextMethod == 0");
4652         return -1;
4653     }
4654 }
4655 
4656 BOOL
isAccessibleChildSelectedFromContext(jobject accessibleContext,int i)4657 AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(jobject accessibleContext, int i) {
4658     jboolean result;
4659     jthrowable exception;
4660 
4661     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(%p):", accessibleContext);
4662 
4663     // Get (& return) the # of items selected in the AccessibleSelection
4664     if (isAccessibleChildSelectedFromContextMethod != (jmethodID) 0) {
4665         result = jniEnv->CallBooleanMethod(accessBridgeObject,
4666                                            isAccessibleChildSelectedFromContextMethod,
4667                                            accessibleContext, i);
4668         EXCEPTION_CHECK("Doing isAccessibleChildSelected - call to CallBooleanMethod()", FALSE);
4669         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4670         if (result != 0) {
4671             return TRUE;
4672         }
4673     } else {
4674         PrintDebugString("[ERROR]: either env == 0 or isAccessibleChildSelectedFromContextMethod == 0");
4675     }
4676     return FALSE;
4677 }
4678 
4679 
4680 void
removeAccessibleSelectionFromContext(jobject accessibleContext,int i)4681 AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(jobject accessibleContext, int i) {
4682     jthrowable exception;
4683 
4684     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(%p):", accessibleContext);
4685 
4686     // Remove the i-th child from the AccessibleSelection
4687     if (removeAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4688         jniEnv->CallVoidMethod(accessBridgeObject,
4689                                removeAccessibleSelectionFromContextMethod,
4690                                accessibleContext, i);
4691         EXCEPTION_CHECK_VOID("Doing removeAccessibleSelection - call to CallVoidMethod()");
4692         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4693     } else {
4694         PrintDebugString("[ERROR]:  either env == 0 or removeAccessibleSelectionFromContextMethod == 0");
4695     }
4696 }
4697 
4698 void
selectAllAccessibleSelectionFromContext(jobject accessibleContext)4699 AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(jobject accessibleContext) {
4700     jthrowable exception;
4701 
4702     PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(%p):", accessibleContext);
4703 
4704     // Select all children (if possible) of the AccessibleSelection
4705     if (selectAllAccessibleSelectionFromContextMethod != (jmethodID) 0) {
4706         jniEnv->CallVoidMethod(accessBridgeObject,
4707                                selectAllAccessibleSelectionFromContextMethod,
4708                                accessibleContext);
4709         EXCEPTION_CHECK_VOID("Doing selectAllAccessibleSelection - call to CallVoidMethod()");
4710         PrintDebugString("[INFO]:   returned from CallObjectMethod()");
4711     } else {
4712         PrintDebugString("[ERROR]: either env == 0 or selectAllAccessibleSelectionFromContextMethod == 0");
4713     }
4714 }
4715 
4716 
4717 /********** Event Notification Registration routines ***************/
4718 
4719 BOOL
addJavaEventNotification(jlong type)4720 AccessBridgeJavaEntryPoints::addJavaEventNotification(jlong type) {
4721     jthrowable exception;
4722 
4723     PrintDebugString("[INFO]:   in AccessBridgeJavaEntryPoints::addJavaEventNotification(%016I64X);", type);
4724 
4725     // Let AccessBridge know we want to add an event type
4726     if (addJavaEventNotificationMethod != (jmethodID) 0) {
4727         jniEnv->CallVoidMethod(accessBridgeObject,
4728                                addJavaEventNotificationMethod, type);
4729         EXCEPTION_CHECK("Doing addJavaEventNotification - call to CallVoidMethod()", FALSE);
4730     } else {
4731         PrintDebugString("[ERROR]: either env == 0 or addJavaEventNotificationMethod == 0");
4732         return FALSE;
4733     }
4734     return TRUE;
4735 }
4736 
4737 BOOL
removeJavaEventNotification(jlong type)4738 AccessBridgeJavaEntryPoints::removeJavaEventNotification(jlong type) {
4739     jthrowable exception;
4740 
4741     PrintDebugString("[INFO]:  in AccessBridgeJavaEntryPoints::removeJavaEventNotification(%016I64X):", type);
4742 
4743     // Let AccessBridge know we want to remove an event type
4744     if (removeJavaEventNotificationMethod != (jmethodID) 0) {
4745         jniEnv->CallVoidMethod(accessBridgeObject,
4746                                removeJavaEventNotificationMethod, type);
4747         EXCEPTION_CHECK("Doing removeJavaEventNotification - call to CallVoidMethod()", FALSE);
4748     } else {
4749         PrintDebugString("[ERROR]: either env == 0 or removeJavaEventNotificationMethod == 0");
4750         return FALSE;
4751     }
4752     return TRUE;
4753 }
4754 
4755 BOOL
addAccessibilityEventNotification(jlong type)4756 AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(jlong type) {
4757     jthrowable exception;
4758 
4759     PrintDebugString("[INFO]:   in AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(%016I64X);", type);
4760 
4761     // Let AccessBridge know we want to add an event type
4762     if (addAccessibilityEventNotificationMethod != (jmethodID) 0) {
4763         PrintDebugString("[INFO]:    addAccessibilityEventNotification: calling void method: accessBridgeObject = %p", accessBridgeObject);
4764         jniEnv->CallVoidMethod(accessBridgeObject,
4765                                addAccessibilityEventNotificationMethod, type);
4766         EXCEPTION_CHECK("Doing addAccessibilityEvent - call to CallVoidMethod()", FALSE);
4767     } else {
4768         PrintDebugString("[ERROR]: either env == 0 or addAccessibilityEventNotificationMethod == 0");
4769         return FALSE;
4770     }
4771     PrintDebugString("[INFO]:     addAccessibilityEventNotification: just returning true");
4772     return TRUE;
4773 }
4774 
4775 BOOL
removeAccessibilityEventNotification(jlong type)4776 AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(jlong type) {
4777     jthrowable exception;
4778 
4779     PrintDebugString("[INFO]:  in AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(%016I64X):", type);
4780 
4781     // Let AccessBridge know we want to remove an event type
4782     if (removeAccessibilityEventNotificationMethod != (jmethodID) 0) {
4783         jniEnv->CallVoidMethod(accessBridgeObject,
4784                                removeAccessibilityEventNotificationMethod, type);
4785         EXCEPTION_CHECK("Doing removeAccessibilityEvent - call to CallVoidMethod()", FALSE);
4786     } else {
4787         PrintDebugString("[ERROR]: either env == 0 or removeAccessibilityEventNotificationMethod == 0");
4788         return FALSE;
4789     }
4790     return TRUE;
4791 }
4792