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