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