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