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