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