1 /*
2  * Copyright (c) 2005, 2020, 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 DLL which is loaded by Windows executables to handle communication
28  * between Java VMs purposes of Accessbility.
29  */
30 
31 #include "AccessBridgeDebug.h"
32 #include "WinAccessBridge.h"
33 #include "accessBridgeResource.h"
34 #include "accessBridgeCallbacks.h"
35 #include "AccessBridgeMessages.h"
36 #include "AccessBridgeMessageQueue.h"
37 
38 #include <windows.h>
39 #include <jni.h>
40 #include <stdio.h>
41 
42 // send memory lock
43 //
44 // This lock is need to serialize access to the buffer used by sendMemoryPackage.
45 // If a JVM goes away while the associated memory buffer is in use, a thread switch
46 // allows a call to JavaVMDestroyed and deallocation of the memory buffer.
47 CRITICAL_SECTION sendMemoryIPCLock;
48 
49 // registry paths to newly found JVMs that don't have the bridge installed
50 char **newJVMs;
51 
52 WinAccessBridge *theWindowsAccessBridge;
53 HWND theDialogWindow;
54 
55 // unique broadcast msg. IDs gotten dymanically
56 extern UINT theFromJavaHelloMsgID;
57 extern UINT theFromWindowsHelloMsgID;
58 
59 // protects the javaVMs chain while in use
60 bool isVMInstanceChainInUse;
61 
62 /* =================================================================================== */
63 
64 
65 
66 /**
67  * Proc for "New JVM Found" dialog
68  */
newJVMFoundDialogProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)69 BOOL CALLBACK newJVMFoundDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) {
70 
71     switch (message) {
72     case WM_COMMAND:
73         // PrintDebugString("    newJVMDialogProc: LOWORD(wParam) = %d", LOWORD(wParam));
74 
75         switch (LOWORD(wParam)) {
76 
77             // Remind user later that a new JVM was installed
78         case cRemindThereIsNewJVM:
79             PrintDebugString("[INFO]:    newJVMDialogProc: cRemindThereIsNewJVM");
80             // do nothing
81             EndDialog(hwndDlg, wParam);
82             return TRUE;
83 
84             // Do not remind user later that a new JVM was installed
85             /*
86         case cDoNotRemindThereIsNewJVM:
87             PrintDebugString("    newJVMDialogProc: cDoNotRemindThereIsNewJVM");
88             // remember to not remind the user there are new JVMs
89             PrintDebugString("theWindowsAccessBridge = %x", theWindowsAccessBridge);
90             if (theWindowsAccessBridge != NULL) {
91                 dontRemindUser(newJVMs);
92             }
93             EndDialog(hwndDlg, wParam);
94             return TRUE;
95             */
96 
97             // Run the AccessBridge installer
98             /*
99         case cInstallAccessBridge:
100             PrintDebugString("    newJVMDialogProc: cInstallAccessBridge");
101             // start the installer
102             if (theWindowsAccessBridge != NULL) {
103                 startInstaller(newJVMs);
104             }
105             EndDialog(hwndDlg, wParam);
106             return TRUE;
107             */
108 
109         default:
110             ;
111         }
112     default:
113         ;
114     }
115     return FALSE;
116 }
117 
118 
119 
120 /* =========================================================================== */
121 
122 // ---------------------------------------------------------------------------
123 
124 extern "C" {
125     /**
126      * DllMain - where Windows executables will load/unload us
127      *
128      */
DllMain(HINSTANCE hinstDll,DWORD fdwReason,LPVOID lpvReserved)129     BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) {
130 
131         switch (fdwReason) {
132         case DLL_PROCESS_ATTACH:        // A Windows executable loaded us
133             initializeFileLogger("windows_access_bridge");
134             PrintDebugString("[INFO]: DLL_PROCESS_ATTACH");
135             theWindowsAccessBridge = new WinAccessBridge(hinstDll);
136             break;
137 
138         case DLL_PROCESS_DETACH:        // A Windows executable unloaded us
139             if (theWindowsAccessBridge != (WinAccessBridge *) 0) {
140                 PrintDebugString("[INFO]: *** AccessBridgeDialogProc -> deleting theWindowsAccessBridge");
141                 delete theWindowsAccessBridge;
142             }
143             break;
144         }
145 
146         return(TRUE);
147     }
148 
149     /**
150      * Append debug info to dialog
151      *
152      * replaced with code to send output to debug file
153      *
154      */
AppendToCallInfo(char * s)155     void AppendToCallInfo(char *s) {
156 
157         /*
158           _CrtDbgReport(_CRT_WARN, (const char *) NULL, NULL, (const char *) NULL,
159           (const char *) "WinAccessBridge: %s", s);
160         */
161 
162         char buf[1024];
163         sprintf(buf, "WinAccessBridge: %s", s);
164         OutputDebugString(buf);
165     }
166 
167     /**
168      * Our window proc
169      *
170      */
AccessBridgeDialogProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)171     BOOL CALLBACK AccessBridgeDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
172         COPYDATASTRUCT *sentToUs;
173         char *package;
174 
175         switch (message) {
176         case WM_INITDIALOG:
177             PrintDebugString("[INFO]: AccessBridgeDialogProc -> Initializing");
178             break;
179 
180             // call from Java with data for us to deliver
181         case WM_COPYDATA:
182             if (theDialogWindow == (HWND) wParam) {
183                 PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got WM_COPYDATA from Java Bridge DLL");
184             } else {
185                 PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got WM_COPYDATA from HWND %p", wParam);
186                 sentToUs = (COPYDATASTRUCT *) lParam;
187                 package = (char *) sentToUs->lpData;
188                 theWindowsAccessBridge->preProcessPackage(package, sentToUs->cbData);
189             }
190             break;
191 
192             // message to ourselves -> de-queue messages and send 'em
193         case AB_MESSAGE_QUEUED:
194             PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got AB_MESSAGE_QUEUED from ourselves");
195             theWindowsAccessBridge->receiveAQueuedPackage();
196             break;
197 
198             // a JavaAccessBridge DLL is going away
199             //
200             // When JavaVMDestroyed is called a AccessBridgeJavaVMInstance in the
201             // javaVMs chain will be removed.  If that chain is in use this will
202             // cause a crash.  One way AB_DLL_GOING_AWAY can arrive is on any
203             // outgoing SendMessage call.  SendMessage normally spins waiting for
204             // a response.  However, if there is an incoming SendMessage, e.g. for
205             // AB_DLL_GOING_AWAY Windows will send that request to this DialogProc.
206             // One seemingly easy way to combat that is to use SendMessageTimeout
207             // with the SMTO_BLOCK flag set.  However, it has been the case that
208             // even after using that technique AB_DLL_GOING_AWAY can still arrive
209             // in the middle of processing the javaVMs chain.  An alternative that
210             // was tried was to use a critical section around any access ot the
211             // javaVMs chain but unfortunately the AB_DLL_GOING_AWAY message arrives
212             // on the same thread and thus the use of a critical section is ineffective.
213             // The solution then is to set a flag whenever the javaVMs chain is being
214             // used and if that flag is set at this point the message will be posted
215             // to the message queue.  That would delay the destruction of the instance
216             // until the chain is not being traversed.
217         case AB_DLL_GOING_AWAY:
218             PrintDebugString("[INFO]: ***** AccessBridgeDialogProc -> Got AB_DLL_GOING_AWAY message");
219             if (isVMInstanceChainInUse) {
220                 PrintDebugString("[INFO]:   javaVMs chain in use, calling PostMessage");
221                 PostMessage(hDlg, AB_DLL_GOING_AWAY, wParam, (LPARAM)0);
222             } else {
223                 PrintDebugString("[INFO]:   calling javaVMDestroyed");
224                 theWindowsAccessBridge->JavaVMDestroyed((HWND) wParam);
225             }
226             break;
227 
228         default:
229             // the JavaVM is saying "hi"!
230             // wParam == sourceHwnd; lParam == JavaVMID
231             if (message == theFromJavaHelloMsgID) {
232                 PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got theFromJavaHelloMsgID; wParam = %p, lParam = %p", wParam, lParam);
233                 theWindowsAccessBridge->rendezvousWithNewJavaDLL((HWND) wParam, (long ) lParam);
234             }
235             break;
236         }
237 
238         return (FALSE);
239     }
240 
241 }
242 
243 
244 
245 
246 // ---------------------------------------------------------------------------
247 
248 /**
249  * Initialize the WinAccessBridge
250  *
251  */
WinAccessBridge(HINSTANCE hInstance)252 WinAccessBridge::WinAccessBridge(HINSTANCE hInstance) {
253 
254     PrintDebugString("[INFO]: WinAccessBridge ctor");
255 
256     //  IntializeCriticalSection should only be called once.
257     InitializeCriticalSection(&sendMemoryIPCLock);
258     windowsInstance = hInstance;
259     javaVMs = (AccessBridgeJavaVMInstance *) 0;
260     eventHandler = new AccessBridgeEventHandler();
261     messageQueue = new AccessBridgeMessageQueue();
262     initBroadcastMessageIDs();          // get the unique to us broadcast msg. IDs
263     theWindowsAccessBridge = this;
264     isVMInstanceChainInUse = false;
265 
266     ShowWindow(theDialogWindow, SW_SHOW);
267 }
268 
269 
270 
271 /**
272  * Destroy the WinAccessBridge
273  *
274  */
~WinAccessBridge()275 WinAccessBridge::~WinAccessBridge() {
276     // inform all other AccessBridges that we're going away
277     //  -> shut down all event listening
278     //  -> release all objects held in the JVM by us
279 
280     PrintDebugString("[INFO]: *****in WinAccessBridge::~WinAccessBridge()");
281 
282     // send a broadcast msg.; let other AccessBridge DLLs know we're going away
283     AccessBridgeJavaVMInstance *current = javaVMs;
284     while (current != (AccessBridgeJavaVMInstance *) 0) {
285         PrintDebugString("[INFO]:   telling %p we're going away", current->javaAccessBridgeWindow);
286         SendMessage(current->javaAccessBridgeWindow,
287                     AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0);
288         current = current->nextJVMInstance;
289     }
290 
291     PrintDebugString("[INFO]:   finished telling JVMs about our demise");
292 
293     delete eventHandler;
294     delete messageQueue;
295     delete javaVMs;
296 
297     PrintDebugString("[INFO]:   finished deleting eventHandler, messageQueue, and javaVMs");
298     PrintDebugString("[INFO]: GOODBYE CRUEL WORLD...");
299     finalizeFileLogger();
300     DestroyWindow(theDialogWindow);
301 }
302 
303 
304 /**
305  * Bring up our window; make a connection to the rest of the world
306  *
307  */
308 BOOL
initWindow()309 WinAccessBridge::initWindow() {
310     theDialogWindow = CreateDialog(windowsInstance,
311                                    "ACCESSBRIDGESTATUSWINDOW", NULL,
312                                    (DLGPROC) AccessBridgeDialogProc);
313 
314     // If window could not be created, return "failure".
315     if (!theDialogWindow)
316         return (FALSE);
317 
318     dialogWindow = theDialogWindow;
319 
320     // Make the window visible, update its client area, & return "success".
321     // DEBUG_CODE(ShowWindow (theDialogWindow, SW_SHOWNORMAL));
322     // DEBUG_CODE(UpdateWindow (theDialogWindow));
323 
324     // post a broadcast msg.; let other AccessBridge DLLs know we exist
325     PostMessage(HWND_BROADCAST, theFromWindowsHelloMsgID, (WPARAM) dialogWindow, (LPARAM) 0);
326 
327     return (TRUE);
328 }
329 
330 // -----------------------
331 
332 /**
333  * rendezvousWithNewJavaDLL
334  *              - Build AccessBridgeJavaVMInstance data structure
335  *                (including setting up Memory-Mapped file info)
336  *
337  */
338 LRESULT
rendezvousWithNewJavaDLL(HWND JavaBridgeDLLwindow,long vmID)339 WinAccessBridge::rendezvousWithNewJavaDLL(HWND JavaBridgeDLLwindow, long vmID) {
340     LRESULT returnVal;
341 
342     PrintDebugString("[INFO]: in WinAccessBridge::rendezvousWithNewJavaDLL(%p, %X)",
343                      JavaBridgeDLLwindow, vmID);
344 
345     isVMInstanceChainInUse = true;
346     AccessBridgeJavaVMInstance *newVM =
347         new AccessBridgeJavaVMInstance(dialogWindow, JavaBridgeDLLwindow, vmID, javaVMs);
348     javaVMs = newVM;
349     isVMInstanceChainInUse = false;
350 
351     returnVal = javaVMs->initiateIPC();
352     if (returnVal == 0) {
353 
354         // tell the newly created JavaVM what events we're interested in, if any
355         long javaEventMask = eventHandler->getJavaEventMask();
356         long accessibilityEventMask = eventHandler->getAccessibilityEventMask();
357 
358         PrintDebugString("[INFO]:   Setting Java event mask to: %X", javaEventMask);
359 
360         if (javaEventMask != 0) {
361             addJavaEventNotification(javaEventMask);
362         }
363 
364         PrintDebugString("[INFO]:   Setting Accessibility event mask to: %X", accessibilityEventMask);
365 
366         if (accessibilityEventMask != 0) {
367             addAccessibilityEventNotification(accessibilityEventMask);
368         }
369     } else {
370         PrintDebugString("[ERROR]: Failed to initiate IPC with newly created JavaVM!!!");
371         return FALSE;
372     }
373 
374     PrintDebugString("[INFO]:   Success!!  We rendezvoused with the JavaDLL");
375     return returnVal;
376 }
377 
378 // -----------------------
379 
380 /**
381  * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging
382  *               with the Java AccessBridge DLL
383  *
384  *               NOTE: WM_COPYDATA is only for one-way IPC; there
385  *               is now way to return parameters (especially big ones)
386  *               Use sendMemoryPackage() to do that!
387  */
388 void
sendPackage(char * buffer,long bufsize,HWND destWindow)389 WinAccessBridge::sendPackage(char *buffer, long bufsize, HWND destWindow) {
390     COPYDATASTRUCT toCopy;
391     toCopy.dwData = 0;          // 32-bits we could use for something...
392     toCopy.cbData = bufsize;
393     toCopy.lpData = buffer;
394 
395     SendMessage(destWindow, WM_COPYDATA, (WPARAM) dialogWindow, (LPARAM) &toCopy);
396 }
397 
398 
399 /**
400  * sendMemoryPackage - uses Memory-Mapped files to do IPC messaging
401  *                     with the Java AccessBridge DLL, informing the
402  *                     Java AccessBridge DLL via SendMessage that something
403  *                     is waiting for it in the shared file...
404  *
405  *                     In the SendMessage call, the third param (WPARAM) is
406  *                     the source HWND (theDialogWindow in this case), and
407  *                     the fourth param (LPARAM) is the size in bytes of
408  *                     the package put into shared memory.
409  *
410  */
411 BOOL
sendMemoryPackage(char * buffer,long bufsize,HWND destWindow)412 WinAccessBridge::sendMemoryPackage(char *buffer, long bufsize, HWND destWindow) {
413     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
414         return FALSE;
415     }
416     AccessBridgeJavaVMInstance *ourABJavaVMInstance;
417     ourABJavaVMInstance = javaVMs->findABJavaVMInstanceFromJavaHWND(destWindow);
418     if (ourABJavaVMInstance != (AccessBridgeJavaVMInstance *) 0) {
419         if (!ourABJavaVMInstance->sendMemoryPackage(buffer, bufsize)) {
420             // return falue to the caller
421             memset(buffer, 0, bufsize);
422             return FALSE;
423         }
424     } else {
425         PrintDebugString("[ERROR]: sending memory package: couldn't find destWindow");
426         return FALSE;
427     }
428     return TRUE;
429 }
430 
431 
432 /**
433  * queuePackage - put a package onto the queue for latter processing
434  *
435  */
436 BOOL
queuePackage(char * buffer,long bufsize)437 WinAccessBridge::queuePackage(char *buffer, long bufsize) {
438     PrintDebugString("[INFO]:  in WinAccessBridge::queuePackage(%p, %d)", buffer, bufsize);
439 
440     AccessBridgeQueueElement *element = new AccessBridgeQueueElement(buffer, bufsize);
441 
442     messageQueue->add(element);
443     PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0);
444     return TRUE;
445 }
446 
447 
448 /**
449  * receiveAQueuedPackage - remove a pending packge from the queue and
450  *                         handle it. If the queue is busy, post a
451  *                         message to self to retrieve it later
452  *
453  */
454 BOOL
receiveAQueuedPackage()455 WinAccessBridge::receiveAQueuedPackage() {
456     AccessBridgeQueueElement *element = NULL;
457 
458     PrintDebugString("[INFO]: in WinAccessBridge::receiveAQueuedPackage()");
459 
460     // ensure against re-entrancy problems...
461     if (messageQueue->getRemoveLockSetting() == FALSE) {
462         messageQueue->setRemoveLock(TRUE);
463 
464         PrintDebugString("[INFO]:  dequeueing message");
465 
466         QueueReturns result = messageQueue->remove(&element);
467 
468         switch (result) {
469 
470         case cQueueBroken:
471             PrintDebugString("[ERROR]: Queue seems to be broken!");
472             messageQueue->setRemoveLock(FALSE);
473             return FALSE;
474 
475         case cMoreMessages:
476         case cQueueEmpty:
477             if (element != (AccessBridgeQueueElement *) 0) {
478                 PrintDebugString("[INFO]:  found one; sending it!");
479                 processPackage(element->buffer, element->bufsize);
480                 delete element;
481             } else {
482                 PrintDebugString("[WARN]:   ODD... element == 0!");
483                 return FALSE;
484             }
485             break;
486 
487         case cQueueInUse:
488             PrintDebugString("[WARN]:  Queue in use, will try again later...");
489             PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0);
490             break;
491 
492         default:
493             messageQueue->setRemoveLock(FALSE);
494             return FALSE;       // should never get something we don't recognize!
495         }
496     } else {
497         PrintDebugString("[WARN]:  unable to dequeue message; remove lock is set");
498         PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); // Fix for 6995891
499     }
500 
501     messageQueue->setRemoveLock(FALSE);
502     return TRUE;
503 }
504 
505 // -----------------------
506 
507 /**
508  * preProcessPackage
509  *              - do triage on incoming packages; queue some, deal with others
510  *
511  */
512 void
preProcessPackage(char * buffer,long bufsize)513 WinAccessBridge::preProcessPackage(char *buffer, long bufsize) {
514     PrintDebugString("[INFO]: PreProcessing package sent from Java:");
515 
516     PackageType *type = (PackageType *) buffer;
517 
518     switch (*type) {
519 
520     PrintDebugString("[INFO]:    type == %X", *type);
521 
522     // event packages all get queued for later handling
523     //case cPropertyChangePackage:
524     case cJavaShutdownPackage:
525     case cFocusGainedPackage:
526     case cFocusLostPackage:
527     case cCaretUpdatePackage:
528     case cMouseClickedPackage:
529     case cMouseEnteredPackage:
530     case cMouseExitedPackage:
531     case cMousePressedPackage:
532     case cMouseReleasedPackage:
533     case cMenuCanceledPackage:
534     case cMenuDeselectedPackage:
535     case cMenuSelectedPackage:
536     case cPopupMenuCanceledPackage:
537     case cPopupMenuWillBecomeInvisiblePackage:
538     case cPopupMenuWillBecomeVisiblePackage:
539 
540     case cPropertyCaretChangePackage:
541     case cPropertyDescriptionChangePackage:
542     case cPropertyNameChangePackage:
543     case cPropertySelectionChangePackage:
544     case cPropertyStateChangePackage:
545     case cPropertyTextChangePackage:
546     case cPropertyValueChangePackage:
547     case cPropertyVisibleDataChangePackage:
548     case cPropertyChildChangePackage:
549     case cPropertyActiveDescendentChangePackage:
550 
551     case cPropertyTableModelChangePackage:
552 
553         queuePackage(buffer, bufsize);
554         break;
555 
556         // perhaps there will be some other packages to process at some point... //
557 
558     default:
559         PrintDebugString("[ERROR]:   processing FAILED!! -> don't know how to handle type = %X", *type);
560         break;
561     }
562 
563     PrintDebugString("[INFO]:    package preprocessing completed");
564 }
565 
566 
567 #define DISPATCH_EVENT_PACKAGE(packageID, eventPackage, fireEventMethod)            \
568     case packageID:                                                                 \
569         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
570             eventPackage *pkg =                                                     \
571                 (eventPackage *) (buffer + sizeof(PackageType));                    \
572             PrintDebugString("[INFO]:    begin callback to AT, type == %X", *type);         \
573                 theWindowsAccessBridge->eventHandler->fireEventMethod(              \
574                     pkg->vmID, pkg->Event, pkg->AccessibleContextSource);           \
575                 PrintDebugString("[INFO]:    event callback complete!");                    \
576         } else {                                                                    \
577             PrintDebugString("[ERROR]:   processing FAILED!! -> bufsize = %d; expectation = %d", \
578                 bufsize, sizeof(PackageType) + sizeof(eventPackage));               \
579         }                                                                           \
580         break;
581 
582 #define DISPATCH_PROPERTY_CHANGE_PACKAGE(packageID, eventPackage, fireEventMethod, oldValue, newValue) \
583     case packageID:                                                                 \
584         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
585             eventPackage *pkg =                                                     \
586                 (eventPackage *) (buffer + sizeof(PackageType));                    \
587             PrintDebugString("[INFO]:    begin callback to AT, type == %X", *type);         \
588             theWindowsAccessBridge->eventHandler->fireEventMethod(                  \
589                 pkg->vmID, pkg->Event, pkg->AccessibleContextSource,                \
590                 pkg->oldValue, pkg->newValue);                                      \
591             PrintDebugString("[INFO]:    event callback complete!");                        \
592         } else {                                                                    \
593             PrintDebugString("[ERROR]:   processing FAILED!! -> bufsize = %d; expectation = %d", \
594                 bufsize, sizeof(PackageType) + sizeof(eventPackage));               \
595         }                                                                           \
596         break;
597 
598 #define DISPATCH_PROPERTY_TABLE_MODEL_CHANGE_PACKAGE(packageID, eventPackage, fireEventMethod, oldValue, newValue) \
599     case packageID:                                                                 \
600         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
601             eventPackage *pkg =                                                     \
602                 (eventPackage *) (buffer + sizeof(PackageType));                    \
603             PrintDebugString("[INFO]:    begin callback to AT, type == %X", *type);         \
604             theWindowsAccessBridge->eventHandler->fireEventMethod(                  \
605                 pkg->vmID, pkg->Event, pkg->AccessibleContextSource,                \
606                 pkg->oldValue, pkg->newValue);                                      \
607             PrintDebugString("[INFO]:    event callback complete!");                        \
608         } else {                                                                    \
609             PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d", \
610                 bufsize, sizeof(PackageType) + sizeof(eventPackage));                \
611         }                                                                            \
612         break;
613 
614 /**
615  * processPackage - processes the output of SendMessage(WM_COPYDATA)
616  *                  to do IPC messaging with the Java AccessBridge DLL
617  *
618  */
619 void
processPackage(char * buffer,long bufsize)620 WinAccessBridge::processPackage(char *buffer, long bufsize) {
621     PrintDebugString("[INFO]: WinAccessBridge::Processing package sent from Java:");
622 
623     PackageType *type = (PackageType *) buffer;
624 
625     switch (*type) {
626 
627     PrintDebugString("[INFO]:    type == %X", *type);
628 
629     case cJavaShutdownPackage:
630         PrintDebugString("[INFO]:    type == cJavaShutdownPackage");
631         if (bufsize == sizeof(PackageType) + sizeof(JavaShutdownPackage)) {
632             JavaShutdownPackage *pkg =
633                 (JavaShutdownPackage *) (buffer + sizeof(PackageType));
634             theWindowsAccessBridge->eventHandler->fireJavaShutdown(pkg->vmID);
635             PrintDebugString("[INFO]:    event callback complete!");
636             PrintDebugString("[INFO]:    event fired!");
637         } else {
638             PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
639                              bufsize, sizeof(PackageType) + sizeof(JavaShutdownPackage));
640         }
641         break;
642 
643 
644         DISPATCH_EVENT_PACKAGE(cFocusGainedPackage, FocusGainedPackage, fireFocusGained);
645         DISPATCH_EVENT_PACKAGE(cFocusLostPackage, FocusLostPackage, fireFocusLost);
646 
647         DISPATCH_EVENT_PACKAGE(cCaretUpdatePackage, CaretUpdatePackage, fireCaretUpdate);
648 
649         DISPATCH_EVENT_PACKAGE(cMouseClickedPackage, MouseClickedPackage, fireMouseClicked);
650         DISPATCH_EVENT_PACKAGE(cMouseEnteredPackage, MouseEnteredPackage, fireMouseEntered);
651         DISPATCH_EVENT_PACKAGE(cMouseExitedPackage, MouseExitedPackage, fireMouseExited);
652         DISPATCH_EVENT_PACKAGE(cMousePressedPackage, MousePressedPackage, fireMousePressed);
653         DISPATCH_EVENT_PACKAGE(cMouseReleasedPackage, MouseReleasedPackage, fireMouseReleased);
654 
655         DISPATCH_EVENT_PACKAGE(cMenuCanceledPackage, MenuCanceledPackage, fireMenuCanceled);
656         DISPATCH_EVENT_PACKAGE(cMenuDeselectedPackage, MenuDeselectedPackage, fireMenuDeselected);
657         DISPATCH_EVENT_PACKAGE(cMenuSelectedPackage, MenuSelectedPackage, fireMenuSelected);
658         DISPATCH_EVENT_PACKAGE(cPopupMenuCanceledPackage, PopupMenuCanceledPackage, firePopupMenuCanceled);
659         DISPATCH_EVENT_PACKAGE(cPopupMenuWillBecomeInvisiblePackage, PopupMenuWillBecomeInvisiblePackage, firePopupMenuWillBecomeInvisible);
660         DISPATCH_EVENT_PACKAGE(cPopupMenuWillBecomeVisiblePackage, PopupMenuWillBecomeVisiblePackage, firePopupMenuWillBecomeVisible);
661 
662         DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyNameChangePackage,
663                                          PropertyNameChangePackage,
664                                          firePropertyNameChange, oldName, newName)
665             DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyDescriptionChangePackage,
666                                              PropertyDescriptionChangePackage,
667                                              firePropertyDescriptionChange,
668                                              oldDescription, newDescription)
669             DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyStateChangePackage,
670                                              PropertyStateChangePackage,
671                                              firePropertyStateChange, oldState, newState)
672             DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyValueChangePackage,
673                                              PropertyValueChangePackage,
674                                              firePropertyValueChange, oldValue, newValue)
675             DISPATCH_EVENT_PACKAGE(cPropertySelectionChangePackage,
676                                    PropertySelectionChangePackage, firePropertySelectionChange)
677             DISPATCH_EVENT_PACKAGE(cPropertyTextChangePackage,
678                                    PropertyTextChangePackage, firePropertyTextChange)
679             DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyCaretChangePackage,
680                                              PropertyCaretChangePackage,
681                                              firePropertyCaretChange, oldPosition, newPosition)
682             DISPATCH_EVENT_PACKAGE(cPropertyVisibleDataChangePackage,
683                                    PropertyVisibleDataChangePackage, firePropertyVisibleDataChange)
684             DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyChildChangePackage,
685                                              PropertyChildChangePackage,
686                                              firePropertyChildChange,
687                                              oldChildAccessibleContext,
688                                              newChildAccessibleContext)
689             DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyActiveDescendentChangePackage,
690                                              PropertyActiveDescendentChangePackage,
691                                              firePropertyActiveDescendentChange,
692                                              oldActiveDescendentAccessibleContext,
693                                              newActiveDescendentAccessibleContext)
694 
695             DISPATCH_PROPERTY_TABLE_MODEL_CHANGE_PACKAGE(cPropertyTableModelChangePackage,
696                                                          PropertyTableModelChangePackage,
697                                                          firePropertyTableModelChange,
698                                                          oldValue, newValue)
699 
700 
701             default:
702         PrintDebugString("[ERROR]:    processing FAILED!! -> don't know how to handle type = %X", *type);
703         break;
704     }
705 
706     PrintDebugString("[INFO]:    package processing completed");
707 }
708 
709 
710 // -----------------------------
711 
712 void
JavaVMDestroyed(HWND VMBridgeDLLWindow)713 WinAccessBridge::JavaVMDestroyed(HWND VMBridgeDLLWindow) {
714     PrintDebugString("[INFO]: ***** WinAccessBridge::JavaVMDestroyed(%p)", VMBridgeDLLWindow);
715 
716     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
717         return;
718     }
719 
720     isVMInstanceChainInUse = true;
721     AccessBridgeJavaVMInstance *currentVM = javaVMs;
722     AccessBridgeJavaVMInstance *previousVM = javaVMs;
723     if (javaVMs->javaAccessBridgeWindow == VMBridgeDLLWindow) {
724         javaVMs = javaVMs->nextJVMInstance;
725         delete currentVM;
726 
727         PrintDebugString("[INFO]:   data structures successfully removed");
728 
729         // [[[FIXME]]] inform Windows AT that a JVM went away,
730         // and that any jobjects it's got lying around for that JVM
731         // are now invalid
732 
733     } else {
734         while (currentVM != (AccessBridgeJavaVMInstance *) 0) {
735             if (currentVM->javaAccessBridgeWindow == VMBridgeDLLWindow) {
736                 previousVM->nextJVMInstance = currentVM->nextJVMInstance;
737                 delete currentVM;
738 
739                 PrintDebugString("[INFO]:   data structures successfully removed");
740 
741                 // [[[FIXME]]] inform Windows AT that a JVM went away,
742                 // and that any jobjects it's got lying around for that JVM
743                 // are now invalid
744                 isVMInstanceChainInUse = false;
745                 return;
746             } else {
747                 previousVM = currentVM;
748                 currentVM = currentVM->nextJVMInstance;
749             }
750         }
751         PrintDebugString("[ERROR]: couldn't find matching data structures!");
752     }
753     isVMInstanceChainInUse = false;
754 }
755 
756 // -----------------------
757 
758 /**
759  * releaseJavaObject - lets the JavaVM know it can release the Java Object
760  *
761  * Note: once you have made this call, the JavaVM will garbage collect
762  * the jobject you pass in.  If you later use that jobject in another
763  * call, you will cause all maner of havoc!
764  *
765  */
766 void
releaseJavaObject(long vmID,JOBJECT64 object)767 WinAccessBridge::releaseJavaObject(long vmID, JOBJECT64 object) {
768 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
769     PrintDebugString("[INFO]: WinAccessBridge::releaseJavaObject(%X, %p)", vmID, object);
770 #else // JOBJECT64 is jlong (64 bit)
771     PrintDebugString("[INFO]: WinAccessBridge::releaseJavaObject(%X, %016I64X)", vmID, object);
772 #endif
773     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
774         return;
775     }
776     char buffer[sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage)];
777     PackageType *type = (PackageType *) buffer;
778     ReleaseJavaObjectPackage *pkg = (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType));
779     *type = cReleaseJavaObjectPackage;
780     pkg->vmID = vmID;
781     pkg->object = object;
782 
783     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
784     if (destABWindow != (HWND) 0) {
785         sendPackage(buffer, sizeof(buffer), destABWindow);              // no return values!
786     }
787 }
788 
789 // -----------------------
790 
791 /**
792  * getVersionInfo - fill the AccessBridgeVersionInfo struct
793  *
794  */
795 BOOL
getVersionInfo(long vmID,AccessBridgeVersionInfo * info)796 WinAccessBridge::getVersionInfo(long vmID, AccessBridgeVersionInfo *info) {
797     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
798         return FALSE;
799     }
800     char buffer[sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage)];
801     PackageType *type = (PackageType *) buffer;
802     GetAccessBridgeVersionPackage *pkg = (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType));
803     *type = cGetAccessBridgeVersionPackage;
804     pkg->vmID = vmID;
805 
806     PrintDebugString("[INFO]: WinAccessBridge::getVersionInfo(%X, )", vmID);
807     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
808     if (destABWindow != (HWND) 0) {
809         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
810             memcpy(info, &(pkg->rVersionInfo), sizeof(AccessBridgeVersionInfo));
811             PrintDebugString("[INFO]:   VMversion: %ls\n"\
812                              "          bridgeJavaClassVersion: %ls\n"\
813                              "          bridgeJavaDLLVersion: %ls\n"\
814                              "          bridgeWinDLLVersion: %ls\n"\
815             , info->VMversion, info->bridgeJavaClassVersion, info->bridgeJavaDLLVersion, info->bridgeWinDLLVersion);
816             return TRUE;
817         }
818     }
819     return FALSE;
820 }
821 
822 
823 /********** Window-related routines ***********************************/
824 
825 /**
826  * isJavaWindow - returns TRUE if the HWND is a top-level Java Window
827  *
828  * Note: just because the Windnow is a top-level Java window, that doesn't
829  * mean that it is accessible.  Call getAccessibleContextFromHWND(HWND) to get the
830  * AccessibleContext, if any, for an HWND that is a Java Window.
831  *
832  */
833 BOOL
isJavaWindow(HWND window)834 WinAccessBridge::isJavaWindow(HWND window) {
835     HWND hwnd;
836 
837     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
838         return FALSE;
839     }
840 
841     // quick check to see if 'window' is top-level; if not, it's not interesting...
842     // [[[FIXME]]] is this for sure an OK optimization?
843     hwnd = getTopLevelHWND(window);
844     if (hwnd == (HWND) NULL) {
845         return FALSE;
846     }
847 
848     PrintDebugString("[INFO]: In WinAccessBridge::isJavaWindow");
849 
850 
851 
852     char buffer[sizeof(PackageType) + sizeof(IsJavaWindowPackage)];
853     PackageType *type = (PackageType *) buffer;
854     IsJavaWindowPackage *pkg = (IsJavaWindowPackage *) (buffer + sizeof(PackageType));
855     *type = cIsJavaWindowPackage;
856     pkg->window = (jint) window;
857 
858     PrintDebugString("[INFO]: WinAccessBridge::isJavaWindow(%p)", window);
859 
860     isVMInstanceChainInUse = true;
861     AccessBridgeJavaVMInstance *current = javaVMs;
862     while (current != (AccessBridgeJavaVMInstance *) 0) {
863         if (sendMemoryPackage(buffer, sizeof(buffer), current->javaAccessBridgeWindow) == TRUE) {
864             if (pkg->rResult != 0) {
865                 isVMInstanceChainInUse = false;
866                 return TRUE;
867             }
868         }
869         current = current->nextJVMInstance;
870     }
871     isVMInstanceChainInUse = false;
872     return FALSE;
873 
874 
875     /*
876       char classname[256];
877       HWND hwnd;
878 
879       hwnd = getTopLevelHWND(window);
880       if (hwnd == (HWND) NULL) {
881       return FALSE;
882       }
883       GetClassName(hwnd, classname, 256);
884 
885       if (strstr(classname, "AwtFrame") != 0) {
886       return TRUE;
887       } else if (strstr(classname, "AwtWindow") != 0) {
888       return TRUE;
889       } else if (strstr(classname, "AwtDialog") != 0) {
890       return TRUE;
891       }
892     */
893     // JDK 1.4 introduces new (and changes old) classnames
894     /*
895       else if (strstr(classname, "SunAwtToolkit") != 0) {
896       return TRUE;
897       } else if (strstr(classname, "javax.swing.JFrame") != 0) {
898       return TRUE;
899       }
900     */
901 
902     return FALSE;
903 }
904 
905 /**
906  * isSameObject - returns TRUE if the two object references refer to
907  *     the same object. Otherwise, this method returns FALSE:
908  */
909 BOOL
isSameObject(long vmID,JOBJECT64 obj1,JOBJECT64 obj2)910 WinAccessBridge::isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) {
911 
912 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
913     PrintDebugString("[INFO]: WinAccessBridge::isSameObject(%p %p)", obj1, obj2);
914 #else // JOBJECT64 is jlong (64 bit)
915     PrintDebugString("[INFO]: WinAccessBridge::isSameObject(%016I64X %016I64X)", obj1, obj2);
916 #endif
917 
918     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
919         return FALSE;
920     }
921 
922     char buffer[sizeof(PackageType) + sizeof(IsSameObjectPackage)];
923     PackageType *type = (PackageType *) buffer;
924     IsSameObjectPackage *pkg = (IsSameObjectPackage *) (buffer + sizeof(PackageType));
925     *type = cIsSameObjectPackage;
926     pkg->vmID = vmID;
927     pkg->obj1 = obj1;
928     pkg->obj2 = obj2;
929 
930     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
931     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
932         if (pkg->rResult != 0) {
933             PrintDebugString("[INFO]:   WinAccessBridge::isSameObject returning TRUE (same object)");
934             return TRUE;
935         } else {
936             PrintDebugString("[INFO]:   WinAccessBridge::isSameObject returning FALSE (different object)");
937             return FALSE;
938         }
939     }
940     PrintDebugString("[ERROR]:   WinAccessBridge::isSameObject returning FALSE (sendMemoryPackage failed)");
941     return FALSE;
942 }
943 
944 /**
945  * FromHWND - returns the AccessibleContext jobject for the HWND
946  *
947  * Note: this routine can return null, even if the HWND is a Java Window,
948  * because the Java Window may not be accessible.
949  *
950  */
951 BOOL
getAccessibleContextFromHWND(HWND window,long * vmID,JOBJECT64 * AccessibleContext)952 WinAccessBridge::getAccessibleContextFromHWND(HWND window, long *vmID, JOBJECT64 *AccessibleContext) {
953     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
954         return FALSE;
955     }
956 
957     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage)];
958     PackageType *type = (PackageType *) buffer;
959     GetAccessibleContextFromHWNDPackage *pkg = (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType));
960     *type = cGetAccessibleContextFromHWNDPackage;
961     pkg->window = (jint) window;
962 
963     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextFromHWND(%p, )", window);
964 
965     DEBUG_CODE(pkg->rVMID = (long ) 0x01010101);
966     DEBUG_CODE(pkg->rAccessibleContext = (JOBJECT64) 0x01010101);
967 
968     isVMInstanceChainInUse = true;
969     AccessBridgeJavaVMInstance *current = javaVMs;
970     while (current != (AccessBridgeJavaVMInstance *) 0) {
971 
972         if (sendMemoryPackage(buffer, sizeof(buffer), current->javaAccessBridgeWindow) == TRUE) {
973             if (pkg->rAccessibleContext != 0) {
974                 *vmID = pkg->rVMID;
975                 *AccessibleContext = (JOBJECT64)pkg->rAccessibleContext;
976                 PrintDebugString("[INFO]:     current->vmID = %X, pkg->rVMID = %X", current->vmID, pkg->rVMID);
977 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
978                 PrintDebugString("[INFO]:     pkg->rAccessibleContext = %p", pkg->rAccessibleContext);
979 #else // JOBJECT64 is jlong (64 bit)
980                 PrintDebugString("[INFO]:     pkg->rAccessibleContext = %016I64X", pkg->rAccessibleContext);
981 #endif
982                 if (pkg->rVMID != current->vmID) {
983                     PrintDebugString("[ERROR]: getAccessibleContextFromHWND vmIDs don't match!");
984                     isVMInstanceChainInUse = false;
985                     return FALSE;
986                 }
987                 isVMInstanceChainInUse = false;
988                 return TRUE;
989             }
990         }
991         current = current->nextJVMInstance;
992     }
993     isVMInstanceChainInUse = false;
994 
995     // This isn't really an error; it just means that the HWND was for a non-Java
996     // window.  It's also possible the HWND was for a Java window but the JVM has
997     // since been shut down and sendMemoryPackage returned FALSE.
998     PrintDebugString("[ERROR]: getAccessibleContextFromHWND no matching HWND found!");
999     return FALSE;
1000 }
1001 
1002 /**
1003  * Returns the HWND for an AccessibleContext.  Returns (HWND)0 on error.
1004  */
1005 HWND
getHWNDFromAccessibleContext(long vmID,JOBJECT64 accessibleContext)1006 WinAccessBridge::getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext) {
1007     PrintDebugString("[INFO]:   in WinAccessBridge::getHWNDFromAccessibleContext");
1008     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1009         return (HWND)0;
1010     }
1011 
1012     char buffer[sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage)];
1013     PackageType *type = (PackageType *) buffer;
1014     GetHWNDFromAccessibleContextPackage *pkg = (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType));
1015     *type = cGetHWNDFromAccessibleContextPackage;
1016     pkg->accessibleContext = accessibleContext;
1017 
1018 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1019     PrintDebugString("[INFO]: WinAccessBridge::getHWNDFromAccessibleContext(%p)", accessibleContext);
1020 #else // JOBJECT64 is jlong (64 bit)
1021     PrintDebugString("[INFO]: WinAccessBridge::getHWNDFromAccessibleContext(%016I64X)", accessibleContext);
1022 #endif
1023 
1024     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1025     if (destABWindow != (HWND) 0) {
1026         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1027             return ((HWND)ABLongToHandle(pkg->rHWND));
1028         }
1029     }
1030     return (HWND)0;
1031 }
1032 
1033 /********** AccessibleContext routines ***********************************/
1034 
1035 /**
1036  * Walk through Java Windows, in front-to-back Z-order.
1037  * If NULL is passed it, this function starts at the top.
1038  *
1039  */
1040 HWND
getNextJavaWindow(HWND previous)1041 WinAccessBridge::getNextJavaWindow(HWND previous) {
1042     HWND current = previous;
1043     if (current == NULL) {
1044         current = GetTopWindow(NULL);
1045     } else {
1046         current = GetNextWindow(current, GW_HWNDNEXT);
1047     }
1048     while (current != NULL) {
1049         if (isJavaWindow(current)) {
1050             return current;
1051         }
1052         current = GetNextWindow(current, GW_HWNDNEXT);
1053     }
1054     return NULL;
1055 }
1056 
1057 
1058 /**
1059  * getAccessibleContextAt - performs the Java code:
1060  *   Accessible a = EventQueueMonitor.getAccessibleAt(x, y);
1061  *       return a.getAccessibleContext();
1062  *
1063  * Note: this call explicitly goes through the AccessBridge,
1064  * so that the AccessBridge can hide expected changes in how this functions
1065  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1066  * of this functionality may be built into the platform
1067  *
1068  */
1069 BOOL
getAccessibleContextAt(long vmID,JOBJECT64 AccessibleContextParent,jint x,jint y,JOBJECT64 * AccessibleContext)1070 WinAccessBridge::getAccessibleContextAt(long vmID, JOBJECT64 AccessibleContextParent,
1071                                         jint x, jint y, JOBJECT64 *AccessibleContext) {
1072     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1073         return FALSE;
1074     }
1075 
1076     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage)];
1077     PackageType *type = (PackageType *) buffer;
1078     GetAccessibleContextAtPackage *pkg = (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType));
1079     *type = cGetAccessibleContextAtPackage;
1080     pkg->vmID = vmID;
1081     pkg->AccessibleContext = AccessibleContextParent;
1082     pkg->x = x;
1083     pkg->y = y;
1084 
1085     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextAt(%X, %p, %d, %c)", vmID, AccessibleContextParent, x, y);
1086     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
1087     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1088         *AccessibleContext = pkg->rAccessibleContext;
1089         return TRUE;
1090     }
1091 
1092     return FALSE;
1093 }
1094 
1095 
1096 /**
1097  * getAccessibleContextWithFocus - performs the Java code:
1098  *   Accessible a = Translator.getAccessible(SwingEventMonitor.getComponentWithFocus());
1099  *   return a.getAccessibleContext();
1100  *
1101  * Note: this call explicitly goes through the AccessBridge,
1102  * so that the AccessBridge can hide expected changes in how this functions
1103  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1104  * of this functionality may be built into the platform
1105  *
1106  */
1107 BOOL
getAccessibleContextWithFocus(HWND window,long * vmID,JOBJECT64 * AccessibleContext)1108 WinAccessBridge::getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT64 *AccessibleContext) {
1109 
1110     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1111         return FALSE;
1112     }
1113     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage)];
1114     PackageType *type = (PackageType *) buffer;
1115     GetAccessibleContextWithFocusPackage *pkg = (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType));
1116     *type = cGetAccessibleContextWithFocusPackage;
1117 
1118     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID);
1119     // find vmID, etc. from HWND; ask that VM for the AC w/Focus
1120     HWND pkgVMID;
1121     if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) {
1122         HWND destABWindow = javaVMs->findAccessBridgeWindow((long)pkgVMID);     // ineffecient [[[FIXME]]]
1123         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1124             *vmID = pkg->rVMID;
1125             *AccessibleContext = pkg->rAccessibleContext;
1126             return TRUE;
1127         }
1128     }
1129 
1130     return FALSE;
1131 }
1132 
1133 /**
1134  * getAccessibleContextInfo - fills a struct with a bunch of information
1135  * contained in the Java Accessibility API
1136  *
1137  *
1138  * Note: if the AccessibleContext parameter is bogus, this call will blow up
1139  */
1140 BOOL
getAccessibleContextInfo(long vmID,JOBJECT64 accessibleContext,AccessibleContextInfo * info)1141 WinAccessBridge::getAccessibleContextInfo(long vmID,
1142                                           JOBJECT64 accessibleContext,
1143                                           AccessibleContextInfo *info) {
1144     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1145         return FALSE;
1146     }
1147     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage)];
1148     PackageType *type = (PackageType *) buffer;
1149     GetAccessibleContextInfoPackage *pkg = (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType));
1150     *type = cGetAccessibleContextInfoPackage;
1151     pkg->vmID = vmID;
1152     pkg->AccessibleContext = accessibleContext;
1153 
1154 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1155     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextInfo(%X, %p, )", vmID, accessibleContext);
1156 #else // JOBJECT64 is jlong (64 bit)
1157     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextInfo(%X, %016I64X, )", vmID, accessibleContext);
1158 #endif
1159     // need to call only the HWND/VM that contains this AC
1160     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1161     if (destABWindow != (HWND) 0) {
1162         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1163             memcpy(info, &(pkg->rAccessibleContextInfo), sizeof(AccessibleContextInfo));
1164             PrintDebugString("[INFO]:   name: %ls\n"\
1165                              "          description: %ls\n"\
1166                              "          role: %ls\n"\
1167                              "          role_en_US: %ls\n"\
1168                              "          states: %ls\n"\
1169                              "          states_en_US: %ls\n"\
1170             , info->name, info->description, info->role, info->role_en_US, info->states, info->states_en_US);
1171             return TRUE;
1172         }
1173     }
1174 
1175     return FALSE;
1176 }
1177 
1178 /**
1179  * getAccessibleChildFromContext - performs the Java code:
1180  *   Accessible child = ac.getAccessibleChild(i);
1181  *   return child.getAccessibleContext();
1182  *
1183  * Note: this call explicitly goes through the AccessBridge,
1184  * so that the AccessBridge can hide expected changes in how this functions
1185  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1186  * of this functionality may be built into the platform
1187  *
1188  */
1189 JOBJECT64
getAccessibleChildFromContext(long vmID,JOBJECT64 AccessibleContext,jint childIndex)1190 WinAccessBridge::getAccessibleChildFromContext(long vmID,
1191                                                JOBJECT64 AccessibleContext,
1192                                                jint childIndex) {
1193     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1194         return (JOBJECT64)0;
1195     }
1196     char buffer[sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage)];
1197     PackageType *type = (PackageType *) buffer;
1198     GetAccessibleChildFromContextPackage *pkg = (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType));
1199     *type = cGetAccessibleChildFromContextPackage;
1200     pkg->vmID = vmID;
1201     pkg->AccessibleContext = AccessibleContext;
1202     pkg->childIndex = childIndex;
1203 
1204 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1205     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleChildFromContext(%X, %p, %d)", vmID, AccessibleContext, childIndex);
1206 #else // JOBJECT64 is jlong (64 bit)
1207     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleChildFromContext(%X, %016I64X, %d)", vmID, AccessibleContext, childIndex);
1208 #endif
1209     // need to call only the HWND/VM that contains this AC
1210     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1211     if (destABWindow != (HWND) 0) {
1212         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1213             return pkg->rAccessibleContext;
1214         }
1215     }
1216 
1217     return (JOBJECT64) 0;
1218 }
1219 
1220 /**
1221  * getAccessibleParentFromContext - returns the parent AccessibleContext jobject
1222  *
1223  * Note: this may be null, if the AccessibleContext passed in is a top-level
1224  * window, then it has no parent.
1225  *
1226  */
1227 JOBJECT64
getAccessibleParentFromContext(long vmID,JOBJECT64 AccessibleContext)1228 WinAccessBridge::getAccessibleParentFromContext(long vmID,
1229                                                 JOBJECT64 AccessibleContext) {
1230     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1231         return (JOBJECT64)0;
1232     }
1233     char buffer[sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage)];
1234     PackageType *type = (PackageType *) buffer;
1235     GetAccessibleParentFromContextPackage *pkg = (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType));
1236     *type = cGetAccessibleParentFromContextPackage;
1237     pkg->vmID = vmID;
1238     pkg->AccessibleContext = AccessibleContext;
1239 
1240     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleParentFromContext(%X, %p)", vmID, AccessibleContext);
1241     // need to call only the HWND/VM that contains this AC
1242     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1243     if (destABWindow != (HWND) 0) {
1244         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1245             return pkg->rAccessibleContext;
1246         }
1247     }
1248 
1249     return (JOBJECT64) 0;
1250 }
1251 
1252 /********** AccessibleTable routines ***********************************/
1253 
1254 BOOL
getAccessibleTableInfo(long vmID,JOBJECT64 accessibleContext,AccessibleTableInfo * tableInfo)1255 WinAccessBridge::getAccessibleTableInfo(long vmID,
1256                                         JOBJECT64 accessibleContext,
1257                                         AccessibleTableInfo *tableInfo) {
1258 
1259 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1260     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableInfo(%X, %p, %p)", vmID, accessibleContext,
1261                      tableInfo);
1262 #else // JOBJECT64 is jlong (64 bit)
1263     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableInfo(%X, %016I64X, %p)", vmID, accessibleContext,
1264                      tableInfo);
1265 #endif
1266 
1267     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1268         return FALSE;
1269     }
1270     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage)];
1271     PackageType *type = (PackageType *) buffer;
1272     GetAccessibleTableInfoPackage *pkg = (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType));
1273     *type = cGetAccessibleTableInfoPackage;
1274     pkg->vmID = vmID;
1275     pkg->accessibleContext = accessibleContext;
1276 
1277     // need to call only the HWND/VM that contains this AC
1278     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1279     if (destABWindow != (HWND) 0) {
1280         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1281             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
1282             if (pkg->rTableInfo.rowCount != -1) {
1283                 PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableInfo succeeded");
1284                 return TRUE;
1285             }
1286         }
1287     }
1288     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableInfo failed");
1289     return FALSE;
1290 }
1291 
1292 BOOL
getAccessibleTableCellInfo(long vmID,JOBJECT64 accessibleTable,jint row,jint column,AccessibleTableCellInfo * tableCellInfo)1293 WinAccessBridge::getAccessibleTableCellInfo(long vmID, JOBJECT64 accessibleTable,
1294                                             jint row, jint column,
1295                                             AccessibleTableCellInfo *tableCellInfo) {
1296 
1297     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableCellInfo(%X, %p, %d, %d, %p)", vmID,
1298                      accessibleTable, row, column, tableCellInfo);
1299 
1300     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1301         return FALSE;
1302     }
1303 
1304     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage)];
1305     PackageType *type = (PackageType *) buffer;
1306     GetAccessibleTableCellInfoPackage *pkg = (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType));
1307     *type = cGetAccessibleTableCellInfoPackage;
1308     pkg->vmID = vmID;
1309     pkg->accessibleTable = accessibleTable;
1310     pkg->row = row;
1311     pkg->column = column;
1312     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1313 
1314     if (destABWindow != (HWND) 0) {
1315         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1316             PrintDebugString("[INFO]:   XXXX pkg->rTableCellInfo.accessibleContext = %p", pkg->rTableCellInfo.accessibleContext);
1317             memcpy(tableCellInfo, &(pkg->rTableCellInfo), sizeof(AccessibleTableCellInfo));
1318             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableCellInfo succeeded");
1319             return TRUE;
1320         }
1321     }
1322     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableCellInfo failed");
1323     return FALSE;
1324 }
1325 
1326 
1327 BOOL
getAccessibleTableRowHeader(long vmID,JOBJECT64 accessibleContext,AccessibleTableInfo * tableInfo)1328 WinAccessBridge::getAccessibleTableRowHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) {
1329 
1330 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1331     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowHeader(%X, %p)", vmID, accessibleContext);
1332 #else // JOBJECT64 is jlong (64 bit)
1333     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowHeader(%X, %016I64X)", vmID, accessibleContext);
1334 #endif
1335 
1336     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1337         return FALSE;
1338     }
1339     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage)];
1340     PackageType *type = (PackageType *) buffer;
1341     GetAccessibleTableRowHeaderPackage *pkg = (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType));
1342     *type = cGetAccessibleTableRowHeaderPackage;
1343     pkg->vmID = vmID;
1344     pkg->accessibleContext = accessibleContext;
1345 
1346     // need to call only the HWND/VM that contains this AC
1347     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1348     if (destABWindow != (HWND) 0) {
1349         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1350             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowHeader succeeded");
1351             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
1352             return TRUE;
1353         }
1354     }
1355     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowHeader failed");
1356     return FALSE;
1357 }
1358 
1359 BOOL
getAccessibleTableColumnHeader(long vmID,JOBJECT64 accessibleContext,AccessibleTableInfo * tableInfo)1360 WinAccessBridge::getAccessibleTableColumnHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) {
1361 
1362 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1363     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %p)", vmID, accessibleContext);
1364 #else // JOBJECT64 is jlong (64 bit)
1365     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %016I64X)", vmID, accessibleContext);
1366 #endif
1367 
1368     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1369         return FALSE;
1370     }
1371     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage)];
1372     PackageType *type = (PackageType *) buffer;
1373     GetAccessibleTableColumnHeaderPackage *pkg = (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType));
1374     *type = cGetAccessibleTableColumnHeaderPackage;
1375     pkg->vmID = vmID;
1376     pkg->accessibleContext = accessibleContext;
1377 
1378     // need to call only the HWND/VM that contains this AC
1379     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1380     if (destABWindow != (HWND) 0) {
1381         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1382             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnHeader succeeded");
1383             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
1384             return TRUE;
1385         }
1386     }
1387     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnHeader failed");
1388     return FALSE;
1389 }
1390 
1391 JOBJECT64
getAccessibleTableRowDescription(long vmID,JOBJECT64 accessibleContext,jint row)1392 WinAccessBridge::getAccessibleTableRowDescription(long vmID,
1393                                                   JOBJECT64 accessibleContext,
1394                                                   jint row) {
1395 
1396 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1397     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowDescription(%X, %p, %d)", vmID, accessibleContext,
1398                      row);
1399 #else // JOBJECT64 is jlong (64 bit)
1400     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowDescription(%X, %016I64X, %d)", vmID, accessibleContext,
1401                      row);
1402 #endif
1403 
1404     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1405         return FALSE;
1406     }
1407     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage)];
1408     PackageType *type = (PackageType *) buffer;
1409     GetAccessibleTableRowDescriptionPackage *pkg = (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType));
1410     *type = cGetAccessibleTableRowDescriptionPackage;
1411     pkg->vmID = vmID;
1412     pkg->row = row;
1413     pkg->accessibleContext = accessibleContext;
1414 
1415     // need to call only the HWND/VM that contains this AC
1416     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1417     if (destABWindow != (HWND) 0) {
1418         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1419             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowDescription succeeded");
1420             return pkg->rAccessibleContext;
1421         }
1422     }
1423     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowDescription failed");
1424     return (JOBJECT64)0;
1425 }
1426 
1427 JOBJECT64
getAccessibleTableColumnDescription(long vmID,JOBJECT64 accessibleContext,jint column)1428 WinAccessBridge::getAccessibleTableColumnDescription(long vmID,
1429                                                      JOBJECT64 accessibleContext,
1430                                                      jint column) {
1431 
1432 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1433     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %p, %d)", vmID, accessibleContext,
1434                      column);
1435 #else // JOBJECT64 is jlong (64 bit)
1436     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %016I64X, %d)", vmID, accessibleContext,
1437                      column);
1438 #endif
1439 
1440     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1441         return FALSE;
1442     }
1443     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage)];
1444     PackageType *type = (PackageType *) buffer;
1445     GetAccessibleTableColumnDescriptionPackage *pkg =
1446         (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType));
1447     *type = cGetAccessibleTableColumnDescriptionPackage;
1448     pkg->vmID = vmID;
1449     pkg->column = column;
1450     pkg->accessibleContext = accessibleContext;
1451 
1452     // need to call only the HWND/VM that contains this AC
1453     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1454     if (destABWindow != (HWND) 0) {
1455         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1456             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnDescription succeeded");
1457             return pkg->rAccessibleContext;
1458         }
1459     }
1460     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnDescription failed");
1461     return (JOBJECT64)0;
1462 }
1463 
1464 jint
getAccessibleTableRowSelectionCount(long vmID,JOBJECT64 accessibleTable)1465 WinAccessBridge::getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable) {
1466 
1467 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1468     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %p)", vmID, accessibleTable);
1469 #else // JOBJECT64 is jlong (64 bit)
1470     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %016I64X)", vmID, accessibleTable);
1471 #endif
1472 
1473     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1474         return 0;
1475     }
1476     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage)];
1477     PackageType *type = (PackageType *) buffer;
1478     GetAccessibleTableRowSelectionCountPackage *pkg =
1479         (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType));
1480     *type = cGetAccessibleTableRowSelectionCountPackage;
1481     pkg->vmID = vmID;
1482     pkg->accessibleTable = accessibleTable;
1483 
1484     // need to call only the HWND/VM that contains this AC
1485     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1486     if (destABWindow != (HWND) 0) {
1487         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1488             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowSelectionCount succeeded");
1489             return pkg->rCount;
1490         }
1491     }
1492     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowSelectionCount failed");
1493     return 0;
1494 }
1495 
1496 BOOL
isAccessibleTableRowSelected(long vmID,JOBJECT64 accessibleTable,jint row)1497 WinAccessBridge::isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row) {
1498 
1499 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1500     PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableRowSelected(%X, %p)", vmID, accessibleTable);
1501 #else // JOBJECT64 is jlong (64 bit)
1502     PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableRowSelected(%X, %016I64X)", vmID, accessibleTable);
1503 #endif
1504 
1505     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1506         return FALSE;
1507     }
1508     char buffer[sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage)];
1509     PackageType *type = (PackageType *) buffer;
1510     IsAccessibleTableRowSelectedPackage *pkg = (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType));
1511     *type = cIsAccessibleTableRowSelectedPackage;
1512     pkg->vmID = vmID;
1513     pkg->accessibleTable = accessibleTable;
1514     pkg->row = row;
1515 
1516     // need to call only the HWND/VM that contains this AC
1517     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1518     if (destABWindow != (HWND) 0) {
1519         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1520             PrintDebugString("[INFO]:   ##### WinAccessBridge::isAccessibleTableRowSelected succeeded");
1521             return pkg->rResult;
1522         }
1523     }
1524     PrintDebugString("[ERROR]:   ##### WinAccessBridge::isAccessibleTableRowSelected failed");
1525     return FALSE;
1526 }
1527 
1528 BOOL
getAccessibleTableRowSelections(long vmID,JOBJECT64 accessibleTable,jint count,jint * selections)1529 WinAccessBridge::getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, jint *selections) {
1530 
1531 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1532     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelections(%X, %p)", vmID, accessibleTable);
1533 #else // JOBJECT64 is jlong (64 bit)
1534     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelections(%X, %016I64X)", vmID, accessibleTable);
1535 #endif
1536 
1537     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1538         return FALSE;
1539     }
1540     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage)];
1541     PackageType *type = (PackageType *) buffer;
1542     GetAccessibleTableRowSelectionsPackage *pkg =
1543         (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType));
1544     *type = cGetAccessibleTableRowSelectionsPackage;
1545     pkg->vmID = vmID;
1546     pkg->accessibleTable = accessibleTable;
1547     pkg->count = count;
1548 
1549     // need to call only the HWND/VM that contains this AC
1550     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1551     if (destABWindow != (HWND) 0) {
1552         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1553             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowSelections succeeded");
1554             memcpy(selections, pkg->rSelections, count * sizeof(jint));
1555             return TRUE;
1556         }
1557     }
1558     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowSelections failed");
1559     return FALSE;
1560 }
1561 
1562 
1563 jint
getAccessibleTableColumnSelectionCount(long vmID,JOBJECT64 accessibleTable)1564 WinAccessBridge::getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable) {
1565 
1566 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1567     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %p)", vmID,
1568                      accessibleTable);
1569 #else // JOBJECT64 is jlong (64 bit)
1570     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %016I64X)", vmID,
1571                      accessibleTable);
1572 #endif
1573 
1574     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1575         return FALSE;
1576     }
1577     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage)];
1578     PackageType *type = (PackageType *) buffer;
1579     GetAccessibleTableColumnSelectionCountPackage *pkg =
1580         (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType));
1581     *type = cGetAccessibleTableColumnSelectionCountPackage;
1582     pkg->vmID = vmID;
1583     pkg->accessibleTable = accessibleTable;
1584 
1585     // need to call only the HWND/VM that contains this AC
1586     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1587     if (destABWindow != (HWND) 0) {
1588         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1589             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnSelectionCount succeeded");
1590             return pkg->rCount;
1591         }
1592     }
1593     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnSelectionCount failed");
1594     return 0;
1595 }
1596 
1597 BOOL
isAccessibleTableColumnSelected(long vmID,JOBJECT64 accessibleTable,jint column)1598 WinAccessBridge::isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column) {
1599 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1600     PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %p)", vmID, accessibleTable);
1601 #else // JOBJECT64 is jlong (64 bit)
1602     PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %016I64X)", vmID, accessibleTable);
1603 #endif
1604 
1605     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1606         return FALSE;
1607     }
1608     char buffer[sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage)];
1609     PackageType *type = (PackageType *) buffer;
1610     IsAccessibleTableColumnSelectedPackage *pkg = (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType));
1611     *type = cIsAccessibleTableColumnSelectedPackage;
1612     pkg->vmID = vmID;
1613     pkg->accessibleTable = accessibleTable;
1614     pkg->column = column;
1615 
1616     // need to call only the HWND/VM that contains this AC
1617     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1618     if (destABWindow != (HWND) 0) {
1619         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1620             PrintDebugString("[INFO]:   ##### WinAccessBridge::isAccessibleTableColumnSelected succeeded");
1621             return pkg->rResult;
1622         }
1623     }
1624     PrintDebugString("[ERROR]:   ##### WinAccessBridge::isAccessibleTableColumnSelected failed");
1625     return FALSE;
1626 }
1627 
1628 BOOL
getAccessibleTableColumnSelections(long vmID,JOBJECT64 accessibleTable,jint count,jint * selections)1629 WinAccessBridge::getAccessibleTableColumnSelections(long vmID, JOBJECT64 accessibleTable, jint count,
1630                                                     jint *selections) {
1631 
1632 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1633     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %p)", vmID, accessibleTable);
1634 #else // JOBJECT64 is jlong (64 bit)
1635     PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %016I64X)", vmID, accessibleTable);
1636 #endif
1637 
1638     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1639         return FALSE;
1640     }
1641     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage)];
1642     PackageType *type = (PackageType *) buffer;
1643     GetAccessibleTableColumnSelectionsPackage *pkg =
1644         (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType));
1645     *type = cGetAccessibleTableColumnSelectionsPackage;
1646     pkg->vmID = vmID;
1647     pkg->count = count;
1648     pkg->accessibleTable = accessibleTable;
1649 
1650     // need to call only the HWND/VM that contains this AC
1651     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1652     if (destABWindow != (HWND) 0) {
1653         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1654             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnSelections succeeded");
1655             memcpy(selections, pkg->rSelections, count * sizeof(jint));
1656             return TRUE;
1657         }
1658     }
1659     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnSelections failed");
1660     return FALSE;
1661 }
1662 
1663 jint
getAccessibleTableRow(long vmID,JOBJECT64 accessibleTable,jint index)1664 WinAccessBridge::getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index) {
1665 
1666 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1667     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRow(%X, %p, index=%d)", vmID,
1668                      accessibleTable, index);
1669 #else // JOBJECT64 is jlong (64 bit)
1670     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRow(%X, %016I64X, index=%d)", vmID,
1671                      accessibleTable, index);
1672 #endif
1673 
1674     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1675         return FALSE;
1676     }
1677     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage)];
1678     PackageType *type = (PackageType *) buffer;
1679     GetAccessibleTableRowPackage *pkg =
1680         (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType));
1681     *type = cGetAccessibleTableRowPackage;
1682     pkg->vmID = vmID;
1683     pkg->accessibleTable = accessibleTable;
1684     pkg->index = index;
1685 
1686     // need to call only the HWND/VM that contains this AC
1687     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1688     if (destABWindow != (HWND) 0) {
1689         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1690             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRow succeeded");
1691             return pkg->rRow;
1692         }
1693     }
1694     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRow failed");
1695     return 0;
1696 }
1697 
1698 jint
getAccessibleTableColumn(long vmID,JOBJECT64 accessibleTable,jint index)1699 WinAccessBridge::getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index) {
1700 
1701 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1702     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumn(%X, %p, index=%d)", vmID,
1703                      accessibleTable, index);
1704 #else // JOBJECT64 is jlong (64 bit)
1705     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumn(%X, %016I64X, index=%d)", vmID,
1706                      accessibleTable, index);
1707 #endif
1708 
1709     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1710         return FALSE;
1711     }
1712     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage)];
1713     PackageType *type = (PackageType *) buffer;
1714     GetAccessibleTableColumnPackage *pkg =
1715         (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType));
1716     *type = cGetAccessibleTableColumnPackage;
1717     pkg->vmID = vmID;
1718     pkg->accessibleTable = accessibleTable;
1719     pkg->index = index;
1720 
1721     // need to call only the HWND/VM that contains this AC
1722     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1723     if (destABWindow != (HWND) 0) {
1724         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1725             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumn succeeded");
1726             return pkg->rColumn;
1727         }
1728     }
1729     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumn failed");
1730     return 0;
1731 }
1732 
1733 jint
getAccessibleTableIndex(long vmID,JOBJECT64 accessibleTable,jint row,jint column)1734 WinAccessBridge::getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column) {
1735 
1736 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1737     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableIndex(%X, %p, row=%d, col=%d)", vmID,
1738                      accessibleTable, row, column);
1739 #else // JOBJECT64 is jlong (64 bit)
1740     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableIndex(%X, %016I64X, row=%d, col=%d)", vmID,
1741                      accessibleTable, row, column);
1742 #endif
1743 
1744     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1745         return FALSE;
1746     }
1747     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage)];
1748     PackageType *type = (PackageType *) buffer;
1749     GetAccessibleTableIndexPackage *pkg =
1750         (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType));
1751     *type = cGetAccessibleTableIndexPackage;
1752     pkg->vmID = vmID;
1753     pkg->accessibleTable = accessibleTable;
1754     pkg->row = row;
1755     pkg->column = column;
1756 
1757     // need to call only the HWND/VM that contains this AC
1758     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1759     if (destABWindow != (HWND) 0) {
1760         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1761             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableIndex succeeded");
1762             return pkg->rIndex;
1763         }
1764     }
1765     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableIndex failed");
1766     return 0;
1767 }
1768 
1769 /********** end AccessibleTable routines ******************************/
1770 
1771 BOOL
getAccessibleRelationSet(long vmID,JOBJECT64 accessibleContext,AccessibleRelationSetInfo * relationSetInfo)1772 WinAccessBridge::getAccessibleRelationSet(long vmID, JOBJECT64 accessibleContext,
1773                                           AccessibleRelationSetInfo *relationSetInfo) {
1774 
1775 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1776     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleRelationSet(%X, %p, %X)", vmID,
1777                      accessibleContext, relationSetInfo);
1778 #else // JOBJECT64 is jlong (64 bit)
1779     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleRelationSet(%X, %016I64X, %X)", vmID,
1780                      accessibleContext, relationSetInfo);
1781 #endif
1782 
1783     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1784         return FALSE;
1785     }
1786 
1787     char buffer[sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage)];
1788     PackageType *type = (PackageType *) buffer;
1789     GetAccessibleRelationSetPackage *pkg = (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType));
1790     *type = cGetAccessibleRelationSetPackage;
1791     pkg->vmID = vmID;
1792     pkg->accessibleContext = accessibleContext;
1793 
1794     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1795     if (destABWindow != (HWND) 0) {
1796         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1797             PrintDebugString("[INFO]:   ##### pkg->rAccessibleRelationSetInfo.relationCount = %X",
1798                              pkg->rAccessibleRelationSetInfo.relationCount);
1799             memcpy(relationSetInfo, &(pkg->rAccessibleRelationSetInfo), sizeof(AccessibleRelationSetInfo));
1800             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleRelationSet succeeded");
1801             return TRUE;
1802         }
1803     }
1804     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleRelationSet failed");
1805     return FALSE;
1806 }
1807 
1808 
1809 /********** AccessibleHypertext routines ***********/
1810 
1811 BOOL
getAccessibleHypertext(long vmID,JOBJECT64 accessibleContext,AccessibleHypertextInfo * hypertextInfo)1812 WinAccessBridge::getAccessibleHypertext(long vmID, JOBJECT64 accessibleContext,
1813                                         AccessibleHypertextInfo *hypertextInfo) {
1814 
1815 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1816     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertext(%X, %p, %X)", vmID,
1817                      accessibleContext, hypertextInfo);
1818 #else // JOBJECT64 is jlong (64 bit)
1819     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertext(%X, %016I64X, %X)", vmID,
1820                      accessibleContext, hypertextInfo);
1821 #endif
1822 
1823     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1824         return FALSE;
1825     }
1826 
1827     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage)];
1828     PackageType *type = (PackageType *) buffer;
1829     GetAccessibleHypertextPackage *pkg = (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType));
1830     *type = cGetAccessibleHypertextPackage;
1831     pkg->vmID = vmID;
1832     pkg->accessibleContext = accessibleContext;
1833 
1834     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1835     if (destABWindow != (HWND) 0) {
1836         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1837             memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo));
1838 
1839             PrintDebugString("[INFO]:   ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);
1840             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleHypertext succeeded");
1841 
1842             return TRUE;
1843         }
1844     }
1845     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHypertext failed");
1846     return FALSE;
1847 }
1848 
1849 
1850 BOOL
activateAccessibleHyperlink(long vmID,JOBJECT64 accessibleContext,JOBJECT64 accessibleHyperlink)1851 WinAccessBridge::activateAccessibleHyperlink(long vmID, JOBJECT64 accessibleContext,
1852                                              JOBJECT64 accessibleHyperlink) {
1853 
1854 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1855     PrintDebugString("[INFO]: WinAccessBridge::activateAccessibleHyperlink(%p %p)", accessibleContext,
1856                      accessibleHyperlink);
1857 #else // JOBJECT64 is jlong (64 bit)
1858     PrintDebugString("[INFO]: WinAccessBridge::activateAccessibleHyperlink(%016I64X %016I64X)", accessibleContext,
1859                      accessibleHyperlink);
1860 #endif
1861 
1862     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1863         return FALSE;
1864     }
1865 
1866     char buffer[sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage)];
1867     PackageType *type = (PackageType *) buffer;
1868     ActivateAccessibleHyperlinkPackage *pkg = (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
1869     *type = cActivateAccessibleHyperlinkPackage;
1870     pkg->vmID = vmID;
1871     pkg->accessibleContext = accessibleContext;
1872     pkg->accessibleHyperlink = accessibleHyperlink;
1873 
1874     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
1875     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1876         return pkg->rResult;
1877     }
1878     PrintDebugString("[ERROR]:  WinAccessBridge::activateAccessibleHyperlink returning FALSE (sendMemoryPackage failed)");
1879     return FALSE;
1880 }
1881 
1882 /*
1883  * Returns the number of hyperlinks in a component
1884  * Maps to AccessibleHypertext.getLinkCount.
1885  * Returns -1 on error.
1886  */
1887 jint
getAccessibleHyperlinkCount(const long vmID,const AccessibleContext accessibleContext)1888 WinAccessBridge::getAccessibleHyperlinkCount(const long vmID,
1889                                              const AccessibleContext accessibleContext) {
1890 
1891 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1892     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %p)",
1893                      vmID, accessibleContext);
1894 #else // JOBJECT64 is jlong (64 bit)
1895     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %016I64X)",
1896                      vmID, accessibleContext);
1897 #endif
1898 
1899     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1900         return FALSE;
1901     }
1902 
1903     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage)];
1904     PackageType *type = (PackageType *) buffer;
1905     GetAccessibleHyperlinkCountPackage *pkg = (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType));
1906     *type = cGetAccessibleHyperlinkCountPackage;
1907     pkg->vmID = vmID;
1908     pkg->accessibleContext = accessibleContext;
1909 
1910     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1911     if (destABWindow != (HWND) 0) {
1912         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1913             PrintDebugString("[INFO]:   ##### hypetext link count = %d", pkg->rLinkCount);
1914             PrintDebugString("[INFO]:  ##### WinAccessBridge::getAccessibleHyperlinkCount succeeded");
1915             return pkg->rLinkCount;
1916         }
1917     }
1918     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHyperlinkCount failed");
1919     return -1;
1920 }
1921 
1922 /*
1923  * This method is used to iterate through the hyperlinks in a component.  It
1924  * returns hypertext information for a component starting at hyperlink index
1925  * nStartIndex.  No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will
1926  * be returned for each call to this method.
1927  * returns FALSE on error.
1928  */
1929 BOOL
getAccessibleHypertextExt(const long vmID,const AccessibleContext accessibleContext,const jint startIndex,AccessibleHypertextInfo * hypertextInfo)1930 WinAccessBridge::getAccessibleHypertextExt(const long vmID,
1931                                            const AccessibleContext accessibleContext,
1932                                            const jint startIndex,
1933                                            /* OUT */ AccessibleHypertextInfo *hypertextInfo) {
1934 
1935 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1936     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextExt(%X, %p %p)", vmID,
1937                      accessibleContext, hypertextInfo);
1938 #else // JOBJECT64 is jlong (64 bit)
1939     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextExt(%X, %016I64X %p)", vmID,
1940                      accessibleContext, hypertextInfo);
1941 #endif
1942 
1943     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1944         return FALSE;
1945     }
1946 
1947     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage)];
1948     PackageType *type = (PackageType *) buffer;
1949     GetAccessibleHypertextExtPackage *pkg = (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType));
1950     *type = cGetAccessibleHypertextExtPackage;
1951     pkg->vmID = vmID;
1952     pkg->accessibleContext = accessibleContext;
1953     pkg->startIndex = startIndex;
1954 
1955     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1956     if (destABWindow != (HWND) 0) {
1957         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1958             PrintDebugString("[INFO]:   ##### pkg->rSuccess = %d", pkg->rSuccess);
1959 
1960             memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo));
1961             if (pkg->rSuccess == TRUE) {
1962                 PrintDebugString("[INFO]:   ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);
1963             } else {
1964                 PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHypertextExt failed");
1965             }
1966             return pkg->rSuccess;
1967         }
1968     }
1969     PrintDebugString("[ERROR]:  ##### WinAccessBridge::getAccessibleHypertextExt failed");
1970     return FALSE;
1971 }
1972 
1973 
1974 /*
1975  * Returns the index into an array of hyperlinks that is associated with
1976  * a character index in document;
1977  * Maps to AccessibleHypertext.getLinkIndex.
1978  * Returns -1 on error.
1979  */
1980 jint
getAccessibleHypertextLinkIndex(const long vmID,const AccessibleHyperlink hypertext,const jint charIndex)1981 WinAccessBridge::getAccessibleHypertextLinkIndex(const long vmID,
1982                                                  const AccessibleHyperlink hypertext,
1983                                                  const jint charIndex) {
1984 
1985 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1986     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %p)",
1987                      vmID, hypertext);
1988 #else // JOBJECT64 is jlong (64 bit)
1989     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %016I64X)",
1990                      vmID, hypertext);
1991 #endif
1992 
1993     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1994         return FALSE;
1995     }
1996 
1997     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage)];
1998     PackageType *type = (PackageType *) buffer;
1999     GetAccessibleHypertextLinkIndexPackage *pkg = (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType));
2000     *type = cGetAccessibleHypertextLinkIndexPackage;
2001     pkg->vmID = vmID;
2002     pkg->hypertext = hypertext;
2003     pkg->charIndex = charIndex;
2004 
2005     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2006     if (destABWindow != (HWND) 0) {
2007         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2008             PrintDebugString("[INFO]:   ##### hypetext link index = %d", pkg->rLinkIndex);
2009             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleHypertextLinkIndex  succeeded");
2010             return pkg->rLinkIndex;
2011         }
2012     }
2013     PrintDebugString("[ERROR]  ##### WinAccessBridge::getAccessibleHypertextLinkIndex  failed");
2014     return -1;
2015 }
2016 
2017 /*
2018  * Returns the nth hyperlink in a document.
2019  * Maps to AccessibleHypertext.getLink.
2020  * Returns -1 on error
2021  */
2022 BOOL
getAccessibleHyperlink(const long vmID,const AccessibleHyperlink hypertext,const jint linkIndex,AccessibleHyperlinkInfo * hyperlinkInfo)2023 WinAccessBridge::getAccessibleHyperlink(const long vmID,
2024                                         const AccessibleHyperlink hypertext,
2025                                         const jint linkIndex,
2026                                         /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) {
2027 
2028 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2029     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlink(%X, %p, %p)", vmID,
2030                      hypertext, hyperlinkInfo);
2031 #else // JOBJECT64 is jlong (64 bit)
2032     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlink(%X, %016I64X, %p)", vmID,
2033                      hypertext, hyperlinkInfo);
2034 #endif
2035 
2036     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2037         return FALSE;
2038     }
2039 
2040     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage)];
2041     PackageType *type = (PackageType *) buffer;
2042     GetAccessibleHyperlinkPackage *pkg = (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
2043     *type = cGetAccessibleHyperlinkPackage;
2044     pkg->vmID = vmID;
2045     pkg->hypertext = hypertext;
2046     pkg->linkIndex = linkIndex;
2047 
2048     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2049     if (destABWindow != (HWND) 0) {
2050         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2051             memcpy(hyperlinkInfo, &(pkg->rAccessibleHyperlinkInfo),
2052                    sizeof(AccessibleHyperlinkInfo));
2053             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleHypertext succeeded");
2054             return TRUE;
2055         }
2056     }
2057     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHypertext failed");
2058     return FALSE;
2059 }
2060 
2061 
2062 /********** AccessibleKeyBinding routines ***********/
2063 
2064 BOOL
getAccessibleKeyBindings(long vmID,JOBJECT64 accessibleContext,AccessibleKeyBindings * keyBindings)2065 WinAccessBridge::getAccessibleKeyBindings(long vmID, JOBJECT64 accessibleContext,
2066                                           AccessibleKeyBindings *keyBindings) {
2067 
2068 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2069     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleKeyBindings(%X, %p, %p)", vmID,
2070                      accessibleContext, keyBindings);
2071 #else // JOBJECT64 is jlong (64 bit)
2072     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleKeyBindings(%X, %016I64X, %p)", vmID,
2073                      accessibleContext, keyBindings);
2074 #endif
2075 
2076     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2077         return FALSE;
2078     }
2079 
2080     char buffer[sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage)];
2081     PackageType *type = (PackageType *) buffer;
2082     GetAccessibleKeyBindingsPackage *pkg = (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType));
2083     *type = cGetAccessibleKeyBindingsPackage;
2084     pkg->vmID = vmID;
2085     pkg->accessibleContext = accessibleContext;
2086 
2087     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2088     if (destABWindow != (HWND) 0) {
2089         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2090             memcpy(keyBindings, &(pkg->rAccessibleKeyBindings), sizeof(AccessibleKeyBindings));
2091 
2092             PrintDebugString("[INFO]:   ##### keyBindings.keyBindingsCount = %d", keyBindings->keyBindingsCount);
2093             for (int i = 0; i < keyBindings->keyBindingsCount; ++i) {
2094                 PrintDebugString("[INFO]:   Key Binding # %d"\
2095                 "                           Modifiers: 0x%x"\
2096                 "                           Character (hex):  0x%x"\
2097                 "                           Character (wide char):  %lc"\
2098                 , i+1, keyBindings->keyBindingInfo[i].modifiers, keyBindings->keyBindingInfo[i].character, keyBindings->keyBindingInfo[i].character);
2099             }
2100             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleKeyBindings succeeded");
2101 
2102             return TRUE;
2103         }
2104     }
2105     PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleKeyBindings failed");
2106     return FALSE;
2107 }
2108 
2109 BOOL
getAccessibleIcons(long vmID,JOBJECT64 accessibleContext,AccessibleIcons * icons)2110 WinAccessBridge::getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, AccessibleIcons *icons) {
2111 
2112 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2113     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleIcons(%X, %p, %p)", vmID,
2114                      accessibleContext, icons);
2115 #else // JOBJECT64 is jlong (64 bit)
2116     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleIcons(%X, %016I64X, %p)", vmID,
2117                      accessibleContext, icons);
2118 #endif
2119 
2120     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2121         return FALSE;
2122     }
2123 
2124     char buffer[sizeof(PackageType) + sizeof(GetAccessibleIconsPackage)];
2125     PackageType *type = (PackageType *) buffer;
2126     GetAccessibleIconsPackage *pkg = (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType));
2127     *type = cGetAccessibleIconsPackage;
2128     pkg->vmID = vmID;
2129     pkg->accessibleContext = accessibleContext;
2130 
2131     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2132     if (destABWindow != (HWND) 0) {
2133         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2134             memcpy(icons, &(pkg->rAccessibleIcons), sizeof(AccessibleIcons));
2135 
2136             PrintDebugString("[INFO]:   ##### icons.iconsCount = %d", icons->iconsCount);
2137             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleIcons succeeded");
2138 
2139             return TRUE;
2140         }
2141     }
2142     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleIcons failed");
2143     return FALSE;
2144 }
2145 
2146 BOOL
getAccessibleActions(long vmID,JOBJECT64 accessibleContext,AccessibleActions * actions)2147 WinAccessBridge::getAccessibleActions(long vmID, JOBJECT64 accessibleContext, AccessibleActions *actions) {
2148 
2149 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2150     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleActions(%X, %p, %p)", vmID,
2151                      accessibleContext, actions);
2152 #else // JOBJECT64 is jlong (64 bit)
2153     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleActions(%X, %016I64X, %p)", vmID,
2154                      accessibleContext, actions);
2155 #endif
2156 
2157     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2158         return FALSE;
2159     }
2160 
2161     char buffer[sizeof(PackageType) + sizeof(GetAccessibleActionsPackage)];
2162     PackageType *type = (PackageType *) buffer;
2163     GetAccessibleActionsPackage *pkg = (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType));
2164     *type = cGetAccessibleActionsPackage;
2165     pkg->vmID = vmID;
2166     pkg->accessibleContext = accessibleContext;
2167 
2168     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2169     if (destABWindow != (HWND) 0) {
2170         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2171             memcpy(actions, &(pkg->rAccessibleActions), sizeof(AccessibleActions));
2172 
2173             PrintDebugString("[INFO]:   ##### actions.actionsCount = %d", actions->actionsCount);
2174             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleActions succeeded");
2175 
2176             return TRUE;
2177         }
2178     }
2179     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleActions failed");
2180     return FALSE;
2181 }
2182 
2183 BOOL
doAccessibleActions(long vmID,JOBJECT64 accessibleContext,AccessibleActionsToDo * actionsToDo,jint * failure)2184 WinAccessBridge::doAccessibleActions(long vmID, JOBJECT64 accessibleContext,
2185                                      AccessibleActionsToDo *actionsToDo, jint *failure) {
2186 
2187 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2188     PrintDebugString("[INFO]: WinAccessBridge::doAccessibleActions(%p #actions %d %ls)", accessibleContext,
2189                      actionsToDo->actionsCount,
2190                      actionsToDo->actions[0].name);
2191 #else // JOBJECT64 is jlong (64 bit)
2192     PrintDebugString("[INFO]: WinAccessBridge::doAccessibleActions(%016I64X #actions %d %ls)", accessibleContext,
2193                      actionsToDo->actionsCount,
2194                      actionsToDo->actions[0].name);
2195 #endif
2196 
2197     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2198         return FALSE;
2199     }
2200     char buffer[sizeof(PackageType) + sizeof(DoAccessibleActionsPackage)];
2201     PackageType *type = (PackageType *) buffer;
2202     DoAccessibleActionsPackage *pkg = (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType));
2203     *type = cDoAccessibleActionsPackage;
2204     pkg->vmID = vmID;
2205     pkg->accessibleContext = accessibleContext;
2206     memcpy((void *)(&(pkg->actionsToDo)), (void *)actionsToDo, sizeof(AccessibleActionsToDo));
2207     pkg->failure = -1;
2208 
2209     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
2210     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2211         *failure = pkg->failure;
2212         return pkg->rResult;
2213     }
2214     PrintDebugString("[ERROR]:   WinAccessBridge::doAccessibleActions returning FALSE (sendMemoryPackage failed)");
2215     return FALSE;
2216 }
2217 
2218 /* ====== Utility methods ====== */
2219 
2220 /**
2221  * Sets a text field to the specified string. Returns whether successful.
2222  */
2223 BOOL
setTextContents(const long vmID,const AccessibleContext accessibleContext,const wchar_t * text)2224 WinAccessBridge::setTextContents (const long vmID, const AccessibleContext accessibleContext,
2225                                   const wchar_t *text) {
2226 
2227     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2228         return FALSE;
2229     }
2230     char buffer[sizeof(PackageType) + sizeof(SetTextContentsPackage)];
2231     PackageType *type = (PackageType *) buffer;
2232     SetTextContentsPackage *pkg = (SetTextContentsPackage *) (buffer + sizeof(PackageType));
2233     *type = cSetTextContentsPackage;
2234     pkg->vmID = vmID;
2235     pkg->accessibleContext = accessibleContext;
2236     wcsncpy(pkg->text, text, sizeof(pkg->text)/sizeof(wchar_t)); // wide character copy
2237 
2238 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2239     PrintDebugString("[INFO]: WinAccessBridge::setTextContents(%X, %016I64X %ls)", vmID, accessibleContext, text);
2240 #else // JOBJECT64 is jlong (64 bit)
2241     PrintDebugString("[INFO]: WinAccessBridge::setTextContents(%X, %p %ls)", vmID, accessibleContext, text);
2242 #endif
2243     // need to call only the HWND/VM that contains this AC
2244     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2245     if (destABWindow != (HWND) 0) {
2246         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2247             return pkg->rResult;
2248         }
2249     }
2250     return FALSE;
2251 }
2252 
2253 /**
2254  * Returns the Accessible Context of a Page Tab object that is the
2255  * ancestor of a given object.  If the object is a Page Tab object
2256  * or a Page Tab ancestor object was found, returns the object
2257  * AccessibleContext.
2258  * If there is no ancestor object that has an Accessible Role of Page Tab,
2259  * returns (AccessibleContext)0.
2260  */
2261 AccessibleContext
getParentWithRole(const long vmID,const AccessibleContext accessibleContext,const wchar_t * role)2262 WinAccessBridge::getParentWithRole (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) {
2263 
2264     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2265         return (JOBJECT64)0;
2266     }
2267     char buffer[sizeof(PackageType) + sizeof(GetParentWithRolePackage)];
2268     PackageType *type = (PackageType *) buffer;
2269     GetParentWithRolePackage *pkg = (GetParentWithRolePackage *) (buffer + sizeof(PackageType));
2270     *type = cGetParentWithRolePackage;
2271     pkg->vmID = vmID;
2272     pkg->accessibleContext = accessibleContext;
2273     memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role));
2274 
2275 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2276     PrintDebugString("[INFO]: WinAccessBridge::getParentWithRole(%X, %p)", vmID, accessibleContext);
2277 #else // JOBJECT64 is jlong (64 bit)
2278     PrintDebugString("[INFO]: WinAccessBridge::getParentWithRole(%X, %016I64X)", vmID, accessibleContext);
2279 #endif
2280     PrintDebugString("[INFO]:   pkg->vmID: %X"\
2281                      "          pkg->accessibleContext: %p"\
2282                      "          pkg->role: %ls"\
2283                      , pkg->vmID, pkg->accessibleContext, pkg->role);
2284     // need to call only the HWND/VM that contains this AC
2285     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2286     if (destABWindow != (HWND) 0) {
2287         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2288             PrintDebugString("[INFO]:   pkg->rAccessibleContext: %p", pkg->rAccessibleContext);
2289             return pkg->rAccessibleContext;
2290         }
2291     }
2292     return (JOBJECT64) 0;
2293 }
2294 
2295 
2296 /**
2297  * Returns the Accessible Context for the top level object in
2298  * a Java Window.  This is same Accessible Context that is obtained
2299  * from GetAccessibleContextFromHWND for that window.  Returns
2300  * (AccessibleContext)0 on error.
2301  */
2302 AccessibleContext
getTopLevelObject(const long vmID,const AccessibleContext accessibleContext)2303 WinAccessBridge::getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) {
2304 
2305     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2306         return (JOBJECT64)0;
2307     }
2308     char buffer[sizeof(PackageType) + sizeof(GetTopLevelObjectPackage)];
2309     PackageType *type = (PackageType *) buffer;
2310     GetTopLevelObjectPackage *pkg = (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType));
2311     *type = cGetTopLevelObjectPackage;
2312     pkg->vmID = vmID;
2313     pkg->accessibleContext = accessibleContext;
2314 
2315 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2316     PrintDebugString("[INFO]: WinAccessBridge::getTopLevelObject(%X, %p)", vmID, accessibleContext);
2317 #else // JOBJECT64 is jlong (64 bit)
2318     PrintDebugString("[INFO]: WinAccessBridge::getTopLevelObject(%X, %016I64X)", vmID, accessibleContext);
2319 #endif
2320     // need to call only the HWND/VM that contains this AC
2321     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2322     if (destABWindow != (HWND) 0) {
2323         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2324             return pkg->rAccessibleContext;
2325         }
2326     }
2327     return (JOBJECT64) 0;
2328 }
2329 
2330 /**
2331  * If there is an Ancestor object that has an Accessible Role of
2332  * Internal Frame, returns the Accessible Context of the Internal
2333  * Frame object.  Otherwise, returns the top level object for that
2334  * Java Window.  Returns (AccessibleContext)0 on error.
2335  */
2336 AccessibleContext
getParentWithRoleElseRoot(const long vmID,const AccessibleContext accessibleContext,const wchar_t * role)2337 WinAccessBridge::getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) {
2338 
2339     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2340         return (JOBJECT64)0;
2341     }
2342     char buffer[sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage)];
2343     PackageType *type = (PackageType *) buffer;
2344     GetParentWithRoleElseRootPackage *pkg = (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType));
2345     *type = cGetParentWithRoleElseRootPackage;
2346     pkg->vmID = vmID;
2347     pkg->accessibleContext = accessibleContext;
2348     memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role));
2349 
2350 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2351     PrintDebugString("[INFO]: WinAccessBridge::getParentWithRoleElseRoot(%X, %p)", vmID, accessibleContext);
2352 #else // JOBJECT64 is jlong (64 bit)
2353     PrintDebugString("[INFO]: WinAccessBridge::getParentWithRoleElseRoot(%X, %016I64X)", vmID, accessibleContext);
2354 #endif
2355     // need to call only the HWND/VM that contains this AC
2356     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2357     if (destABWindow != (HWND) 0) {
2358         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2359             return pkg->rAccessibleContext;
2360         }
2361     }
2362     return (JOBJECT64) 0;
2363 }
2364 
2365 /**
2366  * Returns how deep in the object hierarchy a given object is.
2367  * The top most object in the object hierarchy has an object depth of 0.
2368  * Returns -1 on error.
2369  */
2370 int
getObjectDepth(const long vmID,const AccessibleContext accessibleContext)2371 WinAccessBridge::getObjectDepth (const long vmID, const AccessibleContext accessibleContext) {
2372 
2373     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2374         return -1;
2375     }
2376     char buffer[sizeof(PackageType) + sizeof(GetObjectDepthPackage)];
2377     PackageType *type = (PackageType *) buffer;
2378     GetObjectDepthPackage *pkg = (GetObjectDepthPackage *) (buffer + sizeof(PackageType));
2379     *type = cGetObjectDepthPackage;
2380     pkg->vmID = vmID;
2381     pkg->accessibleContext = accessibleContext;
2382 
2383 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2384     PrintDebugString("[INFO]: WinAccessBridge::getObjectDepth(%X, %p)", vmID, accessibleContext);
2385 #else // JOBJECT64 is jlong (64 bit)
2386     PrintDebugString("[INFO]: WinAccessBridge::getObjectDepth(%X, %016I64X)", vmID, accessibleContext);
2387 #endif
2388     // need to call only the HWND/VM that contains this AC
2389     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2390     if (destABWindow != (HWND) 0) {
2391         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2392             return pkg->rResult;
2393         }
2394     }
2395     return -1;
2396 }
2397 
2398 /**
2399  * Returns the Accessible Context of the currently ActiveDescendent of an object.
2400  * Returns (AccessibleContext)0 on error.
2401  */
2402 AccessibleContext
getActiveDescendent(const long vmID,const AccessibleContext accessibleContext)2403 WinAccessBridge::getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) {
2404 
2405     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2406         return (JOBJECT64)0;
2407     }
2408     char buffer[sizeof(PackageType) + sizeof(GetActiveDescendentPackage)];
2409     PackageType *type = (PackageType *) buffer;
2410     GetActiveDescendentPackage *pkg = (GetActiveDescendentPackage *) (buffer + sizeof(PackageType));
2411     *type = cGetActiveDescendentPackage;
2412     pkg->vmID = vmID;
2413     pkg->accessibleContext = accessibleContext;
2414 
2415 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2416     PrintDebugString("[INFO]: WinAccessBridge::getActiveDescendent(%X, %p)", vmID, accessibleContext);
2417 #else // JOBJECT64 is jlong (64 bit)
2418     PrintDebugString("[INFO]: WinAccessBridge::getActiveDescendent(%X, %016I64X)", vmID, accessibleContext);
2419 #endif
2420     // need to call only the HWND/VM that contains this AC
2421     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2422     if (destABWindow != (HWND) 0) {
2423         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2424             return pkg->rAccessibleContext;
2425         }
2426     }
2427     return (JOBJECT64) 0;
2428 }
2429 
2430 /**
2431  * Additional methods for Teton
2432  */
2433 
2434 /**
2435  * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns
2436  * whether successful.
2437  *
2438  * Bug ID 4916682 - Implement JAWS AccessibleName policy
2439  */
2440 BOOL
getVirtualAccessibleName(long vmID,AccessibleContext accessibleContext,wchar_t * name,int len)2441 WinAccessBridge::getVirtualAccessibleName(long vmID, AccessibleContext accessibleContext,
2442                                           wchar_t *name, int len) {
2443 
2444     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2445         return FALSE;
2446     }
2447     char buffer[sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage)];
2448     PackageType *type = (PackageType *) buffer;
2449     GetVirtualAccessibleNamePackage *pkg = (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType));
2450     *type = cGetVirtualAccessibleNamePackage;
2451     pkg->vmID = vmID;
2452     pkg->accessibleContext = accessibleContext;
2453     size_t max = (len > sizeof(pkg->rName)) ? sizeof(pkg->rName) : len;
2454     pkg->len = (int)max;
2455 
2456 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2457     PrintDebugString("[INFO]: WinAccessBridge::getVirtualAccessibleName(%X, %p)", vmID, accessibleContext);
2458 #else // JOBJECT64 is jlong (64 bit)
2459     PrintDebugString("[INFO]: WinAccessBridge::getVirtualAccessibleName(%X, %016I64X)", vmID, accessibleContext);
2460 #endif
2461     // need to call only the HWND/VM that contains this AC
2462     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2463     if (destABWindow != (HWND) 0) {
2464         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2465             wcsncpy(name, pkg->rName, max);
2466             PrintDebugString("[INFO]:     WinAccessBridge::getVirtualAccessibleName: Virtual name = %ls", name);
2467             return TRUE;
2468         }
2469     }
2470     return FALSE;
2471 }
2472 
2473 /**
2474  * Request focus for a component. Returns whether successful;
2475  *
2476  * Bug ID 4944757 - requestFocus method needed
2477  */
2478 BOOL
requestFocus(long vmID,AccessibleContext accessibleContext)2479 WinAccessBridge::requestFocus(long vmID, AccessibleContext accessibleContext) {
2480 
2481     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2482         return FALSE;
2483     }
2484     char buffer[sizeof(PackageType) + sizeof(RequestFocusPackage)];
2485     PackageType *type = (PackageType *) buffer;
2486     RequestFocusPackage *pkg = (RequestFocusPackage *) (buffer + sizeof(PackageType));
2487     *type = cRequestFocusPackage;
2488     pkg->vmID = vmID;
2489     pkg->accessibleContext = accessibleContext;
2490 
2491 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2492     PrintDebugString("[INFO]: WinAccessBridge::requestFocus(%X, %p)", vmID, accessibleContext);
2493 #else // JOBJECT64 is jlong (64 bit)
2494     PrintDebugString("[INFO]: WinAccessBridge::requestFocus(%X, %016I64X)", vmID, accessibleContext);
2495 #endif
2496     // need to call only the HWND/VM that contains this AC
2497     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2498     if (destABWindow != (HWND) 0) {
2499         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2500             return TRUE;
2501         }
2502     }
2503     return FALSE;
2504 }
2505 
2506 /**
2507  * Selects text between two indices.  Selection includes the text at the start index
2508  * and the text at the end index. Returns whether successful;
2509  *
2510  * Bug ID 4944758 - selectTextRange method needed
2511  */
2512 BOOL
selectTextRange(long vmID,AccessibleContext accessibleContext,int startIndex,int endIndex)2513 WinAccessBridge::selectTextRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex) {
2514     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2515         return FALSE;
2516     }
2517     char buffer[sizeof(PackageType) + sizeof(SelectTextRangePackage)];
2518     PackageType *type = (PackageType *) buffer;
2519     SelectTextRangePackage *pkg = (SelectTextRangePackage *) (buffer + sizeof(PackageType));
2520     *type = cSelectTextRangePackage;
2521     pkg->vmID = vmID;
2522     pkg->accessibleContext = accessibleContext;
2523     pkg->startIndex = startIndex;
2524     pkg->endIndex = endIndex;
2525 
2526 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2527     PrintDebugString("[INFO]:     WinAccessBridge::selectTextRange(%X, %p %d %d)", vmID, accessibleContext,
2528                      startIndex, endIndex);
2529 #else // JOBJECT64 is jlong (64 bit)
2530     PrintDebugString("[INFO]:     WinAccessBridge::selectTextRange(%X, %016I64X %d %d)", vmID, accessibleContext,
2531                      startIndex, endIndex);
2532 #endif
2533     // need to call only the HWND/VM that contains this AC
2534     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2535     if (destABWindow != (HWND) 0) {
2536         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2537             return TRUE;
2538         }
2539     }
2540     return FALSE;
2541 }
2542 
2543 /**
2544  * Get text attributes between two indices.  The attribute list includes the text at the
2545  * start index and the text at the end index. Returns whether successful;
2546  *
2547  * Bug ID 4944761 - getTextAttributes between two indices method needed
2548  */
2549 BOOL
getTextAttributesInRange(long vmID,AccessibleContext accessibleContext,int startIndex,int endIndex,AccessibleTextAttributesInfo * attributes,short * len)2550 WinAccessBridge::getTextAttributesInRange(long vmID, AccessibleContext accessibleContext,
2551                                           int startIndex, int endIndex,
2552                                           AccessibleTextAttributesInfo *attributes, short *len) {
2553 
2554     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2555         return FALSE;
2556     }
2557     char buffer[sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage)];
2558     PackageType *type = (PackageType *) buffer;
2559     GetTextAttributesInRangePackage *pkg = (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType));
2560     *type = cGetTextAttributesInRangePackage;
2561     pkg->vmID = vmID;
2562     pkg->accessibleContext = accessibleContext;
2563     pkg->startIndex = startIndex;
2564     pkg->endIndex = endIndex;
2565     memcpy(&(pkg->attributes), attributes, sizeof(AccessibleTextAttributesInfo));
2566 
2567 
2568 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2569     PrintDebugString("[INFO]:     WinAccessBridge::getTextAttributesInRange(%X, %p %d %d)", vmID, accessibleContext,
2570                      startIndex, endIndex);
2571 #else // JOBJECT64 is jlong (64 bit)
2572     PrintDebugString("[INFO]:     WinAccessBridge::getTextAttributesInRange(%X, %016I64X %d %d)", vmID, accessibleContext,
2573                      startIndex, endIndex);
2574 #endif
2575     // need to call only the HWND/VM that contains this AC
2576     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2577     if (destABWindow != (HWND) 0) {
2578         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2579             *attributes = pkg->attributes;
2580             *len = pkg->rLength;
2581             return TRUE;
2582         }
2583     }
2584     return FALSE;
2585 }
2586 
2587 /**
2588  * Gets the number of visible children of a component. Returns -1 on error.
2589  *
2590  * Bug ID 4944762- getVisibleChildren for list-like components needed
2591  */
2592 int
getVisibleChildrenCount(long vmID,AccessibleContext accessibleContext)2593 WinAccessBridge::getVisibleChildrenCount(long vmID, AccessibleContext accessibleContext) {
2594 
2595     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2596         return -1;
2597     }
2598     char buffer[sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage)];
2599     PackageType *type = (PackageType *) buffer;
2600     GetVisibleChildrenCountPackage *pkg = (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType));
2601     *type = cGetVisibleChildrenCountPackage;
2602     pkg->vmID = vmID;
2603     pkg->accessibleContext = accessibleContext;
2604 
2605 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2606     PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildrenCount(%X, %p)", vmID, accessibleContext);
2607 #else // JOBJECT64 is jlong (64 bit)
2608     PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildrenCount(%X, %016I64X)", vmID, accessibleContext);
2609 #endif
2610     // need to call only the HWND/VM that contains this AC
2611     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2612     if (destABWindow != (HWND) 0) {
2613         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2614             return pkg->rChildrenCount;
2615         }
2616     }
2617     return -1;
2618 }
2619 
2620 /**
2621  * Gets the visible children of an AccessibleContext. Returns whether successful;
2622  *
2623  * Bug ID 4944762- getVisibleChildren for list-like components needed
2624  */
2625 BOOL
getVisibleChildren(long vmID,AccessibleContext accessibleContext,int startIndex,VisibleChildrenInfo * visibleChildrenInfo)2626 WinAccessBridge::getVisibleChildren(long vmID, AccessibleContext accessibleContext, int startIndex,
2627                                     VisibleChildrenInfo *visibleChildrenInfo) {
2628 
2629     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2630         return FALSE;
2631     }
2632     char buffer[sizeof(PackageType) + sizeof(GetVisibleChildrenPackage)];
2633     PackageType *type = (PackageType *) buffer;
2634     GetVisibleChildrenPackage *pkg = (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType));
2635     *type = cGetVisibleChildrenPackage;
2636     pkg->vmID = vmID;
2637     pkg->accessibleContext = accessibleContext;
2638     pkg->startIndex = startIndex;
2639 
2640 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2641     PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildren(%X, %p)", vmID, accessibleContext);
2642 #else // JOBJECT64 is jlong (64 bit)
2643     PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildren(%X, %016I64X)", vmID, accessibleContext);
2644 #endif
2645     // need to call only the HWND/VM that contains this AC
2646     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2647     if (destABWindow != (HWND) 0) {
2648         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2649             memcpy(visibleChildrenInfo, &(pkg->rVisibleChildrenInfo), sizeof(pkg->rVisibleChildrenInfo));
2650             return pkg->rSuccess;
2651         }
2652     }
2653     return FALSE;
2654 }
2655 
2656 /**
2657  * Set the caret to a text position. Returns whether successful;
2658  *
2659  * Bug ID 4944770 - setCaretPosition method needed
2660  */
2661 BOOL
setCaretPosition(long vmID,AccessibleContext accessibleContext,int position)2662 WinAccessBridge::setCaretPosition(long vmID, AccessibleContext accessibleContext, int position) {
2663 
2664     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2665         return FALSE;
2666     }
2667     char buffer[sizeof(PackageType) + sizeof(SetCaretPositionPackage)];
2668     PackageType *type = (PackageType *) buffer;
2669     SetCaretPositionPackage *pkg = (SetCaretPositionPackage *) (buffer + sizeof(PackageType));
2670     *type = cSetCaretPositionPackage;
2671     pkg->vmID = vmID;
2672     pkg->accessibleContext = accessibleContext;
2673     pkg->position = position;
2674 
2675 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2676     PrintDebugString("[INFO]: WinAccessBridge::setCaretPosition(%X, %p %ls)", vmID, accessibleContext);
2677 #else // JOBJECT64 is jlong (64 bit)
2678     PrintDebugString("[INFO]: WinAccessBridge::setCaretPosition(%X, %016I64X %ls)", vmID, accessibleContext);
2679 #endif
2680     // need to call only the HWND/VM that contains this AC
2681     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2682     if (destABWindow != (HWND) 0) {
2683         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2684             return TRUE;
2685         }
2686     }
2687     return FALSE;
2688 }
2689 
2690 
2691 /********** AccessibleText routines ***********************************/
2692 
2693 /**
2694  * getAccessibleTextInfo - fills a struct with a bunch of information
2695  * contained in the Java Accessibility AccessibleText API
2696  *
2697  *
2698  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2699  */
2700 BOOL
getAccessibleTextInfo(long vmID,JOBJECT64 AccessibleContext,AccessibleTextInfo * textInfo,jint x,jint y)2701 WinAccessBridge::getAccessibleTextInfo(long vmID,
2702                                        JOBJECT64 AccessibleContext,
2703                                        AccessibleTextInfo *textInfo,
2704                                        jint x, jint y) {
2705     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2706         return FALSE;
2707     }
2708     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage)];
2709     PackageType *type = (PackageType *) buffer;
2710     GetAccessibleTextInfoPackage *pkg = (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType));
2711     *type = cGetAccessibleTextInfoPackage;
2712     pkg->vmID = vmID;
2713     pkg->AccessibleContext = AccessibleContext;
2714     pkg->x = x;
2715     pkg->y = y;
2716 
2717 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2718     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextInfo(%X, %p, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y);
2719 #else // JOBJECT64 is jlong (64 bit)
2720     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextInfo(%X, %016I64X, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y);
2721 #endif
2722     // need to call only the HWND/VM that contains this AC
2723     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2724     if (destABWindow != (HWND) 0) {
2725         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2726             memcpy(textInfo, &(pkg->rTextInfo), sizeof(AccessibleTextInfo));
2727             if (pkg->rTextInfo.charCount != -1) {
2728                 PrintDebugString("[INFO]:   charCount: %d"\
2729                                  "          caretIndex: %d"\
2730                                  "          indexAtPoint: %d"\
2731                                  , textInfo->charCount, textInfo->caretIndex, textInfo->indexAtPoint);
2732                 return TRUE;
2733             }
2734         }
2735     }
2736 
2737     return FALSE;
2738 }
2739 
2740 /**
2741  * getAccessibleTextItems - fills a struct with letter, word, and sentence info
2742  * of the AccessibleText interface at a given index
2743  *
2744  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2745  */
2746 BOOL
getAccessibleTextItems(long vmID,JOBJECT64 AccessibleContext,AccessibleTextItemsInfo * textItems,jint index)2747 WinAccessBridge::getAccessibleTextItems(long vmID,
2748                                         JOBJECT64 AccessibleContext,
2749                                         AccessibleTextItemsInfo *textItems,
2750                                         jint index) {
2751     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2752         return FALSE;
2753     }
2754     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage)];
2755     PackageType *type = (PackageType *) buffer;
2756     GetAccessibleTextItemsPackage *pkg = (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType));
2757     *type = cGetAccessibleTextItemsPackage;
2758     pkg->vmID = vmID;
2759     pkg->AccessibleContext = AccessibleContext;
2760     pkg->index = index;
2761     // zero things out, in case the call fails
2762     pkg->rTextItemsInfo.letter = '\0';
2763     pkg->rTextItemsInfo.word[0] = '\0';
2764     pkg->rTextItemsInfo.sentence[0] = '\0';
2765 
2766 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2767     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextItems(%X, %p, %p, %d)", vmID, AccessibleContext, textItems, index);
2768 #else // JOBJECT64 is jlong (64 bit)
2769     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextItems(%X, %016I64X, %p, %d)", vmID, AccessibleContext, textItems, index);
2770 #endif
2771     // need to call only the HWND/VM that contains this AC
2772     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2773     if (destABWindow != (HWND) 0) {
2774         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2775             memcpy(textItems, &(pkg->rTextItemsInfo), sizeof(AccessibleTextItemsInfo));
2776             if (pkg->rTextItemsInfo.letter != '/0') {
2777                 return TRUE;
2778             }
2779         }
2780     }
2781 
2782     return FALSE;
2783 }
2784 
2785 /**
2786  * getAccessibleTextSelectionInfo - returns information about the selected
2787  * text of the object implementing AccessibleText
2788  *
2789  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2790  */
2791 BOOL
getAccessibleTextSelectionInfo(long vmID,JOBJECT64 AccessibleContext,AccessibleTextSelectionInfo * selectionInfo)2792 WinAccessBridge::getAccessibleTextSelectionInfo(long vmID,
2793                                                 JOBJECT64 AccessibleContext,
2794                                                 AccessibleTextSelectionInfo *selectionInfo) {
2795     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2796         return FALSE;
2797     }
2798     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage)];
2799     PackageType *type = (PackageType *) buffer;
2800     GetAccessibleTextSelectionInfoPackage *pkg = (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType));
2801     *type = cGetAccessibleTextSelectionInfoPackage;
2802     pkg->vmID = vmID;
2803     pkg->AccessibleContext = AccessibleContext;
2804 
2805 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2806     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextSelectionInfo(%X, %p, %p)", vmID, AccessibleContext, selectionInfo);
2807 #else // JOBJECT64 is jlong (64 bit)
2808     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextSelectionInfo(%X, %016I64X, %p)", vmID, AccessibleContext, selectionInfo);
2809 #endif
2810     // need to call only the HWND/VM that contains this AC
2811     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2812     if (destABWindow != (HWND) 0) {
2813         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2814             memcpy(selectionInfo, &(pkg->rTextSelectionItemsInfo), sizeof(AccessibleTextSelectionInfo));
2815             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
2816             return TRUE;
2817         }
2818     }
2819 
2820     return FALSE;
2821 }
2822 
2823 /**
2824  * getAccessibleTextAttributes - performs the Java code:
2825  *   ...[[[FIXME]]] fill in this comment...
2826  *
2827  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2828  */
2829 BOOL
getAccessibleTextAttributes(long vmID,JOBJECT64 AccessibleContext,jint index,AccessibleTextAttributesInfo * attributes)2830 WinAccessBridge::getAccessibleTextAttributes(long vmID,
2831                                              JOBJECT64 AccessibleContext,
2832                                              jint index,
2833                                              AccessibleTextAttributesInfo *attributes) {
2834     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2835         return FALSE;
2836     }
2837     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage)];
2838     PackageType *type = (PackageType *) buffer;
2839     GetAccessibleTextAttributeInfoPackage *pkg = (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType));
2840     *type = cGetAccessibleTextAttributeInfoPackage;
2841     pkg->vmID = vmID;
2842     pkg->AccessibleContext = AccessibleContext;
2843     pkg->index = index;
2844 
2845 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2846     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextAttributes(%X, %p, %d, %p)", vmID, AccessibleContext, index, attributes);
2847 #else // JOBJECT64 is jlong (64 bit)
2848     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextAttributes(%X, %016I64X, %d, %p)", vmID, AccessibleContext, index, attributes);
2849 #endif
2850     // need to call only the HWND/VM that contains this AC
2851     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2852     if (destABWindow != (HWND) 0) {
2853         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2854             memcpy(attributes, &(pkg->rAttributeInfo), sizeof(AccessibleTextAttributesInfo));
2855             return TRUE;
2856         }
2857     }
2858 
2859     return FALSE;
2860 }
2861 
2862 /**
2863  * getAccessibleTextRect - gets the text bounding rectangle
2864  *
2865  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2866  */
2867 BOOL
getAccessibleTextRect(long vmID,JOBJECT64 AccessibleContext,AccessibleTextRectInfo * rectInfo,jint index)2868 WinAccessBridge::getAccessibleTextRect(long vmID,
2869                                        JOBJECT64 AccessibleContext,
2870                                        AccessibleTextRectInfo *rectInfo,
2871                                        jint index) {
2872     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2873         return FALSE;
2874     }
2875     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage)];
2876     PackageType *type = (PackageType *) buffer;
2877     GetAccessibleTextRectInfoPackage *pkg = (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType));
2878     *type = cGetAccessibleTextRectInfoPackage;
2879     pkg->vmID = vmID;
2880     pkg->AccessibleContext = AccessibleContext;
2881     pkg->index = index;
2882 
2883 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2884     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRect(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2885 #else // JOBJECT64 is jlong (64 bit)
2886     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRect(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2887 #endif
2888     // need to call only the HWND/VM that contains this AC
2889     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2890     if (destABWindow != (HWND) 0) {
2891         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2892             memcpy(rectInfo, (&pkg->rTextRectInfo), sizeof(AccessibleTextRectInfo));
2893             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
2894             return TRUE;
2895         }
2896     }
2897 
2898     return FALSE;
2899 }
2900 
2901 
2902 /**
2903  * getAccessibleTextRect - gets the text bounding rectangle
2904  *
2905  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2906  */
2907 BOOL
getCaretLocation(long vmID,JOBJECT64 AccessibleContext,AccessibleTextRectInfo * rectInfo,jint index)2908 WinAccessBridge::getCaretLocation(long vmID,
2909                                        JOBJECT64 AccessibleContext,
2910                                        AccessibleTextRectInfo *rectInfo,
2911                                        jint index) {
2912     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2913         return FALSE;
2914     }
2915     char buffer[sizeof(PackageType) + sizeof(GetCaretLocationPackage)];
2916     PackageType *type = (PackageType *) buffer;
2917     GetCaretLocationPackage *pkg = (GetCaretLocationPackage *) (buffer + sizeof(PackageType));
2918     *type = cGetCaretLocationPackage;
2919     pkg->vmID = vmID;
2920     pkg->AccessibleContext = AccessibleContext;
2921     pkg->index = index;
2922 
2923 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2924     PrintDebugString("[INFO]: WinAccessBridge::getCaretLocation(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2925 #else // JOBJECT64 is jlong (64 bit)
2926     PrintDebugString("[INFO]: WinAccessBridge::getCaretLocation(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2927 #endif
2928     // need to call only the HWND/VM that contains this AC
2929     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2930     if (destABWindow != (HWND) 0) {
2931         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2932             memcpy(rectInfo, (&pkg->rTextRectInfo), sizeof(AccessibleTextRectInfo));
2933             return TRUE;
2934         }
2935     }
2936 
2937     return FALSE;
2938 }
2939 
2940 
2941 /**
2942  * getEventsWaiting - gets the number of events waiting to fire
2943  *
2944  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2945  */
2946 int
getEventsWaiting()2947 WinAccessBridge::getEventsWaiting() {
2948     if(messageQueue) {
2949         return(messageQueue->getEventsWaiting());
2950     }
2951     return(0);
2952 }
2953 
2954 
2955 /**
2956  * getAccessibleTextLineBounds - gets the bounding rectangle for the text line
2957  *
2958  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2959  */
2960 BOOL
getAccessibleTextLineBounds(long vmID,JOBJECT64 AccessibleContext,jint index,jint * startIndex,jint * endIndex)2961 WinAccessBridge::getAccessibleTextLineBounds(long vmID,
2962                                              JOBJECT64 AccessibleContext,
2963                                              jint index, jint *startIndex, jint *endIndex) {
2964     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2965         return FALSE;
2966     }
2967     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage)];
2968     PackageType *type = (PackageType *) buffer;
2969     GetAccessibleTextLineBoundsPackage *pkg = (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType));
2970     *type = cGetAccessibleTextLineBoundsPackage;
2971     pkg->vmID = vmID;
2972     pkg->AccessibleContext = AccessibleContext;
2973     pkg->index = index;
2974 
2975 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2976     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextLineBounds(%X, %p, %d, )", vmID, AccessibleContext, index);
2977 #else // JOBJECT64 is jlong (64 bit)
2978     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextLineBounds(%X, %016I64X, %d, )", vmID, AccessibleContext, index);
2979 #endif
2980     // need to call only the HWND/VM that contains this AC
2981     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2982     if (destABWindow != (HWND) 0) {
2983         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2984             *startIndex = pkg->rLineStart;
2985             *endIndex = pkg->rLineEnd;
2986             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
2987             return TRUE;
2988         }
2989     }
2990 
2991     return FALSE;
2992 }
2993 
2994 
2995 /**
2996  * getAccessibleTextLineBounds - performs the Java code:
2997  *   ...[[[FIXME]]] fill in this comment...
2998  *
2999  * Note: if the AccessibleContext parameter is bogus, this call will blow up
3000  */
3001 BOOL
getAccessibleTextRange(long vmID,JOBJECT64 AccessibleContext,jint start,jint end,wchar_t * text,short len)3002 WinAccessBridge::getAccessibleTextRange(long vmID,
3003                                         JOBJECT64 AccessibleContext,
3004                                         jint start, jint end, wchar_t *text, short len) {
3005     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3006         return FALSE;
3007     }
3008     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage)];
3009     PackageType *type = (PackageType *) buffer;
3010     GetAccessibleTextRangePackage *pkg = (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType));
3011     *type = cGetAccessibleTextRangePackage;
3012     pkg->vmID = vmID;
3013     pkg->AccessibleContext = AccessibleContext;
3014     pkg->start = start;
3015     pkg->end = end;
3016 
3017 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
3018     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRange(%X, %p, %d, %d, )", vmID, AccessibleContext, start, end);
3019 #else // JOBJECT64 is jlong (64 bit)
3020     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRange(%X, %016I64X, %d, %d, )", vmID, AccessibleContext, start, end);
3021 #endif
3022     // need to call only the HWND/VM that contains this AC
3023     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3024     if (destABWindow != (HWND) 0) {
3025         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
3026             wcsncpy(text, pkg->rText, len);
3027             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
3028             return TRUE;
3029         }
3030     }
3031 
3032     return FALSE;
3033 }
3034 
3035 
3036 
3037 
3038 /********** AccessibleValue routines ***************/
3039 
3040 BOOL
getCurrentAccessibleValueFromContext(long vmID,JOBJECT64 AccessibleContext,wchar_t * value,short len)3041 WinAccessBridge::getCurrentAccessibleValueFromContext(long vmID,
3042                                                       JOBJECT64 AccessibleContext,
3043                                                       wchar_t *value, short len) {
3044     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3045         return FALSE;
3046     }
3047     char buffer[sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage)];
3048     PackageType *type = (PackageType *) buffer;
3049     GetCurrentAccessibleValueFromContextPackage *pkg = (GetCurrentAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
3050     *type = cGetCurrentAccessibleValueFromContextPackage;
3051     pkg->vmID = vmID;
3052     pkg->AccessibleContext = AccessibleContext;
3053 
3054     // need to call only the HWND/VM that contains this AC
3055     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3056     if (destABWindow != (HWND) 0) {
3057         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
3058             wcsncpy(value, pkg->rValue, len);
3059             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
3060             return TRUE;
3061         }
3062     }
3063 
3064     return FALSE;
3065 }
3066 
3067 BOOL
getMaximumAccessibleValueFromContext(long vmID,JOBJECT64 AccessibleContext,wchar_t * value,short len)3068 WinAccessBridge::getMaximumAccessibleValueFromContext(long vmID,
3069                                                       JOBJECT64 AccessibleContext,
3070                                                       wchar_t *value, short len) {
3071     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3072         return FALSE;
3073     }
3074     char buffer[sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage)];
3075     PackageType *type = (PackageType *) buffer;
3076     GetMaximumAccessibleValueFromContextPackage *pkg = (GetMaximumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
3077     *type = cGetMaximumAccessibleValueFromContextPackage;
3078     pkg->vmID = vmID;
3079     pkg->AccessibleContext = AccessibleContext;
3080 
3081     // need to call only the HWND/VM that contains this AC
3082     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3083     if (destABWindow != (HWND) 0) {
3084         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
3085             wcsncpy(value, pkg->rValue, len);
3086             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
3087             return TRUE;
3088         }
3089     }
3090 
3091     return FALSE;
3092 }
3093 
3094 BOOL
getMinimumAccessibleValueFromContext(long vmID,JOBJECT64 AccessibleContext,wchar_t * value,short len)3095 WinAccessBridge::getMinimumAccessibleValueFromContext(long vmID,
3096                                                       JOBJECT64 AccessibleContext,
3097                                                       wchar_t *value, short len) {
3098     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3099         return FALSE;
3100     }
3101     char buffer[sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage)];
3102     PackageType *type = (PackageType *) buffer;
3103     GetMinimumAccessibleValueFromContextPackage *pkg = (GetMinimumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
3104     *type = cGetMinimumAccessibleValueFromContextPackage;
3105     pkg->vmID = vmID;
3106     pkg->AccessibleContext = AccessibleContext;
3107 
3108     // need to call only the HWND/VM that contains this AC
3109     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3110     if (destABWindow != (HWND) 0) {
3111         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
3112             wcsncpy(value, pkg->rValue, len);
3113             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
3114             return TRUE;
3115         }
3116     }
3117 
3118     return FALSE;
3119 }
3120 
3121 
3122 /********** AccessibleSelection routines ***************/
3123 
3124 void
addAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext,int i)3125 WinAccessBridge::addAccessibleSelectionFromContext(long vmID,
3126                                                    JOBJECT64 AccessibleContext, int i) {
3127     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3128         return;
3129     }
3130     char buffer[sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage)];
3131     PackageType *type = (PackageType *) buffer;
3132     AddAccessibleSelectionFromContextPackage *pkg = (AddAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
3133     *type = cAddAccessibleSelectionFromContextPackage;
3134     pkg->vmID = vmID;
3135     pkg->AccessibleContext = AccessibleContext;
3136     pkg->index = i;
3137 
3138     // need to call only the HWND/VM that contains this AC
3139     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3140     if (destABWindow != (HWND) 0) {
3141         sendMemoryPackage(buffer, sizeof(buffer), destABWindow);
3142     }
3143 }
3144 
3145 void
clearAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext)3146 WinAccessBridge::clearAccessibleSelectionFromContext(long vmID,
3147                                                      JOBJECT64 AccessibleContext) {
3148     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3149         return;
3150     }
3151     char buffer[sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage)];
3152     PackageType *type = (PackageType *) buffer;
3153     ClearAccessibleSelectionFromContextPackage *pkg = (ClearAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
3154     *type = cClearAccessibleSelectionFromContextPackage;
3155     pkg->vmID = vmID;
3156     pkg->AccessibleContext = AccessibleContext;
3157 
3158     // need to call only the HWND/VM that contains this AC
3159     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3160     if (destABWindow != (HWND) 0) {
3161         sendMemoryPackage(buffer, sizeof(buffer), destABWindow);
3162     }
3163 }
3164 
3165 JOBJECT64
getAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext,int i)3166 WinAccessBridge::getAccessibleSelectionFromContext(long vmID,
3167                                                    JOBJECT64 AccessibleContext, int i) {
3168     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3169         return (JOBJECT64)0;
3170     }
3171     char buffer[sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage)];
3172     PackageType *type = (PackageType *) buffer;
3173     GetAccessibleSelectionFromContextPackage *pkg = (GetAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
3174     *type = cGetAccessibleSelectionFromContextPackage;
3175     pkg->vmID = vmID;
3176     pkg->AccessibleContext = AccessibleContext;
3177     pkg->index = i;
3178 
3179     // need to call only the HWND/VM that contains this AC
3180     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3181     if (destABWindow != (HWND) 0) {
3182         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
3183             return pkg->rAccessibleContext;
3184         }
3185     }
3186 
3187     return (JOBJECT64) 0;
3188 }
3189 
3190 int
getAccessibleSelectionCountFromContext(long vmID,JOBJECT64 AccessibleContext)3191 WinAccessBridge::getAccessibleSelectionCountFromContext(long vmID,
3192                                                         JOBJECT64 AccessibleContext) {
3193     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3194         return -1;
3195     }
3196     char buffer[sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage)];
3197     PackageType *type = (PackageType *) buffer;
3198     GetAccessibleSelectionCountFromContextPackage *pkg = (GetAccessibleSelectionCountFromContextPackage *) (buffer + sizeof(PackageType));
3199     *type = cGetAccessibleSelectionCountFromContextPackage;
3200     pkg->vmID = vmID;
3201     pkg->AccessibleContext = AccessibleContext;
3202 
3203     // need to call only the HWND/VM that contains this AC
3204     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3205     if (destABWindow != (HWND) 0) {
3206         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
3207             return (int) pkg->rCount;
3208         }
3209     }
3210 
3211     return -1;
3212 }
3213 
3214 BOOL
isAccessibleChildSelectedFromContext(long vmID,JOBJECT64 AccessibleContext,int i)3215 WinAccessBridge::isAccessibleChildSelectedFromContext(long vmID,
3216                                                       JOBJECT64 AccessibleContext, int i) {
3217     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3218         return FALSE;
3219     }
3220     char buffer[sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage)];
3221     PackageType *type = (PackageType *) buffer;
3222     IsAccessibleChildSelectedFromContextPackage *pkg = (IsAccessibleChildSelectedFromContextPackage *) (buffer + sizeof(PackageType));
3223     *type = cIsAccessibleChildSelectedFromContextPackage;
3224     pkg->vmID = vmID;
3225     pkg->AccessibleContext = AccessibleContext;
3226     pkg->index = i;
3227 
3228     // need to call only the HWND/VM that contains this AC
3229     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3230     if (destABWindow != (HWND) 0) {
3231         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
3232             if (pkg->rResult != 0) {
3233                 return TRUE;
3234             }
3235         }
3236     }
3237 
3238     return FALSE;
3239 }
3240 
3241 
3242 void
removeAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext,int i)3243 WinAccessBridge::removeAccessibleSelectionFromContext(long vmID,
3244                                                       JOBJECT64 AccessibleContext, int i) {
3245     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3246         return;
3247     }
3248     char buffer[sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage)];
3249     PackageType *type = (PackageType *) buffer;
3250     RemoveAccessibleSelectionFromContextPackage *pkg = (RemoveAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
3251     *type = cRemoveAccessibleSelectionFromContextPackage;
3252     pkg->vmID = vmID;
3253     pkg->AccessibleContext = AccessibleContext;
3254     pkg->index = i;
3255 
3256     // need to call only the HWND/VM that contains this AC
3257     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3258     if (destABWindow != (HWND) 0) {
3259         sendMemoryPackage(buffer, sizeof(buffer), destABWindow);
3260     }
3261 }
3262 
3263 void
selectAllAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext)3264 WinAccessBridge::selectAllAccessibleSelectionFromContext(long vmID,
3265                                                          JOBJECT64 AccessibleContext) {
3266     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3267         return;
3268     }
3269     char buffer[sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage)];
3270     PackageType *type = (PackageType *) buffer;
3271     SelectAllAccessibleSelectionFromContextPackage *pkg = (SelectAllAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
3272     *type = cSelectAllAccessibleSelectionFromContextPackage;
3273     pkg->vmID = vmID;
3274     pkg->AccessibleContext = AccessibleContext;
3275 
3276     // need to call only the HWND/VM that contains this AC
3277     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3278     if (destABWindow != (HWND) 0) {
3279         sendMemoryPackage(buffer, sizeof(buffer), destABWindow);
3280     }
3281 }
3282 
3283 
3284 /*********** Event handling methods **********************************/
3285 
3286 /**
3287  * addEventNotification - tell all Java-launched AccessBridge DLLs
3288  *                        that we want events of the specified type
3289  *
3290  * [[[FIXME]]] since we're just sending a long & a source window,
3291  *                         we could use a private message rather than WM_COPYDATA
3292  *                         (though we still may want it to be synchronous; dunno...)
3293  *
3294  */
3295 void
addJavaEventNotification(jlong type)3296 WinAccessBridge::addJavaEventNotification(jlong type) {
3297     PrintDebugString("[INFO]: WinAccessBridge::addJavaEventNotification(%016I64X)", type);
3298     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3299         return;
3300     }
3301 
3302     char buffer[sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage)];
3303     PackageType *pkgType = (PackageType *) buffer;
3304     AddJavaEventNotificationPackage *pkg = (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
3305     *pkgType = cAddJavaEventNotificationPackage;
3306     pkg->type = type;
3307     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3308 
3309     PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %p",
3310                      *pkgType, pkg->type, pkg->DLLwindow);
3311 
3312     // send addEventNotification message to all JVMs
3313     isVMInstanceChainInUse = true;
3314     AccessBridgeJavaVMInstance *current = javaVMs;
3315     while (current != (AccessBridgeJavaVMInstance *) 0) {
3316         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3317         current = current->nextJVMInstance;
3318     }
3319     isVMInstanceChainInUse = false;
3320 }
3321 
3322 /**
3323  * removeEventNotification - tell all Java-launched AccessBridge DLLs
3324  *                                                       that we no longer want events of the
3325  *                                                       specified type
3326  *
3327  * [[[FIXME]]] since we're just sending a long & a source window,
3328  *                         we could use a private message rather than WM_COPYDATA
3329  *                         (though we still may want it to be synchronous; dunno...)
3330  *
3331  */
3332 void
removeJavaEventNotification(jlong type)3333 WinAccessBridge::removeJavaEventNotification(jlong type) {
3334     PrintDebugString("[INFO]: in WinAccessBridge::removeJavaEventNotification(%016I64X)", type);
3335     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3336         return;
3337     }
3338     char buffer[sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage)];
3339     PackageType *pkgType = (PackageType *) buffer;
3340     RemoveJavaEventNotificationPackage *pkg = (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
3341     *pkgType = cRemoveJavaEventNotificationPackage;
3342     pkg->type = type;
3343     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3344 
3345     PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %p",
3346                      *pkgType, pkg->type, pkg->DLLwindow);
3347 
3348     // send removeEventNotification message to all JVMs
3349     isVMInstanceChainInUse = true;
3350     AccessBridgeJavaVMInstance *current = javaVMs;
3351     while (current != (AccessBridgeJavaVMInstance *) 0) {
3352         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3353         current = current->nextJVMInstance;
3354     }
3355     isVMInstanceChainInUse = false;
3356 }
3357 
3358 
3359 /*********** Event handling methods **********************************/
3360 
3361 /**
3362  * addAccessibilityEventNotification - tell all Java-launched AccessBridge DLLs
3363  *                        that we want events of the specified type
3364  *
3365  * [[[FIXME]]] since we're just sending a long & a source window,
3366  *                         we could use a private message rather than WM_COPYDATA
3367  *                         (though we still may want it to be synchronous; dunno...)
3368  *
3369  */
3370 void
addAccessibilityEventNotification(jlong type)3371 WinAccessBridge::addAccessibilityEventNotification(jlong type) {
3372     PrintDebugString("[INFO]: in WinAccessBridge::addAccessibilityEventNotification(%016I64X)", type);
3373     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3374         return;
3375     }
3376     char buffer[sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage)];
3377     PackageType *pkgType = (PackageType *) buffer;
3378     AddAccessibilityEventNotificationPackage *pkg = (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
3379     *pkgType = cAddAccessibilityEventNotificationPackage;
3380     pkg->type = type;
3381     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3382 
3383     PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %X",
3384                      *pkgType, pkg->type, pkg->DLLwindow);
3385 
3386     // send addEventNotification message to all JVMs
3387     isVMInstanceChainInUse = true;
3388     AccessBridgeJavaVMInstance *current = javaVMs;
3389     while (current != (AccessBridgeJavaVMInstance *) 0) {
3390         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3391         current = current->nextJVMInstance;
3392     }
3393     isVMInstanceChainInUse = false;
3394 }
3395 
3396 /**
3397  * removeAccessibilityEventNotification - tell all Java-launched AccessBridge DLLs
3398  *                                                       that we no longer want events of the
3399  *                                                       specified type
3400  *
3401  * [[[FIXME]]] since we're just sending a long & a source window,
3402  *                         we could use a private message rather than WM_COPYDATA
3403  *                         (though we still may want it to be synchronous; dunno...)
3404  *
3405  */
3406 void
removeAccessibilityEventNotification(jlong type)3407 WinAccessBridge::removeAccessibilityEventNotification(jlong type) {
3408     PrintDebugString("[INFO]: in WinAccessBridge::removeAccessibilityEventNotification(%016I64X)", type);
3409     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3410         return;
3411     }
3412     char buffer[sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage)];
3413     PackageType *pkgType = (PackageType *) buffer;
3414     RemoveAccessibilityEventNotificationPackage *pkg = (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
3415     *pkgType = cRemoveAccessibilityEventNotificationPackage;
3416     pkg->type = type;
3417     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3418 
3419     PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %X",
3420                      *pkgType, pkg->type, pkg->DLLwindow);
3421 
3422     // send removeEventNotification message to all JVMs
3423     isVMInstanceChainInUse = true;
3424     AccessBridgeJavaVMInstance *current = javaVMs;
3425     while (current != (AccessBridgeJavaVMInstance *) 0) {
3426         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3427         current = current->nextJVMInstance;
3428     }
3429     isVMInstanceChainInUse = false;
3430 }
3431 
3432 
3433 #define CALL_SET_EVENT_FP(function, callbackFP)         \
3434         void WinAccessBridge::function(callbackFP fp) { \
3435                 eventHandler->function(fp, this);                       \
3436                 /* eventHandler calls back to winAccessBridgeDLL to set eventMask */    \
3437         }
3438 
setJavaShutdownFP(AccessBridge_JavaShutdownFP fp)3439     void WinAccessBridge::setJavaShutdownFP(AccessBridge_JavaShutdownFP fp) {
3440         eventHandler->setJavaShutdownFP(fp, this);
3441     }
3442 
3443     CALL_SET_EVENT_FP(setPropertyChangeFP, AccessBridge_PropertyChangeFP)
3444     CALL_SET_EVENT_FP(setFocusGainedFP, AccessBridge_FocusGainedFP)
3445     CALL_SET_EVENT_FP(setFocusLostFP, AccessBridge_FocusLostFP)
3446     CALL_SET_EVENT_FP(setCaretUpdateFP, AccessBridge_CaretUpdateFP)
3447     CALL_SET_EVENT_FP(setMouseClickedFP, AccessBridge_MouseClickedFP)
3448     CALL_SET_EVENT_FP(setMouseEnteredFP, AccessBridge_MouseEnteredFP)
3449     CALL_SET_EVENT_FP(setMouseExitedFP, AccessBridge_MouseExitedFP)
3450     CALL_SET_EVENT_FP(setMousePressedFP, AccessBridge_MousePressedFP)
3451     CALL_SET_EVENT_FP(setMouseReleasedFP, AccessBridge_MouseReleasedFP)
3452     CALL_SET_EVENT_FP(setMenuCanceledFP, AccessBridge_MenuCanceledFP)
3453     CALL_SET_EVENT_FP(setMenuDeselectedFP, AccessBridge_MenuDeselectedFP)
3454     CALL_SET_EVENT_FP(setMenuSelectedFP, AccessBridge_MenuSelectedFP)
3455     CALL_SET_EVENT_FP(setPopupMenuCanceledFP, AccessBridge_PopupMenuCanceledFP)
3456     CALL_SET_EVENT_FP(setPopupMenuWillBecomeInvisibleFP, AccessBridge_PopupMenuWillBecomeInvisibleFP)
3457     CALL_SET_EVENT_FP(setPopupMenuWillBecomeVisibleFP, AccessBridge_PopupMenuWillBecomeVisibleFP)
3458 
3459     CALL_SET_EVENT_FP(setPropertyNameChangeFP, AccessBridge_PropertyNameChangeFP)
3460     CALL_SET_EVENT_FP(setPropertyDescriptionChangeFP, AccessBridge_PropertyDescriptionChangeFP)
3461     CALL_SET_EVENT_FP(setPropertyStateChangeFP, AccessBridge_PropertyStateChangeFP)
3462     CALL_SET_EVENT_FP(setPropertyValueChangeFP, AccessBridge_PropertyValueChangeFP)
3463     CALL_SET_EVENT_FP(setPropertySelectionChangeFP, AccessBridge_PropertySelectionChangeFP)
3464     CALL_SET_EVENT_FP(setPropertyTextChangeFP, AccessBridge_PropertyTextChangeFP)
3465     CALL_SET_EVENT_FP(setPropertyCaretChangeFP, AccessBridge_PropertyCaretChangeFP)
3466     CALL_SET_EVENT_FP(setPropertyVisibleDataChangeFP, AccessBridge_PropertyVisibleDataChangeFP)
3467     CALL_SET_EVENT_FP(setPropertyChildChangeFP, AccessBridge_PropertyChildChangeFP)
3468     CALL_SET_EVENT_FP(setPropertyActiveDescendentChangeFP, AccessBridge_PropertyActiveDescendentChangeFP)
3469 
3470     CALL_SET_EVENT_FP(setPropertyTableModelChangeFP, AccessBridge_PropertyTableModelChangeFP)
3471