< prev index next >

src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.cpp

Print this page




  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:


 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;


 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 


 404  *                     In the SendMessage call, the third param (WPARAM) is
 405  *                     the source HWND (theDialogWindow in this case), and
 406  *                     the fourth param (LPARAM) is the size in bytes of
 407  *                     the package put into shared memory.
 408  *
 409  */
 410 BOOL
 411 WinAccessBridge::sendMemoryPackage(char *buffer, long bufsize, HWND destWindow) {
 412     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 413         return FALSE;
 414     }
 415     AccessBridgeJavaVMInstance *ourABJavaVMInstance;
 416     ourABJavaVMInstance = javaVMs->findABJavaVMInstanceFromJavaHWND(destWindow);
 417     if (ourABJavaVMInstance != (AccessBridgeJavaVMInstance *) 0) {
 418         if (!ourABJavaVMInstance->sendMemoryPackage(buffer, bufsize)) {
 419             // return falue to the caller
 420             memset(buffer, 0, bufsize);
 421             return FALSE;
 422         }
 423     } else {
 424         PrintDebugString("ERROR sending memory package: couldn't find destWindow");
 425         return FALSE;
 426     }
 427     return TRUE;
 428 }
 429 
 430 
 431 /**
 432  * queuePackage - put a package onto the queue for latter processing
 433  *
 434  */
 435 BOOL
 436 WinAccessBridge::queuePackage(char *buffer, long bufsize) {
 437     PrintDebugString("  in WinAccessBridge::queuePackage(%p, %d)", buffer, bufsize);
 438 
 439     AccessBridgeQueueElement *element = new AccessBridgeQueueElement(buffer, bufsize);
 440 
 441     messageQueue->add(element);
 442     PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0);
 443     return TRUE;
 444 }
 445 
 446 
 447 /**
 448  * receiveAQueuedPackage - remove a pending packge from the queue and
 449  *                         handle it. If the queue is busy, post a
 450  *                         message to self to retrieve it later
 451  *
 452  */
 453 BOOL
 454 WinAccessBridge::receiveAQueuedPackage() {
 455     AccessBridgeQueueElement *element = NULL;
 456 
 457     PrintDebugString("in WinAccessBridge::receiveAQueuedPackage()");
 458 
 459     // ensure against re-entrancy problems...
 460     if (messageQueue->getRemoveLockSetting() == FALSE) {
 461         messageQueue->setRemoveLock(TRUE);
 462 
 463         PrintDebugString("  dequeueing message");
 464 
 465         QueueReturns result = messageQueue->remove(&element);
 466 
 467         switch (result) {
 468 
 469         case cQueueBroken:
 470             PrintDebugString("  ERROR!!! Queue seems to be broken!");
 471             messageQueue->setRemoveLock(FALSE);
 472             return FALSE;
 473 
 474         case cMoreMessages:
 475         case cQueueEmpty:
 476             if (element != (AccessBridgeQueueElement *) 0) {
 477                 PrintDebugString("  found one; sending it!");
 478                 processPackage(element->buffer, element->bufsize);
 479                 delete element;
 480             } else {
 481                 PrintDebugString("  ODD... element == 0!");
 482                 return FALSE;
 483             }
 484             break;
 485 
 486         case cQueueInUse:
 487             PrintDebugString("  Queue in use, will try again later...");
 488             PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0);
 489             break;
 490 
 491         default:
 492             messageQueue->setRemoveLock(FALSE);
 493             return FALSE;       // should never get something we don't recognize!
 494         }
 495     } else {
 496         PrintDebugString("  unable to dequeue message; remove lock is set");
 497         PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); // Fix for 6995891
 498     }
 499 
 500     messageQueue->setRemoveLock(FALSE);
 501     return TRUE;
 502 }
 503 
 504 // -----------------------
 505 
 506 /**
 507  * preProcessPackage
 508  *              - do triage on incoming packages; queue some, deal with others
 509  *
 510  */
 511 void
 512 WinAccessBridge::preProcessPackage(char *buffer, long bufsize) {
 513     PrintDebugString("PreProcessing package sent from Java:");
 514 
 515     PackageType *type = (PackageType *) buffer;
 516 
 517     switch (*type) {
 518 
 519     PrintDebugString("   type == %X", *type);
 520 
 521     // event packages all get queued for later handling
 522     //case cPropertyChangePackage:
 523     case cJavaShutdownPackage:
 524     case cFocusGainedPackage:
 525     case cFocusLostPackage:
 526     case cCaretUpdatePackage:
 527     case cMouseClickedPackage:
 528     case cMouseEnteredPackage:
 529     case cMouseExitedPackage:
 530     case cMousePressedPackage:
 531     case cMouseReleasedPackage:
 532     case cMenuCanceledPackage:
 533     case cMenuDeselectedPackage:
 534     case cMenuSelectedPackage:
 535     case cPopupMenuCanceledPackage:
 536     case cPopupMenuWillBecomeInvisiblePackage:
 537     case cPopupMenuWillBecomeVisiblePackage:
 538 
 539     case cPropertyCaretChangePackage:
 540     case cPropertyDescriptionChangePackage:
 541     case cPropertyNameChangePackage:
 542     case cPropertySelectionChangePackage:
 543     case cPropertyStateChangePackage:
 544     case cPropertyTextChangePackage:
 545     case cPropertyValueChangePackage:
 546     case cPropertyVisibleDataChangePackage:
 547     case cPropertyChildChangePackage:
 548     case cPropertyActiveDescendentChangePackage:
 549 
 550     case cPropertyTableModelChangePackage:
 551 
 552         queuePackage(buffer, bufsize);
 553         break;
 554 
 555         // perhaps there will be some other packages to process at some point... //
 556 
 557     default:
 558         PrintDebugString("   processing FAILED!! -> don't know how to handle type = %X", *type);
 559         break;
 560     }
 561 
 562     PrintDebugString("   package preprocessing completed");
 563 }
 564 
 565 
 566 #define DISPATCH_EVENT_PACKAGE(packageID, eventPackage, fireEventMethod)            \
 567     case packageID:                                                                 \
 568         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
 569             eventPackage *pkg =                                                     \
 570                 (eventPackage *) (buffer + sizeof(PackageType));                    \
 571             PrintDebugString("   begin callback to AT, type == %X", *type);         \
 572                 theWindowsAccessBridge->eventHandler->fireEventMethod(              \
 573                     pkg->vmID, pkg->Event, pkg->AccessibleContextSource);           \
 574                 PrintDebugString("   event callback complete!");                    \
 575         } else {                                                                    \
 576             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d", \
 577                 bufsize, sizeof(PackageType) + sizeof(eventPackage));               \
 578         }                                                                           \
 579         break;
 580 
 581 #define DISPATCH_PROPERTY_CHANGE_PACKAGE(packageID, eventPackage, fireEventMethod, oldValue, newValue) \
 582     case packageID:                                                                 \
 583         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
 584             eventPackage *pkg =                                                     \
 585                 (eventPackage *) (buffer + sizeof(PackageType));                    \
 586             PrintDebugString("   begin callback to AT, type == %X", *type);         \
 587             theWindowsAccessBridge->eventHandler->fireEventMethod(                  \
 588                 pkg->vmID, pkg->Event, pkg->AccessibleContextSource,                \
 589                 pkg->oldValue, pkg->newValue);                                      \
 590             PrintDebugString("   event callback complete!");                        \
 591         } else {                                                                    \
 592             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d", \
 593                 bufsize, sizeof(PackageType) + sizeof(eventPackage));               \
 594         }                                                                           \
 595         break;
 596 
 597 #define DISPATCH_PROPERTY_TABLE_MODEL_CHANGE_PACKAGE(packageID, eventPackage, fireEventMethod, oldValue, newValue) \
 598     case packageID:                                                                 \
 599         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
 600             eventPackage *pkg =                                                     \
 601                 (eventPackage *) (buffer + sizeof(PackageType));                    \
 602             PrintDebugString("   begin callback to AT, type == %X", *type);         \
 603             theWindowsAccessBridge->eventHandler->fireEventMethod(                  \
 604                 pkg->vmID, pkg->Event, pkg->AccessibleContextSource,                \
 605                 pkg->oldValue, pkg->newValue);                                      \
 606             PrintDebugString("   event callback complete!");                        \
 607         } else {                                                                    \
 608             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d", \
 609                 bufsize, sizeof(PackageType) + sizeof(eventPackage));                \
 610         }                                                                            \
 611         break;
 612 
 613 /**
 614  * processPackage - processes the output of SendMessage(WM_COPYDATA)
 615  *                  to do IPC messaging with the Java AccessBridge DLL
 616  *
 617  */
 618 void
 619 WinAccessBridge::processPackage(char *buffer, long bufsize) {
 620     PrintDebugString("WinAccessBridge::Processing package sent from Java:");
 621 
 622     PackageType *type = (PackageType *) buffer;
 623 
 624     switch (*type) {
 625 
 626     PrintDebugString("   type == %X", *type);
 627 
 628     case cJavaShutdownPackage:
 629         PrintDebugString("   type == cJavaShutdownPackage");
 630         if (bufsize == sizeof(PackageType) + sizeof(JavaShutdownPackage)) {
 631             JavaShutdownPackage *pkg =
 632                 (JavaShutdownPackage *) (buffer + sizeof(PackageType));
 633             theWindowsAccessBridge->eventHandler->fireJavaShutdown(pkg->vmID);
 634             PrintDebugString("   event callback complete!");
 635             PrintDebugString("   event fired!");
 636         } else {
 637             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 638                              bufsize, sizeof(PackageType) + sizeof(JavaShutdownPackage));
 639         }
 640         break;
 641 
 642 
 643         DISPATCH_EVENT_PACKAGE(cFocusGainedPackage, FocusGainedPackage, fireFocusGained);
 644         DISPATCH_EVENT_PACKAGE(cFocusLostPackage, FocusLostPackage, fireFocusLost);
 645 
 646         DISPATCH_EVENT_PACKAGE(cCaretUpdatePackage, CaretUpdatePackage, fireCaretUpdate);
 647 
 648         DISPATCH_EVENT_PACKAGE(cMouseClickedPackage, MouseClickedPackage, fireMouseClicked);
 649         DISPATCH_EVENT_PACKAGE(cMouseEnteredPackage, MouseEnteredPackage, fireMouseEntered);
 650         DISPATCH_EVENT_PACKAGE(cMouseExitedPackage, MouseExitedPackage, fireMouseExited);
 651         DISPATCH_EVENT_PACKAGE(cMousePressedPackage, MousePressedPackage, fireMousePressed);
 652         DISPATCH_EVENT_PACKAGE(cMouseReleasedPackage, MouseReleasedPackage, fireMouseReleased);
 653 
 654         DISPATCH_EVENT_PACKAGE(cMenuCanceledPackage, MenuCanceledPackage, fireMenuCanceled);
 655         DISPATCH_EVENT_PACKAGE(cMenuDeselectedPackage, MenuDeselectedPackage, fireMenuDeselected);
 656         DISPATCH_EVENT_PACKAGE(cMenuSelectedPackage, MenuSelectedPackage, fireMenuSelected);
 657         DISPATCH_EVENT_PACKAGE(cPopupMenuCanceledPackage, PopupMenuCanceledPackage, firePopupMenuCanceled);


 681             DISPATCH_EVENT_PACKAGE(cPropertyVisibleDataChangePackage,
 682                                    PropertyVisibleDataChangePackage, firePropertyVisibleDataChange)
 683             DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyChildChangePackage,
 684                                              PropertyChildChangePackage,
 685                                              firePropertyChildChange,
 686                                              oldChildAccessibleContext,
 687                                              newChildAccessibleContext)
 688             DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyActiveDescendentChangePackage,
 689                                              PropertyActiveDescendentChangePackage,
 690                                              firePropertyActiveDescendentChange,
 691                                              oldActiveDescendentAccessibleContext,
 692                                              newActiveDescendentAccessibleContext)
 693 
 694             DISPATCH_PROPERTY_TABLE_MODEL_CHANGE_PACKAGE(cPropertyTableModelChangePackage,
 695                                                          PropertyTableModelChangePackage,
 696                                                          firePropertyTableModelChange,
 697                                                          oldValue, newValue)
 698 
 699 
 700             default:
 701         PrintDebugString("   processing FAILED!! -> don't know how to handle type = %X", *type);
 702         break;
 703     }
 704 
 705     PrintDebugString("   package processing completed");
 706 }
 707 
 708 
 709 // -----------------------------
 710 
 711 void
 712 WinAccessBridge::JavaVMDestroyed(HWND VMBridgeDLLWindow) {
 713     PrintDebugString("***** WinAccessBridge::JavaVMDestroyed(%p)", VMBridgeDLLWindow);
 714 
 715     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 716         return;
 717     }
 718 
 719     isVMInstanceChainInUse = true;
 720     AccessBridgeJavaVMInstance *currentVM = javaVMs;
 721     AccessBridgeJavaVMInstance *previousVM = javaVMs;
 722     if (javaVMs->javaAccessBridgeWindow == VMBridgeDLLWindow) {
 723         javaVMs = javaVMs->nextJVMInstance;
 724         delete currentVM;
 725 
 726         PrintDebugString("  data structures successfully removed");
 727 
 728         // [[[FIXME]]] inform Windows AT that a JVM went away,
 729         // and that any jobjects it's got lying around for that JVM
 730         // are now invalid
 731 
 732     } else {
 733         while (currentVM != (AccessBridgeJavaVMInstance *) 0) {
 734             if (currentVM->javaAccessBridgeWindow == VMBridgeDLLWindow) {
 735                 previousVM->nextJVMInstance = currentVM->nextJVMInstance;
 736                 delete currentVM;
 737 
 738                 PrintDebugString("  data structures successfully removed");
 739 
 740                 // [[[FIXME]]] inform Windows AT that a JVM went away,
 741                 // and that any jobjects it's got lying around for that JVM
 742                 // are now invalid
 743                 isVMInstanceChainInUse = false;
 744                 return;
 745             } else {
 746                 previousVM = currentVM;
 747                 currentVM = currentVM->nextJVMInstance;
 748             }
 749         }
 750         PrintDebugString("  ERROR!! couldn't find matching data structures!");
 751     }
 752     isVMInstanceChainInUse = false;
 753 }
 754 
 755 // -----------------------
 756 
 757 /**
 758  * releaseJavaObject - lets the JavaVM know it can release the Java Object
 759  *
 760  * Note: once you have made this call, the JavaVM will garbage collect
 761  * the jobject you pass in.  If you later use that jobject in another
 762  * call, you will cause all maner of havoc!
 763  *
 764  */
 765 void
 766 WinAccessBridge::releaseJavaObject(long vmID, JOBJECT64 object) {
 767 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
 768     PrintDebugString("WinAccessBridge::releaseJavaObject(%X, %p)", vmID, object);
 769 #else // JOBJECT64 is jlong (64 bit)
 770     PrintDebugString("WinAccessBridge::releaseJavaObject(%X, %016I64X)", vmID, object);
 771 #endif
 772     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 773         return;
 774     }
 775     char buffer[sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage)];
 776     PackageType *type = (PackageType *) buffer;
 777     ReleaseJavaObjectPackage *pkg = (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType));
 778     *type = cReleaseJavaObjectPackage;
 779     pkg->vmID = vmID;
 780     pkg->object = object;
 781 
 782     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
 783     if (destABWindow != (HWND) 0) {
 784         sendPackage(buffer, sizeof(buffer), destABWindow);              // no return values!
 785     }
 786 }
 787 
 788 // -----------------------
 789 
 790 /**
 791  * getVersionInfo - fill the AccessBridgeVersionInfo struct
 792  *
 793  */
 794 BOOL
 795 WinAccessBridge::getVersionInfo(long vmID, AccessBridgeVersionInfo *info) {
 796     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 797         return FALSE;
 798     }
 799     char buffer[sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage)];
 800     PackageType *type = (PackageType *) buffer;
 801     GetAccessBridgeVersionPackage *pkg = (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType));
 802     *type = cGetAccessBridgeVersionPackage;
 803     pkg->vmID = vmID;
 804 
 805     PrintDebugString("WinAccessBridge::getVersionInfo(%X, )", vmID);
 806     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
 807     if (destABWindow != (HWND) 0) {
 808         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
 809             memcpy(info, &(pkg->rVersionInfo), sizeof(AccessBridgeVersionInfo));
 810             PrintDebugString("  VMversion: %ls", info->VMversion);
 811             PrintDebugString("  bridgeJavaClassVersion: %ls", info->bridgeJavaClassVersion);
 812             PrintDebugString("  bridgeJavaDLLVersion: %ls", info->bridgeJavaDLLVersion);
 813             PrintDebugString("  bridgeWinDLLVersion: %ls", info->bridgeWinDLLVersion);

 814             return TRUE;
 815         }
 816     }
 817     return FALSE;
 818 }
 819 
 820 
 821 /********** Window-related routines ***********************************/
 822 
 823 /**
 824  * isJavaWindow - returns TRUE if the HWND is a top-level Java Window
 825  *
 826  * Note: just because the Windnow is a top-level Java window, that doesn't
 827  * mean that it is accessible.  Call getAccessibleContextFromHWND(HWND) to get the
 828  * AccessibleContext, if any, for an HWND that is a Java Window.
 829  *
 830  */
 831 BOOL
 832 WinAccessBridge::isJavaWindow(HWND window) {
 833     HWND hwnd;
 834 
 835     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 836         return FALSE;
 837     }
 838 
 839     // quick check to see if 'window' is top-level; if not, it's not interesting...
 840     // [[[FIXME]]] is this for sure an OK optimization?
 841     hwnd = getTopLevelHWND(window);
 842     if (hwnd == (HWND) NULL) {
 843         return FALSE;
 844     }
 845 
 846     PrintDebugString("In WinAccessBridge::isJavaWindow");
 847 
 848 
 849 
 850     char buffer[sizeof(PackageType) + sizeof(IsJavaWindowPackage)];
 851     PackageType *type = (PackageType *) buffer;
 852     IsJavaWindowPackage *pkg = (IsJavaWindowPackage *) (buffer + sizeof(PackageType));
 853     *type = cIsJavaWindowPackage;
 854     pkg->window = (jint) window;
 855 
 856     PrintDebugString("WinAccessBridge::isJavaWindow(%p)", window);
 857 
 858     isVMInstanceChainInUse = true;
 859     AccessBridgeJavaVMInstance *current = javaVMs;
 860     while (current != (AccessBridgeJavaVMInstance *) 0) {
 861         if (sendMemoryPackage(buffer, sizeof(buffer), current->javaAccessBridgeWindow) == TRUE) {
 862             if (pkg->rResult != 0) {
 863                 isVMInstanceChainInUse = false;
 864                 return TRUE;
 865             }
 866         }
 867         current = current->nextJVMInstance;
 868     }
 869     isVMInstanceChainInUse = false;
 870     return FALSE;
 871 
 872 
 873     /*
 874       char classname[256];
 875       HWND hwnd;
 876 


 891     // JDK 1.4 introduces new (and changes old) classnames
 892     /*
 893       else if (strstr(classname, "SunAwtToolkit") != 0) {
 894       return TRUE;
 895       } else if (strstr(classname, "javax.swing.JFrame") != 0) {
 896       return TRUE;
 897       }
 898     */
 899 
 900     return FALSE;
 901 }
 902 
 903 /**
 904  * isSameObject - returns TRUE if the two object references refer to
 905  *     the same object. Otherwise, this method returns FALSE:
 906  */
 907 BOOL
 908 WinAccessBridge::isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) {
 909 
 910 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
 911     PrintDebugString("WinAccessBridge::isSameObject(%p %p)", obj1, obj2);
 912 #else // JOBJECT64 is jlong (64 bit)
 913     PrintDebugString("WinAccessBridge::isSameObject(%016I64X %016I64X)", obj1, obj2);
 914 #endif
 915 
 916     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 917         return FALSE;
 918     }
 919 
 920     char buffer[sizeof(PackageType) + sizeof(IsSameObjectPackage)];
 921     PackageType *type = (PackageType *) buffer;
 922     IsSameObjectPackage *pkg = (IsSameObjectPackage *) (buffer + sizeof(PackageType));
 923     *type = cIsSameObjectPackage;
 924     pkg->vmID = vmID;
 925     pkg->obj1 = obj1;
 926     pkg->obj2 = obj2;
 927 
 928     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
 929     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
 930         if (pkg->rResult != 0) {
 931             PrintDebugString("  WinAccessBridge::isSameObject returning TRUE (same object)");
 932             return TRUE;
 933         } else {
 934             PrintDebugString("  WinAccessBridge::isSameObject returning FALSE (different object)");
 935             return FALSE;
 936         }
 937     }
 938     PrintDebugString("  WinAccessBridge::isSameObject returning FALSE (sendMemoryPackage failed)");
 939     return FALSE;
 940 }
 941 
 942 /**
 943  * FromHWND - returns the AccessibleContext jobject for the HWND
 944  *
 945  * Note: this routine can return null, even if the HWND is a Java Window,
 946  * because the Java Window may not be accessible.
 947  *
 948  */
 949 BOOL
 950 WinAccessBridge::getAccessibleContextFromHWND(HWND window, long *vmID, JOBJECT64 *AccessibleContext) {
 951     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 952         return FALSE;
 953     }
 954 
 955     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage)];
 956     PackageType *type = (PackageType *) buffer;
 957     GetAccessibleContextFromHWNDPackage *pkg = (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType));
 958     *type = cGetAccessibleContextFromHWNDPackage;
 959     pkg->window = (jint) window;
 960 
 961     PrintDebugString("WinAccessBridge::getAccessibleContextFromHWND(%p, )", window);
 962 
 963     DEBUG_CODE(pkg->rVMID = (long ) 0x01010101);
 964     DEBUG_CODE(pkg->rAccessibleContext = (JOBJECT64) 0x01010101);
 965 
 966     isVMInstanceChainInUse = true;
 967     AccessBridgeJavaVMInstance *current = javaVMs;
 968     while (current != (AccessBridgeJavaVMInstance *) 0) {
 969 
 970         if (sendMemoryPackage(buffer, sizeof(buffer), current->javaAccessBridgeWindow) == TRUE) {
 971             if (pkg->rAccessibleContext != 0) {
 972                 *vmID = pkg->rVMID;
 973                 *AccessibleContext = (JOBJECT64)pkg->rAccessibleContext;
 974                 PrintDebugString("    current->vmID = %X", current->vmID);
 975                 PrintDebugString("    pkg->rVMID = %X", pkg->rVMID);
 976 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
 977                 PrintDebugString("    pkg->rAccessibleContext = %p", pkg->rAccessibleContext);
 978 #else // JOBJECT64 is jlong (64 bit)
 979                 PrintDebugString("    pkg->rAccessibleContext = %016I64X", pkg->rAccessibleContext);
 980 #endif
 981                 if (pkg->rVMID != current->vmID) {
 982                     PrintDebugString("    ERROR! getAccessibleContextFromHWND vmIDs don't match!");
 983                     isVMInstanceChainInUse = false;
 984                     return FALSE;
 985                 }
 986                 isVMInstanceChainInUse = false;
 987                 return TRUE;
 988             }
 989         }
 990         current = current->nextJVMInstance;
 991     }
 992     isVMInstanceChainInUse = false;
 993 
 994     // This isn't really an error; it just means that the HWND was for a non-Java
 995     // window.  It's also possible the HWND was for a Java window but the JVM has
 996     // since been shut down and sendMemoryPackage returned FALSE.
 997     PrintDebugString("    ERROR! getAccessibleContextFromHWND no matching HWND found!");
 998     return FALSE;
 999 }
1000 
1001 /**
1002  * Returns the HWND for an AccessibleContext.  Returns (HWND)0 on error.
1003  */
1004 HWND
1005 WinAccessBridge::getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext) {
1006     PrintDebugString("  in WinAccessBridge::getHWNDFromAccessibleContext");
1007     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1008         return (HWND)0;
1009     }
1010 
1011     char buffer[sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage)];
1012     PackageType *type = (PackageType *) buffer;
1013     GetHWNDFromAccessibleContextPackage *pkg = (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType));
1014     *type = cGetHWNDFromAccessibleContextPackage;
1015     pkg->accessibleContext = accessibleContext;
1016 
1017 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1018     PrintDebugString("WinAccessBridge::getHWNDFromAccessibleContext(%p)", accessibleContext);
1019 #else // JOBJECT64 is jlong (64 bit)
1020     PrintDebugString("WinAccessBridge::getHWNDFromAccessibleContext(%016I64X)", accessibleContext);
1021 #endif
1022 
1023     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1024     if (destABWindow != (HWND) 0) {
1025         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1026             return ((HWND)ABLongToHandle(pkg->rHWND));
1027         }
1028     }
1029     return (HWND)0;
1030 }
1031 
1032 /********** AccessibleContext routines ***********************************/
1033 
1034 /**
1035  * Walk through Java Windows, in front-to-back Z-order.
1036  * If NULL is passed it, this function starts at the top.
1037  *
1038  */
1039 HWND
1040 WinAccessBridge::getNextJavaWindow(HWND previous) {


1064  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1065  * of this functionality may be built into the platform
1066  *
1067  */
1068 BOOL
1069 WinAccessBridge::getAccessibleContextAt(long vmID, JOBJECT64 AccessibleContextParent,
1070                                         jint x, jint y, JOBJECT64 *AccessibleContext) {
1071     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1072         return FALSE;
1073     }
1074 
1075     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage)];
1076     PackageType *type = (PackageType *) buffer;
1077     GetAccessibleContextAtPackage *pkg = (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType));
1078     *type = cGetAccessibleContextAtPackage;
1079     pkg->vmID = vmID;
1080     pkg->AccessibleContext = AccessibleContextParent;
1081     pkg->x = x;
1082     pkg->y = y;
1083 
1084     PrintDebugString("WinAccessBridge::getAccessibleContextAt(%X, %p, %d, %c)", vmID, AccessibleContextParent, x, y);
1085     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
1086     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1087         *AccessibleContext = pkg->rAccessibleContext;
1088         return TRUE;
1089     }
1090 
1091     return FALSE;
1092 }
1093 
1094 
1095 /**
1096  * getAccessibleContextWithFocus - performs the Java code:
1097  *   Accessible a = Translator.getAccessible(SwingEventMonitor.getComponentWithFocus());
1098  *   return a.getAccessibleContext();
1099  *
1100  * Note: this call explicitly goes through the AccessBridge,
1101  * so that the AccessBridge can hide expected changes in how this functions
1102  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1103  * of this functionality may be built into the platform
1104  *
1105  */
1106 BOOL
1107 WinAccessBridge::getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT64 *AccessibleContext) {
1108 
1109     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1110         return FALSE;
1111     }
1112     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage)];
1113     PackageType *type = (PackageType *) buffer;
1114     GetAccessibleContextWithFocusPackage *pkg = (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType));
1115     *type = cGetAccessibleContextWithFocusPackage;
1116 
1117     PrintDebugString("WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID);
1118     // find vmID, etc. from HWND; ask that VM for the AC w/Focus
1119     HWND pkgVMID;
1120     if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) {
1121         HWND destABWindow = javaVMs->findAccessBridgeWindow((long)pkgVMID);     // ineffecient [[[FIXME]]]
1122         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1123             *vmID = pkg->rVMID;
1124             *AccessibleContext = pkg->rAccessibleContext;
1125             return TRUE;
1126         }
1127     }
1128 
1129     return FALSE;
1130 }
1131 
1132 /**
1133  * getAccessibleContextInfo - fills a struct with a bunch of information
1134  * contained in the Java Accessibility API
1135  *
1136  *
1137  * Note: if the AccessibleContext parameter is bogus, this call will blow up
1138  */
1139 BOOL
1140 WinAccessBridge::getAccessibleContextInfo(long vmID,
1141                                           JOBJECT64 accessibleContext,
1142                                           AccessibleContextInfo *info) {
1143     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1144         return FALSE;
1145     }
1146     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage)];
1147     PackageType *type = (PackageType *) buffer;
1148     GetAccessibleContextInfoPackage *pkg = (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType));
1149     *type = cGetAccessibleContextInfoPackage;
1150     pkg->vmID = vmID;
1151     pkg->AccessibleContext = accessibleContext;
1152 
1153 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1154     PrintDebugString("WinAccessBridge::getAccessibleContextInfo(%X, %p, )", vmID, accessibleContext);
1155 #else // JOBJECT64 is jlong (64 bit)
1156     PrintDebugString("WinAccessBridge::getAccessibleContextInfo(%X, %016I64X, )", vmID, accessibleContext);
1157 #endif
1158     // need to call only the HWND/VM that contains this AC
1159     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1160     if (destABWindow != (HWND) 0) {
1161         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1162             memcpy(info, &(pkg->rAccessibleContextInfo), sizeof(AccessibleContextInfo));
1163             PrintDebugString("  name: %ls", info->name);
1164             PrintDebugString("  description: %ls", info->description);
1165             PrintDebugString("  role: %ls", info->role);
1166             PrintDebugString("  role_en_US: %ls", info->role_en_US);
1167             PrintDebugString("  states: %ls", info->states);
1168             PrintDebugString("  states_en_US: %ls", info->states_en_US);

1169             return TRUE;
1170         }
1171     }
1172 
1173     return FALSE;
1174 }
1175 
1176 /**
1177  * getAccessibleChildFromContext - performs the Java code:
1178  *   Accessible child = ac.getAccessibleChild(i);
1179  *   return child.getAccessibleContext();
1180  *
1181  * Note: this call explicitly goes through the AccessBridge,
1182  * so that the AccessBridge can hide expected changes in how this functions
1183  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1184  * of this functionality may be built into the platform
1185  *
1186  */
1187 JOBJECT64
1188 WinAccessBridge::getAccessibleChildFromContext(long vmID,
1189                                                JOBJECT64 AccessibleContext,
1190                                                jint childIndex) {
1191     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1192         return (JOBJECT64)0;
1193     }
1194     char buffer[sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage)];
1195     PackageType *type = (PackageType *) buffer;
1196     GetAccessibleChildFromContextPackage *pkg = (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType));
1197     *type = cGetAccessibleChildFromContextPackage;
1198     pkg->vmID = vmID;
1199     pkg->AccessibleContext = AccessibleContext;
1200     pkg->childIndex = childIndex;
1201 
1202 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1203     PrintDebugString("WinAccessBridge::getAccessibleChildFromContext(%X, %p, %d)", vmID, AccessibleContext, childIndex);
1204 #else // JOBJECT64 is jlong (64 bit)
1205     PrintDebugString("WinAccessBridge::getAccessibleChildFromContext(%X, %016I64X, %d)", vmID, AccessibleContext, childIndex);
1206 #endif
1207     // need to call only the HWND/VM that contains this AC
1208     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1209     if (destABWindow != (HWND) 0) {
1210         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1211             return pkg->rAccessibleContext;
1212         }
1213     }
1214 
1215     return (JOBJECT64) 0;
1216 }
1217 
1218 /**
1219  * getAccessibleParentFromContext - returns the parent AccessibleContext jobject
1220  *
1221  * Note: this may be null, if the AccessibleContext passed in is a top-level
1222  * window, then it has no parent.
1223  *
1224  */
1225 JOBJECT64
1226 WinAccessBridge::getAccessibleParentFromContext(long vmID,
1227                                                 JOBJECT64 AccessibleContext) {
1228     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1229         return (JOBJECT64)0;
1230     }
1231     char buffer[sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage)];
1232     PackageType *type = (PackageType *) buffer;
1233     GetAccessibleParentFromContextPackage *pkg = (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType));
1234     *type = cGetAccessibleParentFromContextPackage;
1235     pkg->vmID = vmID;
1236     pkg->AccessibleContext = AccessibleContext;
1237 
1238     PrintDebugString("WinAccessBridge::getAccessibleParentFromContext(%X, %p)", vmID, AccessibleContext);
1239     // need to call only the HWND/VM that contains this AC
1240     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1241     if (destABWindow != (HWND) 0) {
1242         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1243             return pkg->rAccessibleContext;
1244         }
1245     }
1246 
1247     return (JOBJECT64) 0;
1248 }
1249 
1250 /********** AccessibleTable routines ***********************************/
1251 
1252 BOOL
1253 WinAccessBridge::getAccessibleTableInfo(long vmID,
1254                                         JOBJECT64 accessibleContext,
1255                                         AccessibleTableInfo *tableInfo) {
1256 
1257 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1258     PrintDebugString("##### WinAccessBridge::getAccessibleTableInfo(%X, %p, %p)", vmID, accessibleContext,
1259                      tableInfo);
1260 #else // JOBJECT64 is jlong (64 bit)
1261     PrintDebugString("##### WinAccessBridge::getAccessibleTableInfo(%X, %016I64X, %p)", vmID, accessibleContext,
1262                      tableInfo);
1263 #endif
1264 
1265     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1266         return FALSE;
1267     }
1268     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage)];
1269     PackageType *type = (PackageType *) buffer;
1270     GetAccessibleTableInfoPackage *pkg = (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType));
1271     *type = cGetAccessibleTableInfoPackage;
1272     pkg->vmID = vmID;
1273     pkg->accessibleContext = accessibleContext;
1274 
1275     // need to call only the HWND/VM that contains this AC
1276     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1277     if (destABWindow != (HWND) 0) {
1278         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1279             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
1280             if (pkg->rTableInfo.rowCount != -1) {
1281                 PrintDebugString("  ##### WinAccessBridge::getAccessibleTableInfo succeeded");
1282                 return TRUE;
1283             }
1284         }
1285     }
1286     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableInfo failed");
1287     return FALSE;
1288 }
1289 
1290 BOOL
1291 WinAccessBridge::getAccessibleTableCellInfo(long vmID, JOBJECT64 accessibleTable,
1292                                             jint row, jint column,
1293                                             AccessibleTableCellInfo *tableCellInfo) {
1294 
1295     PrintDebugString("##### WinAccessBridge::getAccessibleTableCellInfo(%X, %p, %d, %d, %p)", vmID,
1296                      accessibleTable, row, column, tableCellInfo);
1297 
1298     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1299         return FALSE;
1300     }
1301 
1302     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage)];
1303     PackageType *type = (PackageType *) buffer;
1304     GetAccessibleTableCellInfoPackage *pkg = (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType));
1305     *type = cGetAccessibleTableCellInfoPackage;
1306     pkg->vmID = vmID;
1307     pkg->accessibleTable = accessibleTable;
1308     pkg->row = row;
1309     pkg->column = column;
1310     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1311 
1312     if (destABWindow != (HWND) 0) {
1313         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1314             PrintDebugString("  XXXX pkg->rTableCellInfo.accessibleContext = %p", pkg->rTableCellInfo.accessibleContext);
1315             memcpy(tableCellInfo, &(pkg->rTableCellInfo), sizeof(AccessibleTableCellInfo));
1316             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableCellInfo succeeded");
1317             return TRUE;
1318         }
1319     }
1320     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableCellInfo failed");
1321     return FALSE;
1322 }
1323 
1324 
1325 BOOL
1326 WinAccessBridge::getAccessibleTableRowHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) {
1327 
1328 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1329     PrintDebugString("##### WinAccessBridge::getAccessibleTableRowHeader(%X, %p)", vmID, accessibleContext);
1330 #else // JOBJECT64 is jlong (64 bit)
1331     PrintDebugString("##### WinAccessBridge::getAccessibleTableRowHeader(%X, %016I64X)", vmID, accessibleContext);
1332 #endif
1333 
1334     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1335         return FALSE;
1336     }
1337     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage)];
1338     PackageType *type = (PackageType *) buffer;
1339     GetAccessibleTableRowHeaderPackage *pkg = (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType));
1340     *type = cGetAccessibleTableRowHeaderPackage;
1341     pkg->vmID = vmID;
1342     pkg->accessibleContext = accessibleContext;
1343 
1344     // need to call only the HWND/VM that contains this AC
1345     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1346     if (destABWindow != (HWND) 0) {
1347         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1348             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowHeader succeeded");
1349             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
1350             return TRUE;
1351         }
1352     }
1353     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowHeader failed");
1354     return FALSE;
1355 }
1356 
1357 BOOL
1358 WinAccessBridge::getAccessibleTableColumnHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) {
1359 
1360 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1361     PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %p)", vmID, accessibleContext);
1362 #else // JOBJECT64 is jlong (64 bit)
1363     PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %016I64X)", vmID, accessibleContext);
1364 #endif
1365 
1366     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1367         return FALSE;
1368     }
1369     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage)];
1370     PackageType *type = (PackageType *) buffer;
1371     GetAccessibleTableColumnHeaderPackage *pkg = (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType));
1372     *type = cGetAccessibleTableColumnHeaderPackage;
1373     pkg->vmID = vmID;
1374     pkg->accessibleContext = accessibleContext;
1375 
1376     // need to call only the HWND/VM that contains this AC
1377     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1378     if (destABWindow != (HWND) 0) {
1379         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1380             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnHeader succeeded");
1381             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
1382             return TRUE;
1383         }
1384     }
1385     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnHeader failed");
1386     return FALSE;
1387 }
1388 
1389 JOBJECT64
1390 WinAccessBridge::getAccessibleTableRowDescription(long vmID,
1391                                                   JOBJECT64 accessibleContext,
1392                                                   jint row) {
1393 
1394 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1395     PrintDebugString("##### WinAccessBridge::getAccessibleTableRowDescription(%X, %p, %d)", vmID, accessibleContext,
1396                      row);
1397 #else // JOBJECT64 is jlong (64 bit)
1398     PrintDebugString("##### WinAccessBridge::getAccessibleTableRowDescription(%X, %016I64X, %d)", vmID, accessibleContext,
1399                      row);
1400 #endif
1401 
1402     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1403         return FALSE;
1404     }
1405     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage)];
1406     PackageType *type = (PackageType *) buffer;
1407     GetAccessibleTableRowDescriptionPackage *pkg = (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType));
1408     *type = cGetAccessibleTableRowDescriptionPackage;
1409     pkg->vmID = vmID;
1410     pkg->row = row;
1411     pkg->accessibleContext = accessibleContext;
1412 
1413     // need to call only the HWND/VM that contains this AC
1414     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1415     if (destABWindow != (HWND) 0) {
1416         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1417             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowDescription succeeded");
1418             return pkg->rAccessibleContext;
1419         }
1420     }
1421     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowDescription failed");
1422     return (JOBJECT64)0;
1423 }
1424 
1425 JOBJECT64
1426 WinAccessBridge::getAccessibleTableColumnDescription(long vmID,
1427                                                      JOBJECT64 accessibleContext,
1428                                                      jint column) {
1429 
1430 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1431     PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %p, %d)", vmID, accessibleContext,
1432                      column);
1433 #else // JOBJECT64 is jlong (64 bit)
1434     PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %016I64X, %d)", vmID, accessibleContext,
1435                      column);
1436 #endif
1437 
1438     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1439         return FALSE;
1440     }
1441     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage)];
1442     PackageType *type = (PackageType *) buffer;
1443     GetAccessibleTableColumnDescriptionPackage *pkg =
1444         (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType));
1445     *type = cGetAccessibleTableColumnDescriptionPackage;
1446     pkg->vmID = vmID;
1447     pkg->column = column;
1448     pkg->accessibleContext = accessibleContext;
1449 
1450     // need to call only the HWND/VM that contains this AC
1451     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1452     if (destABWindow != (HWND) 0) {
1453         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1454             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnDescription succeeded");
1455             return pkg->rAccessibleContext;
1456         }
1457     }
1458     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnDescription failed");
1459     return (JOBJECT64)0;
1460 }
1461 
1462 jint
1463 WinAccessBridge::getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable) {
1464 
1465 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1466     PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %p)", vmID, accessibleTable);
1467 #else // JOBJECT64 is jlong (64 bit)
1468     PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %016I64X)", vmID, accessibleTable);
1469 #endif
1470 
1471     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1472         return 0;
1473     }
1474     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage)];
1475     PackageType *type = (PackageType *) buffer;
1476     GetAccessibleTableRowSelectionCountPackage *pkg =
1477         (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType));
1478     *type = cGetAccessibleTableRowSelectionCountPackage;
1479     pkg->vmID = vmID;
1480     pkg->accessibleTable = accessibleTable;
1481 
1482     // need to call only the HWND/VM that contains this AC
1483     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1484     if (destABWindow != (HWND) 0) {
1485         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1486             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowSelectionCount succeeded");
1487             return pkg->rCount;
1488         }
1489     }
1490     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowSelectionCount failed");
1491     return 0;
1492 }
1493 
1494 BOOL
1495 WinAccessBridge::isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row) {
1496 
1497 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1498     PrintDebugString("##### WinAccessBridge::isAccessibleTableRowSelected(%X, %p)", vmID, accessibleTable);
1499 #else // JOBJECT64 is jlong (64 bit)
1500     PrintDebugString("##### WinAccessBridge::isAccessibleTableRowSelected(%X, %016I64X)", vmID, accessibleTable);
1501 #endif
1502 
1503     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1504         return FALSE;
1505     }
1506     char buffer[sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage)];
1507     PackageType *type = (PackageType *) buffer;
1508     IsAccessibleTableRowSelectedPackage *pkg = (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType));
1509     *type = cIsAccessibleTableRowSelectedPackage;
1510     pkg->vmID = vmID;
1511     pkg->accessibleTable = accessibleTable;
1512     pkg->row = row;
1513 
1514     // need to call only the HWND/VM that contains this AC
1515     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1516     if (destABWindow != (HWND) 0) {
1517         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1518             PrintDebugString("  ##### WinAccessBridge::isAccessibleTableRowSelected succeeded");
1519             return pkg->rResult;
1520         }
1521     }
1522     PrintDebugString("  ##### WinAccessBridge::isAccessibleTableRowSelected failed");
1523     return FALSE;
1524 }
1525 
1526 BOOL
1527 WinAccessBridge::getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, jint *selections) {
1528 
1529 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1530     PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelections(%X, %p)", vmID, accessibleTable);
1531 #else // JOBJECT64 is jlong (64 bit)
1532     PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelections(%X, %016I64X)", vmID, accessibleTable);
1533 #endif
1534 
1535     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1536         return FALSE;
1537     }
1538     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage)];
1539     PackageType *type = (PackageType *) buffer;
1540     GetAccessibleTableRowSelectionsPackage *pkg =
1541         (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType));
1542     *type = cGetAccessibleTableRowSelectionsPackage;
1543     pkg->vmID = vmID;
1544     pkg->accessibleTable = accessibleTable;
1545     pkg->count = count;
1546 
1547     // need to call only the HWND/VM that contains this AC
1548     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1549     if (destABWindow != (HWND) 0) {
1550         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1551             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowSelections succeeded");
1552             memcpy(selections, pkg->rSelections, count * sizeof(jint));
1553             return TRUE;
1554         }
1555     }
1556     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowSelections failed");
1557     return FALSE;
1558 }
1559 
1560 
1561 jint
1562 WinAccessBridge::getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable) {
1563 
1564 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1565     PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %p)", vmID,
1566                      accessibleTable);
1567 #else // JOBJECT64 is jlong (64 bit)
1568     PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %016I64X)", vmID,
1569                      accessibleTable);
1570 #endif
1571 
1572     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1573         return FALSE;
1574     }
1575     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage)];
1576     PackageType *type = (PackageType *) buffer;
1577     GetAccessibleTableColumnSelectionCountPackage *pkg =
1578         (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType));
1579     *type = cGetAccessibleTableColumnSelectionCountPackage;
1580     pkg->vmID = vmID;
1581     pkg->accessibleTable = accessibleTable;
1582 
1583     // need to call only the HWND/VM that contains this AC
1584     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1585     if (destABWindow != (HWND) 0) {
1586         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1587             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnSelectionCount succeeded");
1588             return pkg->rCount;
1589         }
1590     }
1591     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnSelectionCount failed");
1592     return 0;
1593 }
1594 
1595 BOOL
1596 WinAccessBridge::isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column) {
1597 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1598     PrintDebugString("##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %p)", vmID, accessibleTable);
1599 #else // JOBJECT64 is jlong (64 bit)
1600     PrintDebugString("##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %016I64X)", vmID, accessibleTable);
1601 #endif
1602 
1603     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1604         return FALSE;
1605     }
1606     char buffer[sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage)];
1607     PackageType *type = (PackageType *) buffer;
1608     IsAccessibleTableColumnSelectedPackage *pkg = (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType));
1609     *type = cIsAccessibleTableColumnSelectedPackage;
1610     pkg->vmID = vmID;
1611     pkg->accessibleTable = accessibleTable;
1612     pkg->column = column;
1613 
1614     // need to call only the HWND/VM that contains this AC
1615     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1616     if (destABWindow != (HWND) 0) {
1617         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1618             PrintDebugString("  ##### WinAccessBridge::isAccessibleTableColumnSelected succeeded");
1619             return pkg->rResult;
1620         }
1621     }
1622     PrintDebugString("  ##### WinAccessBridge::isAccessibleTableColumnSelected failed");
1623     return FALSE;
1624 }
1625 
1626 BOOL
1627 WinAccessBridge::getAccessibleTableColumnSelections(long vmID, JOBJECT64 accessibleTable, jint count,
1628                                                     jint *selections) {
1629 
1630 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1631     PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %p)", vmID, accessibleTable);
1632 #else // JOBJECT64 is jlong (64 bit)
1633     PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %016I64X)", vmID, accessibleTable);
1634 #endif
1635 
1636     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1637         return FALSE;
1638     }
1639     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage)];
1640     PackageType *type = (PackageType *) buffer;
1641     GetAccessibleTableColumnSelectionsPackage *pkg =
1642         (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType));
1643     *type = cGetAccessibleTableColumnSelectionsPackage;
1644     pkg->vmID = vmID;
1645     pkg->count = count;
1646     pkg->accessibleTable = accessibleTable;
1647 
1648     // need to call only the HWND/VM that contains this AC
1649     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1650     if (destABWindow != (HWND) 0) {
1651         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1652             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnSelections succeeded");
1653             memcpy(selections, pkg->rSelections, count * sizeof(jint));
1654             return TRUE;
1655         }
1656     }
1657     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnSelections failed");
1658     return FALSE;
1659 }
1660 
1661 jint
1662 WinAccessBridge::getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index) {
1663 
1664 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1665     PrintDebugString("##### WinAccessBridge::getAccessibleTableRow(%X, %p, index=%d)", vmID,
1666                      accessibleTable, index);
1667 #else // JOBJECT64 is jlong (64 bit)
1668     PrintDebugString("##### WinAccessBridge::getAccessibleTableRow(%X, %016I64X, index=%d)", vmID,
1669                      accessibleTable, index);
1670 #endif
1671 
1672     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1673         return FALSE;
1674     }
1675     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage)];
1676     PackageType *type = (PackageType *) buffer;
1677     GetAccessibleTableRowPackage *pkg =
1678         (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType));
1679     *type = cGetAccessibleTableRowPackage;
1680     pkg->vmID = vmID;
1681     pkg->accessibleTable = accessibleTable;
1682     pkg->index = index;
1683 
1684     // need to call only the HWND/VM that contains this AC
1685     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1686     if (destABWindow != (HWND) 0) {
1687         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1688             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRow succeeded");
1689             return pkg->rRow;
1690         }
1691     }
1692     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRow failed");
1693     return 0;
1694 }
1695 
1696 jint
1697 WinAccessBridge::getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index) {
1698 
1699 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1700     PrintDebugString("##### WinAccessBridge::getAccessibleTableColumn(%X, %p, index=%d)", vmID,
1701                      accessibleTable, index);
1702 #else // JOBJECT64 is jlong (64 bit)
1703     PrintDebugString("##### WinAccessBridge::getAccessibleTableColumn(%X, %016I64X, index=%d)", vmID,
1704                      accessibleTable, index);
1705 #endif
1706 
1707     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1708         return FALSE;
1709     }
1710     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage)];
1711     PackageType *type = (PackageType *) buffer;
1712     GetAccessibleTableColumnPackage *pkg =
1713         (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType));
1714     *type = cGetAccessibleTableColumnPackage;
1715     pkg->vmID = vmID;
1716     pkg->accessibleTable = accessibleTable;
1717     pkg->index = index;
1718 
1719     // need to call only the HWND/VM that contains this AC
1720     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1721     if (destABWindow != (HWND) 0) {
1722         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1723             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumn succeeded");
1724             return pkg->rColumn;
1725         }
1726     }
1727     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumn failed");
1728     return 0;
1729 }
1730 
1731 jint
1732 WinAccessBridge::getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column) {
1733 
1734 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1735     PrintDebugString("##### WinAccessBridge::getAccessibleTableIndex(%X, %p, row=%d, col=%d)", vmID,
1736                      accessibleTable, row, column);
1737 #else // JOBJECT64 is jlong (64 bit)
1738     PrintDebugString("##### WinAccessBridge::getAccessibleTableIndex(%X, %016I64X, row=%d, col=%d)", vmID,
1739                      accessibleTable, row, column);
1740 #endif
1741 
1742     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1743         return FALSE;
1744     }
1745     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage)];
1746     PackageType *type = (PackageType *) buffer;
1747     GetAccessibleTableIndexPackage *pkg =
1748         (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType));
1749     *type = cGetAccessibleTableIndexPackage;
1750     pkg->vmID = vmID;
1751     pkg->accessibleTable = accessibleTable;
1752     pkg->row = row;
1753     pkg->column = column;
1754 
1755     // need to call only the HWND/VM that contains this AC
1756     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1757     if (destABWindow != (HWND) 0) {
1758         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1759             PrintDebugString("  ##### WinAccessBridge::getAccessibleTableIndex succeeded");
1760             return pkg->rIndex;
1761         }
1762     }
1763     PrintDebugString("  ##### WinAccessBridge::getAccessibleTableIndex failed");
1764     return 0;
1765 }
1766 
1767 /********** end AccessibleTable routines ******************************/
1768 
1769 BOOL
1770 WinAccessBridge::getAccessibleRelationSet(long vmID, JOBJECT64 accessibleContext,
1771                                           AccessibleRelationSetInfo *relationSetInfo) {
1772 
1773 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1774     PrintDebugString("##### WinAccessBridge::getAccessibleRelationSet(%X, %p, %X)", vmID,
1775                      accessibleContext, relationSetInfo);
1776 #else // JOBJECT64 is jlong (64 bit)
1777     PrintDebugString("##### WinAccessBridge::getAccessibleRelationSet(%X, %016I64X, %X)", vmID,
1778                      accessibleContext, relationSetInfo);
1779 #endif
1780 
1781     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1782         return FALSE;
1783     }
1784 
1785     char buffer[sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage)];
1786     PackageType *type = (PackageType *) buffer;
1787     GetAccessibleRelationSetPackage *pkg = (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType));
1788     *type = cGetAccessibleRelationSetPackage;
1789     pkg->vmID = vmID;
1790     pkg->accessibleContext = accessibleContext;
1791 
1792     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1793     if (destABWindow != (HWND) 0) {
1794         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1795             PrintDebugString("  ##### pkg->rAccessibleRelationSetInfo.relationCount = %X",
1796                              pkg->rAccessibleRelationSetInfo.relationCount);
1797             memcpy(relationSetInfo, &(pkg->rAccessibleRelationSetInfo), sizeof(AccessibleRelationSetInfo));
1798             PrintDebugString("  ##### WinAccessBridge::getAccessibleRelationSet succeeded");
1799             return TRUE;
1800         }
1801     }
1802     PrintDebugString("  ##### WinAccessBridge::getAccessibleRelationSet failed");
1803     return FALSE;
1804 }
1805 
1806 
1807 /********** AccessibleHypertext routines ***********/
1808 
1809 BOOL
1810 WinAccessBridge::getAccessibleHypertext(long vmID, JOBJECT64 accessibleContext,
1811                                         AccessibleHypertextInfo *hypertextInfo) {
1812 
1813 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1814     PrintDebugString("##### WinAccessBridge::getAccessibleHypertext(%X, %p, %X)", vmID,
1815                      accessibleContext, hypertextInfo);
1816 #else // JOBJECT64 is jlong (64 bit)
1817     PrintDebugString("##### WinAccessBridge::getAccessibleHypertext(%X, %016I64X, %X)", vmID,
1818                      accessibleContext, hypertextInfo);
1819 #endif
1820 
1821     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1822         return FALSE;
1823     }
1824 
1825     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage)];
1826     PackageType *type = (PackageType *) buffer;
1827     GetAccessibleHypertextPackage *pkg = (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType));
1828     *type = cGetAccessibleHypertextPackage;
1829     pkg->vmID = vmID;
1830     pkg->accessibleContext = accessibleContext;
1831 
1832     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1833     if (destABWindow != (HWND) 0) {
1834         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1835             memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo));
1836 
1837             PrintDebugString("  ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);
1838             PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertext succeeded");
1839 
1840             return TRUE;
1841         }
1842     }
1843     PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertext failed");
1844     return FALSE;
1845 }
1846 
1847 
1848 BOOL
1849 WinAccessBridge::activateAccessibleHyperlink(long vmID, JOBJECT64 accessibleContext,
1850                                              JOBJECT64 accessibleHyperlink) {
1851 
1852 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1853     PrintDebugString("WinAccessBridge::activateAccessibleHyperlink(%p %p)", accessibleContext,
1854                      accessibleHyperlink);
1855 #else // JOBJECT64 is jlong (64 bit)
1856     PrintDebugString("WinAccessBridge::activateAccessibleHyperlink(%016I64X %016I64X)", accessibleContext,
1857                      accessibleHyperlink);
1858 #endif
1859 
1860     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1861         return FALSE;
1862     }
1863 
1864     char buffer[sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage)];
1865     PackageType *type = (PackageType *) buffer;
1866     ActivateAccessibleHyperlinkPackage *pkg = (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
1867     *type = cActivateAccessibleHyperlinkPackage;
1868     pkg->vmID = vmID;
1869     pkg->accessibleContext = accessibleContext;
1870     pkg->accessibleHyperlink = accessibleHyperlink;
1871 
1872     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
1873     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1874         return pkg->rResult;
1875     }
1876     PrintDebugString("  WinAccessBridge::activateAccessibleHyperlink returning FALSE (sendMemoryPackage failed)");
1877     return FALSE;
1878 }
1879 
1880 /*
1881  * Returns the number of hyperlinks in a component
1882  * Maps to AccessibleHypertext.getLinkCount.
1883  * Returns -1 on error.
1884  */
1885 jint
1886 WinAccessBridge::getAccessibleHyperlinkCount(const long vmID,
1887                                              const AccessibleContext accessibleContext) {
1888 
1889 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1890     PrintDebugString("##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %p)",
1891                      vmID, accessibleContext);
1892 #else // JOBJECT64 is jlong (64 bit)
1893     PrintDebugString("##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %016I64X)",
1894                      vmID, accessibleContext);
1895 #endif
1896 
1897     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1898         return FALSE;
1899     }
1900 
1901     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage)];
1902     PackageType *type = (PackageType *) buffer;
1903     GetAccessibleHyperlinkCountPackage *pkg = (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType));
1904     *type = cGetAccessibleHyperlinkCountPackage;
1905     pkg->vmID = vmID;
1906     pkg->accessibleContext = accessibleContext;
1907 
1908     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1909     if (destABWindow != (HWND) 0) {
1910         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1911             PrintDebugString("  ##### hypetext link count = %d", pkg->rLinkCount);
1912             PrintDebugString("  ##### WinAccessBridge::getAccessibleHyperlinkCount succeeded");
1913             return pkg->rLinkCount;
1914         }
1915     }
1916     PrintDebugString("  ##### WinAccessBridge::getAccessibleHyperlinkCount failed");
1917     return -1;
1918 }
1919 
1920 /*
1921  * This method is used to iterate through the hyperlinks in a component.  It
1922  * returns hypertext information for a component starting at hyperlink index
1923  * nStartIndex.  No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will
1924  * be returned for each call to this method.
1925  * returns FALSE on error.
1926  */
1927 BOOL
1928 WinAccessBridge::getAccessibleHypertextExt(const long vmID,
1929                                            const AccessibleContext accessibleContext,
1930                                            const jint startIndex,
1931                                            /* OUT */ AccessibleHypertextInfo *hypertextInfo) {
1932 
1933 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1934     PrintDebugString("##### WinAccessBridge::getAccessibleHypertextExt(%X, %p %p)", vmID,
1935                      accessibleContext, hypertextInfo);
1936 #else // JOBJECT64 is jlong (64 bit)
1937     PrintDebugString("##### WinAccessBridge::getAccessibleHypertextExt(%X, %016I64X %p)", vmID,
1938                      accessibleContext, hypertextInfo);
1939 #endif
1940 
1941     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1942         return FALSE;
1943     }
1944 
1945     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage)];
1946     PackageType *type = (PackageType *) buffer;
1947     GetAccessibleHypertextExtPackage *pkg = (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType));
1948     *type = cGetAccessibleHypertextExtPackage;
1949     pkg->vmID = vmID;
1950     pkg->accessibleContext = accessibleContext;
1951     pkg->startIndex = startIndex;
1952 
1953     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1954     if (destABWindow != (HWND) 0) {
1955         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1956             PrintDebugString("  ##### pkg->rSuccess = %d", pkg->rSuccess);
1957 
1958             memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo));
1959             if (pkg->rSuccess == TRUE) {
1960                 PrintDebugString("  ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);
1961                 PrintDebugString("  ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);
1962             } else {
1963                 PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertextExt failed");
1964             }
1965             return pkg->rSuccess;;
1966         }
1967     }
1968     PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertextExt failed");
1969     return FALSE;
1970 }
1971 
1972 
1973 /*
1974  * Returns the index into an array of hyperlinks that is associated with
1975  * a character index in document;
1976  * Maps to AccessibleHypertext.getLinkIndex.
1977  * Returns -1 on error.
1978  */
1979 jint
1980 WinAccessBridge::getAccessibleHypertextLinkIndex(const long vmID,
1981                                                  const AccessibleHyperlink hypertext,
1982                                                  const jint charIndex) {
1983 
1984 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1985     PrintDebugString("##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %p)",
1986                      vmID, hypertext);
1987 #else // JOBJECT64 is jlong (64 bit)
1988     PrintDebugString("##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %016I64X)",
1989                      vmID, hypertext);
1990 #endif
1991 
1992     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1993         return FALSE;
1994     }
1995 
1996     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage)];
1997     PackageType *type = (PackageType *) buffer;
1998     GetAccessibleHypertextLinkIndexPackage *pkg = (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType));
1999     *type = cGetAccessibleHypertextLinkIndexPackage;
2000     pkg->vmID = vmID;
2001     pkg->hypertext = hypertext;
2002     pkg->charIndex = charIndex;
2003 
2004     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2005     if (destABWindow != (HWND) 0) {
2006         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2007             PrintDebugString("  ##### hypetext link index = %d", pkg->rLinkIndex);
2008             PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertextLinkIndex  succeeded");
2009             return pkg->rLinkIndex;
2010         }
2011     }
2012     PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertextLinkIndex  failed");
2013     return -1;
2014 }
2015 
2016 /*
2017  * Returns the nth hyperlink in a document.
2018  * Maps to AccessibleHypertext.getLink.
2019  * Returns -1 on error
2020  */
2021 BOOL
2022 WinAccessBridge::getAccessibleHyperlink(const long vmID,
2023                                         const AccessibleHyperlink hypertext,
2024                                         const jint linkIndex,
2025                                         /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) {
2026 
2027 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2028     PrintDebugString("##### WinAccessBridge::getAccessibleHyperlink(%X, %p, %p)", vmID,
2029                      hypertext, hyperlinkInfo);
2030 #else // JOBJECT64 is jlong (64 bit)
2031     PrintDebugString("##### WinAccessBridge::getAccessibleHyperlink(%X, %016I64X, %p)", vmID,
2032                      hypertext, hyperlinkInfo);
2033 #endif
2034 
2035     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2036         return FALSE;
2037     }
2038 
2039     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage)];
2040     PackageType *type = (PackageType *) buffer;
2041     GetAccessibleHyperlinkPackage *pkg = (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
2042     *type = cGetAccessibleHyperlinkPackage;
2043     pkg->vmID = vmID;
2044     pkg->hypertext = hypertext;
2045     pkg->linkIndex = linkIndex;
2046 
2047     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2048     if (destABWindow != (HWND) 0) {
2049         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2050             memcpy(hyperlinkInfo, &(pkg->rAccessibleHyperlinkInfo),
2051                    sizeof(AccessibleHyperlinkInfo));
2052             PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertext succeeded");
2053             return TRUE;
2054         }
2055     }
2056     PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertext failed");
2057     return FALSE;
2058 }
2059 
2060 
2061 /********** AccessibleKeyBinding routines ***********/
2062 
2063 BOOL
2064 WinAccessBridge::getAccessibleKeyBindings(long vmID, JOBJECT64 accessibleContext,
2065                                           AccessibleKeyBindings *keyBindings) {
2066 
2067 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2068     PrintDebugString("##### WinAccessBridge::getAccessibleKeyBindings(%X, %p, %p)", vmID,
2069                      accessibleContext, keyBindings);
2070 #else // JOBJECT64 is jlong (64 bit)
2071     PrintDebugString("##### WinAccessBridge::getAccessibleKeyBindings(%X, %016I64X, %p)", vmID,
2072                      accessibleContext, keyBindings);
2073 #endif
2074 
2075     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2076         return FALSE;
2077     }
2078 
2079     char buffer[sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage)];
2080     PackageType *type = (PackageType *) buffer;
2081     GetAccessibleKeyBindingsPackage *pkg = (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType));
2082     *type = cGetAccessibleKeyBindingsPackage;
2083     pkg->vmID = vmID;
2084     pkg->accessibleContext = accessibleContext;
2085 
2086     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2087     if (destABWindow != (HWND) 0) {
2088         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2089             memcpy(keyBindings, &(pkg->rAccessibleKeyBindings), sizeof(AccessibleKeyBindings));
2090 
2091             PrintDebugString("  ##### keyBindings.keyBindingsCount = %d", keyBindings->keyBindingsCount);
2092             for (int i = 0; i < keyBindings->keyBindingsCount; ++i) {
2093                 PrintDebugString("  Key Binding # %d", i+1);
2094                 PrintDebugString("    Modifiers: 0x%x", keyBindings->keyBindingInfo[i].modifiers);
2095                 PrintDebugString("    Character (hex):  0x%x", keyBindings->keyBindingInfo[i].character);
2096                 PrintDebugString("    Character (wide char):  %lc", keyBindings->keyBindingInfo[i].character);

2097             }
2098             PrintDebugString("  ##### WinAccessBridge::getAccessibleKeyBindings succeeded");
2099 
2100             return TRUE;
2101         }
2102     }
2103     PrintDebugString("  ##### WinAccessBridge::getAccessibleKeyBindings failed");
2104     return FALSE;
2105 }
2106 
2107 BOOL
2108 WinAccessBridge::getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, AccessibleIcons *icons) {
2109 
2110 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2111     PrintDebugString("##### WinAccessBridge::getAccessibleIcons(%X, %p, %p)", vmID,
2112                      accessibleContext, icons);
2113 #else // JOBJECT64 is jlong (64 bit)
2114     PrintDebugString("##### WinAccessBridge::getAccessibleIcons(%X, %016I64X, %p)", vmID,
2115                      accessibleContext, icons);
2116 #endif
2117 
2118     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2119         return FALSE;
2120     }
2121 
2122     char buffer[sizeof(PackageType) + sizeof(GetAccessibleIconsPackage)];
2123     PackageType *type = (PackageType *) buffer;
2124     GetAccessibleIconsPackage *pkg = (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType));
2125     *type = cGetAccessibleIconsPackage;
2126     pkg->vmID = vmID;
2127     pkg->accessibleContext = accessibleContext;
2128 
2129     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2130     if (destABWindow != (HWND) 0) {
2131         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2132             memcpy(icons, &(pkg->rAccessibleIcons), sizeof(AccessibleIcons));
2133 
2134             PrintDebugString("  ##### icons.iconsCount = %d", icons->iconsCount);
2135             PrintDebugString("  ##### WinAccessBridge::getAccessibleIcons succeeded");
2136 
2137             return TRUE;
2138         }
2139     }
2140     PrintDebugString("  ##### WinAccessBridge::getAccessibleIcons failed");
2141     return FALSE;
2142 }
2143 
2144 BOOL
2145 WinAccessBridge::getAccessibleActions(long vmID, JOBJECT64 accessibleContext, AccessibleActions *actions) {
2146 
2147 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2148     PrintDebugString("##### WinAccessBridge::getAccessibleActions(%X, %p, %p)", vmID,
2149                      accessibleContext, actions);
2150 #else // JOBJECT64 is jlong (64 bit)
2151     PrintDebugString("##### WinAccessBridge::getAccessibleActions(%X, %016I64X, %p)", vmID,
2152                      accessibleContext, actions);
2153 #endif
2154 
2155     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2156         return FALSE;
2157     }
2158 
2159     char buffer[sizeof(PackageType) + sizeof(GetAccessibleActionsPackage)];
2160     PackageType *type = (PackageType *) buffer;
2161     GetAccessibleActionsPackage *pkg = (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType));
2162     *type = cGetAccessibleActionsPackage;
2163     pkg->vmID = vmID;
2164     pkg->accessibleContext = accessibleContext;
2165 
2166     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2167     if (destABWindow != (HWND) 0) {
2168         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2169             memcpy(actions, &(pkg->rAccessibleActions), sizeof(AccessibleActions));
2170 
2171             PrintDebugString("  ##### actions.actionsCount = %d", actions->actionsCount);
2172             PrintDebugString("  ##### WinAccessBridge::getAccessibleActions succeeded");
2173 
2174             return TRUE;
2175         }
2176     }
2177     PrintDebugString("  ##### WinAccessBridge::getAccessibleActions failed");
2178     return FALSE;
2179 }
2180 
2181 BOOL
2182 WinAccessBridge::doAccessibleActions(long vmID, JOBJECT64 accessibleContext,
2183                                      AccessibleActionsToDo *actionsToDo, jint *failure) {
2184 
2185 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2186     PrintDebugString("WinAccessBridge::doAccessibleActions(%p #actions %d %ls)", accessibleContext,
2187                      actionsToDo->actionsCount,
2188                      actionsToDo->actions[0].name);
2189 #else // JOBJECT64 is jlong (64 bit)
2190     PrintDebugString("WinAccessBridge::doAccessibleActions(%016I64X #actions %d %ls)", accessibleContext,
2191                      actionsToDo->actionsCount,
2192                      actionsToDo->actions[0].name);
2193 #endif
2194 
2195     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2196         return FALSE;
2197     }
2198     char buffer[sizeof(PackageType) + sizeof(DoAccessibleActionsPackage)];
2199     PackageType *type = (PackageType *) buffer;
2200     DoAccessibleActionsPackage *pkg = (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType));
2201     *type = cDoAccessibleActionsPackage;
2202     pkg->vmID = vmID;
2203     pkg->accessibleContext = accessibleContext;
2204     memcpy((void *)(&(pkg->actionsToDo)), (void *)actionsToDo, sizeof(AccessibleActionsToDo));
2205     pkg->failure = -1;
2206 
2207     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
2208     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2209         *failure = pkg->failure;
2210         return pkg->rResult;
2211     }
2212     PrintDebugString("  WinAccessBridge::doAccessibleActions returning FALSE (sendMemoryPackage failed)");
2213     return FALSE;
2214 }
2215 
2216 /* ====== Utility methods ====== */
2217 
2218 /**
2219  * Sets a text field to the specified string. Returns whether successful.
2220  */
2221 BOOL
2222 WinAccessBridge::setTextContents (const long vmID, const AccessibleContext accessibleContext,
2223                                   const wchar_t *text) {
2224 
2225     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2226         return FALSE;
2227     }
2228     char buffer[sizeof(PackageType) + sizeof(SetTextContentsPackage)];
2229     PackageType *type = (PackageType *) buffer;
2230     SetTextContentsPackage *pkg = (SetTextContentsPackage *) (buffer + sizeof(PackageType));
2231     *type = cSetTextContentsPackage;
2232     pkg->vmID = vmID;
2233     pkg->accessibleContext = accessibleContext;
2234     wcsncpy(pkg->text, text, sizeof(pkg->text)/sizeof(wchar_t)); // wide character copy
2235 
2236 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2237     PrintDebugString("WinAccessBridge::setTextContents(%X, %016I64X %ls)", vmID, accessibleContext, text);
2238 #else // JOBJECT64 is jlong (64 bit)
2239     PrintDebugString("WinAccessBridge::setTextContents(%X, %p %ls)", vmID, accessibleContext, text);
2240 #endif
2241     // need to call only the HWND/VM that contains this AC
2242     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2243     if (destABWindow != (HWND) 0) {
2244         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2245             return pkg->rResult;
2246         }
2247     }
2248     return FALSE;
2249 }
2250 
2251 /**
2252  * Returns the Accessible Context of a Page Tab object that is the
2253  * ancestor of a given object.  If the object is a Page Tab object
2254  * or a Page Tab ancestor object was found, returns the object
2255  * AccessibleContext.
2256  * If there is no ancestor object that has an Accessible Role of Page Tab,
2257  * returns (AccessibleContext)0.
2258  */
2259 AccessibleContext
2260 WinAccessBridge::getParentWithRole (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) {
2261 
2262     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2263         return (JOBJECT64)0;
2264     }
2265     char buffer[sizeof(PackageType) + sizeof(GetParentWithRolePackage)];
2266     PackageType *type = (PackageType *) buffer;
2267     GetParentWithRolePackage *pkg = (GetParentWithRolePackage *) (buffer + sizeof(PackageType));
2268     *type = cGetParentWithRolePackage;
2269     pkg->vmID = vmID;
2270     pkg->accessibleContext = accessibleContext;
2271     memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role));
2272 
2273 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2274     PrintDebugString("WinAccessBridge::getParentWithRole(%X, %p)", vmID, accessibleContext);
2275 #else // JOBJECT64 is jlong (64 bit)
2276     PrintDebugString("WinAccessBridge::getParentWithRole(%X, %016I64X)", vmID, accessibleContext);
2277 #endif
2278     PrintDebugString("  pkg->vmID: %X", pkg->vmID);
2279     PrintDebugString("  pkg->accessibleContext: %p", pkg->accessibleContext);
2280     PrintDebugString("  pkg->role: %ls", pkg->role);

2281     // need to call only the HWND/VM that contains this AC
2282     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2283     if (destABWindow != (HWND) 0) {
2284         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2285             PrintDebugString("  pkg->rAccessibleContext: %p", pkg->rAccessibleContext);
2286             return pkg->rAccessibleContext;
2287         }
2288     }
2289     return (JOBJECT64) 0;
2290 }
2291 
2292 
2293 /**
2294  * Returns the Accessible Context for the top level object in
2295  * a Java Window.  This is same Accessible Context that is obtained
2296  * from GetAccessibleContextFromHWND for that window.  Returns
2297  * (AccessibleContext)0 on error.
2298  */
2299 AccessibleContext
2300 WinAccessBridge::getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) {
2301 
2302     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2303         return (JOBJECT64)0;
2304     }
2305     char buffer[sizeof(PackageType) + sizeof(GetTopLevelObjectPackage)];
2306     PackageType *type = (PackageType *) buffer;
2307     GetTopLevelObjectPackage *pkg = (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType));
2308     *type = cGetTopLevelObjectPackage;
2309     pkg->vmID = vmID;
2310     pkg->accessibleContext = accessibleContext;
2311 
2312 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2313     PrintDebugString("WinAccessBridge::getTopLevelObject(%X, %p)", vmID, accessibleContext);
2314 #else // JOBJECT64 is jlong (64 bit)
2315     PrintDebugString("WinAccessBridge::getTopLevelObject(%X, %016I64X)", vmID, accessibleContext);
2316 #endif
2317     // need to call only the HWND/VM that contains this AC
2318     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2319     if (destABWindow != (HWND) 0) {
2320         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2321             return pkg->rAccessibleContext;
2322         }
2323     }
2324     return (JOBJECT64) 0;
2325 }
2326 
2327 /**
2328  * If there is an Ancestor object that has an Accessible Role of
2329  * Internal Frame, returns the Accessible Context of the Internal
2330  * Frame object.  Otherwise, returns the top level object for that
2331  * Java Window.  Returns (AccessibleContext)0 on error.
2332  */
2333 AccessibleContext
2334 WinAccessBridge::getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) {
2335 
2336     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2337         return (JOBJECT64)0;
2338     }
2339     char buffer[sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage)];
2340     PackageType *type = (PackageType *) buffer;
2341     GetParentWithRoleElseRootPackage *pkg = (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType));
2342     *type = cGetParentWithRoleElseRootPackage;
2343     pkg->vmID = vmID;
2344     pkg->accessibleContext = accessibleContext;
2345     memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role));
2346 
2347 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2348     PrintDebugString("WinAccessBridge::getParentWithRoleElseRoot(%X, %p)", vmID, accessibleContext);
2349 #else // JOBJECT64 is jlong (64 bit)
2350     PrintDebugString("WinAccessBridge::getParentWithRoleElseRoot(%X, %016I64X)", vmID, accessibleContext);
2351 #endif
2352     // need to call only the HWND/VM that contains this AC
2353     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2354     if (destABWindow != (HWND) 0) {
2355         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2356             return pkg->rAccessibleContext;
2357         }
2358     }
2359     return (JOBJECT64) 0;
2360 }
2361 
2362 /**
2363  * Returns how deep in the object hierarchy a given object is.
2364  * The top most object in the object hierarchy has an object depth of 0.
2365  * Returns -1 on error.
2366  */
2367 int
2368 WinAccessBridge::getObjectDepth (const long vmID, const AccessibleContext accessibleContext) {
2369 
2370     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2371         return -1;
2372     }
2373     char buffer[sizeof(PackageType) + sizeof(GetObjectDepthPackage)];
2374     PackageType *type = (PackageType *) buffer;
2375     GetObjectDepthPackage *pkg = (GetObjectDepthPackage *) (buffer + sizeof(PackageType));
2376     *type = cGetObjectDepthPackage;
2377     pkg->vmID = vmID;
2378     pkg->accessibleContext = accessibleContext;
2379 
2380 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2381     PrintDebugString("WinAccessBridge::getObjectDepth(%X, %p)", vmID, accessibleContext);
2382 #else // JOBJECT64 is jlong (64 bit)
2383     PrintDebugString("WinAccessBridge::getObjectDepth(%X, %016I64X)", vmID, accessibleContext);
2384 #endif
2385     // need to call only the HWND/VM that contains this AC
2386     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2387     if (destABWindow != (HWND) 0) {
2388         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2389             return pkg->rResult;
2390         }
2391     }
2392     return -1;
2393 }
2394 
2395 /**
2396  * Returns the Accessible Context of the currently ActiveDescendent of an object.
2397  * Returns (AccessibleContext)0 on error.
2398  */
2399 AccessibleContext
2400 WinAccessBridge::getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) {
2401 
2402     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2403         return (JOBJECT64)0;
2404     }
2405     char buffer[sizeof(PackageType) + sizeof(GetActiveDescendentPackage)];
2406     PackageType *type = (PackageType *) buffer;
2407     GetActiveDescendentPackage *pkg = (GetActiveDescendentPackage *) (buffer + sizeof(PackageType));
2408     *type = cGetActiveDescendentPackage;
2409     pkg->vmID = vmID;
2410     pkg->accessibleContext = accessibleContext;
2411 
2412 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2413     PrintDebugString("WinAccessBridge::getActiveDescendent(%X, %p)", vmID, accessibleContext);
2414 #else // JOBJECT64 is jlong (64 bit)
2415     PrintDebugString("WinAccessBridge::getActiveDescendent(%X, %016I64X)", vmID, accessibleContext);
2416 #endif
2417     // need to call only the HWND/VM that contains this AC
2418     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2419     if (destABWindow != (HWND) 0) {
2420         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2421             return pkg->rAccessibleContext;
2422         }
2423     }
2424     return (JOBJECT64) 0;
2425 }
2426 
2427 /**
2428  * Additional methods for Teton
2429  */
2430 
2431 /**
2432  * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns
2433  * whether successful.
2434  *
2435  * Bug ID 4916682 - Implement JAWS AccessibleName policy
2436  */
2437 BOOL
2438 WinAccessBridge::getVirtualAccessibleName(long vmID, AccessibleContext accessibleContext,
2439                                           wchar_t *name, int len) {
2440 
2441     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2442         return FALSE;
2443     }
2444     char buffer[sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage)];
2445     PackageType *type = (PackageType *) buffer;
2446     GetVirtualAccessibleNamePackage *pkg = (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType));
2447     *type = cGetVirtualAccessibleNamePackage;
2448     pkg->vmID = vmID;
2449     pkg->accessibleContext = accessibleContext;
2450     size_t max = (len > sizeof(pkg->rName)) ? sizeof(pkg->rName) : len;
2451     pkg->len = (int)max;
2452 
2453 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2454     PrintDebugString("WinAccessBridge::getVirtualAccessibleName(%X, %p)", vmID, accessibleContext);
2455 #else // JOBJECT64 is jlong (64 bit)
2456     PrintDebugString("WinAccessBridge::getVirtualAccessibleName(%X, %016I64X)", vmID, accessibleContext);
2457 #endif
2458     // need to call only the HWND/VM that contains this AC
2459     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2460     if (destABWindow != (HWND) 0) {
2461         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2462             wcsncpy(name, pkg->rName, max);
2463             PrintDebugString("    WinAccessBridge::getVirtualAccessibleName: Virtual name = %ls", name);
2464             return TRUE;
2465         }
2466     }
2467     return FALSE;
2468 }
2469 
2470 /**
2471  * Request focus for a component. Returns whether successful;
2472  *
2473  * Bug ID 4944757 - requestFocus method needed
2474  */
2475 BOOL
2476 WinAccessBridge::requestFocus(long vmID, AccessibleContext accessibleContext) {
2477 
2478     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2479         return FALSE;
2480     }
2481     char buffer[sizeof(PackageType) + sizeof(RequestFocusPackage)];
2482     PackageType *type = (PackageType *) buffer;
2483     RequestFocusPackage *pkg = (RequestFocusPackage *) (buffer + sizeof(PackageType));
2484     *type = cRequestFocusPackage;
2485     pkg->vmID = vmID;
2486     pkg->accessibleContext = accessibleContext;
2487 
2488 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2489     PrintDebugString("WinAccessBridge::requestFocus(%X, %p)", vmID, accessibleContext);
2490 #else // JOBJECT64 is jlong (64 bit)
2491     PrintDebugString("WinAccessBridge::requestFocus(%X, %016I64X)", vmID, accessibleContext);
2492 #endif
2493     // need to call only the HWND/VM that contains this AC
2494     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2495     if (destABWindow != (HWND) 0) {
2496         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2497             return TRUE;
2498         }
2499     }
2500     return FALSE;
2501 }
2502 
2503 /**
2504  * Selects text between two indices.  Selection includes the text at the start index
2505  * and the text at the end index. Returns whether successful;
2506  *
2507  * Bug ID 4944758 - selectTextRange method needed
2508  */
2509 BOOL
2510 WinAccessBridge::selectTextRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex) {
2511     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2512         return FALSE;
2513     }
2514     char buffer[sizeof(PackageType) + sizeof(SelectTextRangePackage)];
2515     PackageType *type = (PackageType *) buffer;
2516     SelectTextRangePackage *pkg = (SelectTextRangePackage *) (buffer + sizeof(PackageType));
2517     *type = cSelectTextRangePackage;
2518     pkg->vmID = vmID;
2519     pkg->accessibleContext = accessibleContext;
2520     pkg->startIndex = startIndex;
2521     pkg->endIndex = endIndex;
2522 
2523 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2524     PrintDebugString("    WinAccessBridge::selectTextRange(%X, %p %d %d)", vmID, accessibleContext,
2525                      startIndex, endIndex);
2526 #else // JOBJECT64 is jlong (64 bit)
2527     PrintDebugString("    WinAccessBridge::selectTextRange(%X, %016I64X %d %d)", vmID, accessibleContext,
2528                      startIndex, endIndex);
2529 #endif
2530     // need to call only the HWND/VM that contains this AC
2531     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2532     if (destABWindow != (HWND) 0) {
2533         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2534             return TRUE;
2535         }
2536     }
2537     return FALSE;
2538 }
2539 
2540 /**
2541  * Get text attributes between two indices.  The attribute list includes the text at the
2542  * start index and the text at the end index. Returns whether successful;
2543  *
2544  * Bug ID 4944761 - getTextAttributes between two indices method needed
2545  */
2546 BOOL
2547 WinAccessBridge::getTextAttributesInRange(long vmID, AccessibleContext accessibleContext,
2548                                           int startIndex, int endIndex,
2549                                           AccessibleTextAttributesInfo *attributes, short *len) {
2550 
2551     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2552         return FALSE;
2553     }
2554     char buffer[sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage)];
2555     PackageType *type = (PackageType *) buffer;
2556     GetTextAttributesInRangePackage *pkg = (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType));
2557     *type = cGetTextAttributesInRangePackage;
2558     pkg->vmID = vmID;
2559     pkg->accessibleContext = accessibleContext;
2560     pkg->startIndex = startIndex;
2561     pkg->endIndex = endIndex;
2562     memcpy(&(pkg->attributes), attributes, sizeof(AccessibleTextAttributesInfo));
2563 
2564 
2565 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2566     PrintDebugString("    WinAccessBridge::getTextAttributesInRange(%X, %p %d %d)", vmID, accessibleContext,
2567                      startIndex, endIndex);
2568 #else // JOBJECT64 is jlong (64 bit)
2569     PrintDebugString("    WinAccessBridge::getTextAttributesInRange(%X, %016I64X %d %d)", vmID, accessibleContext,
2570                      startIndex, endIndex);
2571 #endif
2572     // need to call only the HWND/VM that contains this AC
2573     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2574     if (destABWindow != (HWND) 0) {
2575         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2576             *attributes = pkg->attributes;
2577             *len = pkg->rLength;
2578             return TRUE;
2579         }
2580     }
2581     return FALSE;
2582 }
2583 
2584 /**
2585  * Gets the number of visible children of a component. Returns -1 on error.
2586  *
2587  * Bug ID 4944762- getVisibleChildren for list-like components needed
2588  */
2589 int
2590 WinAccessBridge::getVisibleChildrenCount(long vmID, AccessibleContext accessibleContext) {
2591 
2592     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2593         return -1;
2594     }
2595     char buffer[sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage)];
2596     PackageType *type = (PackageType *) buffer;
2597     GetVisibleChildrenCountPackage *pkg = (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType));
2598     *type = cGetVisibleChildrenCountPackage;
2599     pkg->vmID = vmID;
2600     pkg->accessibleContext = accessibleContext;
2601 
2602 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2603     PrintDebugString("WinAccessBridge::getVisibleChildrenCount(%X, %p)", vmID, accessibleContext);
2604 #else // JOBJECT64 is jlong (64 bit)
2605     PrintDebugString("WinAccessBridge::getVisibleChildrenCount(%X, %016I64X)", vmID, accessibleContext);
2606 #endif
2607     // need to call only the HWND/VM that contains this AC
2608     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2609     if (destABWindow != (HWND) 0) {
2610         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2611             return pkg->rChildrenCount;
2612         }
2613     }
2614     return -1;
2615 }
2616 
2617 /**
2618  * Gets the visible children of an AccessibleContext. Returns whether successful;
2619  *
2620  * Bug ID 4944762- getVisibleChildren for list-like components needed
2621  */
2622 BOOL
2623 WinAccessBridge::getVisibleChildren(long vmID, AccessibleContext accessibleContext, int startIndex,
2624                                     VisibleChildrenInfo *visibleChildrenInfo) {
2625 
2626     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2627         return FALSE;
2628     }
2629     char buffer[sizeof(PackageType) + sizeof(GetVisibleChildrenPackage)];
2630     PackageType *type = (PackageType *) buffer;
2631     GetVisibleChildrenPackage *pkg = (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType));
2632     *type = cGetVisibleChildrenPackage;
2633     pkg->vmID = vmID;
2634     pkg->accessibleContext = accessibleContext;
2635     pkg->startIndex = startIndex;
2636 
2637 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2638     PrintDebugString("WinAccessBridge::getVisibleChildren(%X, %p)", vmID, accessibleContext);
2639 #else // JOBJECT64 is jlong (64 bit)
2640     PrintDebugString("WinAccessBridge::getVisibleChildren(%X, %016I64X)", vmID, accessibleContext);
2641 #endif
2642     // need to call only the HWND/VM that contains this AC
2643     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2644     if (destABWindow != (HWND) 0) {
2645         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2646             memcpy(visibleChildrenInfo, &(pkg->rVisibleChildrenInfo), sizeof(pkg->rVisibleChildrenInfo));
2647             return pkg->rSuccess;
2648         }
2649     }
2650     return FALSE;
2651 }
2652 
2653 /**
2654  * Set the caret to a text position. Returns whether successful;
2655  *
2656  * Bug ID 4944770 - setCaretPosition method needed
2657  */
2658 BOOL
2659 WinAccessBridge::setCaretPosition(long vmID, AccessibleContext accessibleContext, int position) {
2660 
2661     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2662         return FALSE;
2663     }
2664     char buffer[sizeof(PackageType) + sizeof(SetCaretPositionPackage)];
2665     PackageType *type = (PackageType *) buffer;
2666     SetCaretPositionPackage *pkg = (SetCaretPositionPackage *) (buffer + sizeof(PackageType));
2667     *type = cSetCaretPositionPackage;
2668     pkg->vmID = vmID;
2669     pkg->accessibleContext = accessibleContext;
2670     pkg->position = position;
2671 
2672 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2673     PrintDebugString("WinAccessBridge::setCaretPosition(%X, %p %ls)", vmID, accessibleContext);
2674 #else // JOBJECT64 is jlong (64 bit)
2675     PrintDebugString("WinAccessBridge::setCaretPosition(%X, %016I64X %ls)", vmID, accessibleContext);
2676 #endif
2677     // need to call only the HWND/VM that contains this AC
2678     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2679     if (destABWindow != (HWND) 0) {
2680         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2681             return TRUE;
2682         }
2683     }
2684     return FALSE;
2685 }
2686 
2687 
2688 /********** AccessibleText routines ***********************************/
2689 
2690 /**
2691  * getAccessibleTextInfo - fills a struct with a bunch of information
2692  * contained in the Java Accessibility AccessibleText API
2693  *
2694  *
2695  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2696  */
2697 BOOL
2698 WinAccessBridge::getAccessibleTextInfo(long vmID,
2699                                        JOBJECT64 AccessibleContext,
2700                                        AccessibleTextInfo *textInfo,
2701                                        jint x, jint y) {
2702     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2703         return FALSE;
2704     }
2705     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage)];
2706     PackageType *type = (PackageType *) buffer;
2707     GetAccessibleTextInfoPackage *pkg = (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType));
2708     *type = cGetAccessibleTextInfoPackage;
2709     pkg->vmID = vmID;
2710     pkg->AccessibleContext = AccessibleContext;
2711     pkg->x = x;
2712     pkg->y = y;
2713 
2714 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2715     PrintDebugString("WinAccessBridge::getAccessibleTextInfo(%X, %p, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y);
2716 #else // JOBJECT64 is jlong (64 bit)
2717     PrintDebugString("WinAccessBridge::getAccessibleTextInfo(%X, %016I64X, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y);
2718 #endif
2719     // need to call only the HWND/VM that contains this AC
2720     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2721     if (destABWindow != (HWND) 0) {
2722         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2723             memcpy(textInfo, &(pkg->rTextInfo), sizeof(AccessibleTextInfo));
2724             if (pkg->rTextInfo.charCount != -1) {
2725                 PrintDebugString("  charCount: %d", textInfo->charCount);
2726                 PrintDebugString("  caretIndex: %d", textInfo->caretIndex);
2727                 PrintDebugString("  indexAtPoint: %d", textInfo->indexAtPoint);

2728                 return TRUE;
2729             }
2730         }
2731     }
2732 
2733     return FALSE;
2734 }
2735 
2736 /**
2737  * getAccessibleTextItems - fills a struct with letter, word, and sentence info
2738  * of the AccessibleText interface at a given index
2739  *
2740  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2741  */
2742 BOOL
2743 WinAccessBridge::getAccessibleTextItems(long vmID,
2744                                         JOBJECT64 AccessibleContext,
2745                                         AccessibleTextItemsInfo *textItems,
2746                                         jint index) {
2747     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2748         return FALSE;
2749     }
2750     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage)];
2751     PackageType *type = (PackageType *) buffer;
2752     GetAccessibleTextItemsPackage *pkg = (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType));
2753     *type = cGetAccessibleTextItemsPackage;
2754     pkg->vmID = vmID;
2755     pkg->AccessibleContext = AccessibleContext;
2756     pkg->index = index;
2757     // zero things out, in case the call fails
2758     pkg->rTextItemsInfo.letter = '\0';
2759     pkg->rTextItemsInfo.word[0] = '\0';
2760     pkg->rTextItemsInfo.sentence[0] = '\0';
2761 
2762 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2763     PrintDebugString("WinAccessBridge::getAccessibleTextItems(%X, %p, %p, %d)", vmID, AccessibleContext, textItems, index);
2764 #else // JOBJECT64 is jlong (64 bit)
2765     PrintDebugString("WinAccessBridge::getAccessibleTextItems(%X, %016I64X, %p, %d)", vmID, AccessibleContext, textItems, index);
2766 #endif
2767     // need to call only the HWND/VM that contains this AC
2768     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2769     if (destABWindow != (HWND) 0) {
2770         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2771             memcpy(textItems, &(pkg->rTextItemsInfo), sizeof(AccessibleTextItemsInfo));
2772             if (pkg->rTextItemsInfo.letter != '/0') {
2773                 return TRUE;
2774             }
2775         }
2776     }
2777 
2778     return FALSE;
2779 }
2780 
2781 /**
2782  * getAccessibleTextSelectionInfo - returns information about the selected
2783  * text of the object implementing AccessibleText
2784  *
2785  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2786  */
2787 BOOL
2788 WinAccessBridge::getAccessibleTextSelectionInfo(long vmID,
2789                                                 JOBJECT64 AccessibleContext,
2790                                                 AccessibleTextSelectionInfo *selectionInfo) {
2791     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2792         return FALSE;
2793     }
2794     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage)];
2795     PackageType *type = (PackageType *) buffer;
2796     GetAccessibleTextSelectionInfoPackage *pkg = (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType));
2797     *type = cGetAccessibleTextSelectionInfoPackage;
2798     pkg->vmID = vmID;
2799     pkg->AccessibleContext = AccessibleContext;
2800 
2801 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2802     PrintDebugString("WinAccessBridge::getAccessibleTextSelectionInfo(%X, %p, %p)", vmID, AccessibleContext, selectionInfo);
2803 #else // JOBJECT64 is jlong (64 bit)
2804     PrintDebugString("WinAccessBridge::getAccessibleTextSelectionInfo(%X, %016I64X, %p)", vmID, AccessibleContext, selectionInfo);
2805 #endif
2806     // need to call only the HWND/VM that contains this AC
2807     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2808     if (destABWindow != (HWND) 0) {
2809         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2810             memcpy(selectionInfo, &(pkg->rTextSelectionItemsInfo), sizeof(AccessibleTextSelectionInfo));
2811             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
2812             return TRUE;
2813         }
2814     }
2815 
2816     return FALSE;
2817 }
2818 
2819 /**
2820  * getAccessibleTextAttributes - performs the Java code:
2821  *   ...[[[FIXME]]] fill in this comment...
2822  *
2823  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2824  */
2825 BOOL
2826 WinAccessBridge::getAccessibleTextAttributes(long vmID,
2827                                              JOBJECT64 AccessibleContext,
2828                                              jint index,
2829                                              AccessibleTextAttributesInfo *attributes) {
2830     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2831         return FALSE;
2832     }
2833     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage)];
2834     PackageType *type = (PackageType *) buffer;
2835     GetAccessibleTextAttributeInfoPackage *pkg = (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType));
2836     *type = cGetAccessibleTextAttributeInfoPackage;
2837     pkg->vmID = vmID;
2838     pkg->AccessibleContext = AccessibleContext;
2839     pkg->index = index;
2840 
2841 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2842     PrintDebugString("WinAccessBridge::getAccessibleTextAttributes(%X, %p, %d, %p)", vmID, AccessibleContext, index, attributes);
2843 #else // JOBJECT64 is jlong (64 bit)
2844     PrintDebugString("WinAccessBridge::getAccessibleTextAttributes(%X, %016I64X, %d, %p)", vmID, AccessibleContext, index, attributes);
2845 #endif
2846     // need to call only the HWND/VM that contains this AC
2847     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2848     if (destABWindow != (HWND) 0) {
2849         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2850             memcpy(attributes, &(pkg->rAttributeInfo), sizeof(AccessibleTextAttributesInfo));
2851             return TRUE;
2852         }
2853     }
2854 
2855     return FALSE;
2856 }
2857 
2858 /**
2859  * getAccessibleTextRect - gets the text bounding rectangle
2860  *
2861  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2862  */
2863 BOOL
2864 WinAccessBridge::getAccessibleTextRect(long vmID,
2865                                        JOBJECT64 AccessibleContext,
2866                                        AccessibleTextRectInfo *rectInfo,
2867                                        jint index) {
2868     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2869         return FALSE;
2870     }
2871     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage)];
2872     PackageType *type = (PackageType *) buffer;
2873     GetAccessibleTextRectInfoPackage *pkg = (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType));
2874     *type = cGetAccessibleTextRectInfoPackage;
2875     pkg->vmID = vmID;
2876     pkg->AccessibleContext = AccessibleContext;
2877     pkg->index = index;
2878 
2879 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2880     PrintDebugString("WinAccessBridge::getAccessibleTextRect(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2881 #else // JOBJECT64 is jlong (64 bit)
2882     PrintDebugString("WinAccessBridge::getAccessibleTextRect(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2883 #endif
2884     // need to call only the HWND/VM that contains this AC
2885     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2886     if (destABWindow != (HWND) 0) {
2887         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2888             memcpy(rectInfo, (&pkg->rTextRectInfo), sizeof(AccessibleTextRectInfo));
2889             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
2890             return TRUE;
2891         }
2892     }
2893 
2894     return FALSE;
2895 }
2896 
2897 
2898 /**
2899  * getAccessibleTextRect - gets the text bounding rectangle
2900  *
2901  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2902  */
2903 BOOL
2904 WinAccessBridge::getCaretLocation(long vmID,
2905                                        JOBJECT64 AccessibleContext,
2906                                        AccessibleTextRectInfo *rectInfo,
2907                                        jint index) {
2908     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2909         return FALSE;
2910     }
2911     char buffer[sizeof(PackageType) + sizeof(GetCaretLocationPackage)];
2912     PackageType *type = (PackageType *) buffer;
2913     GetCaretLocationPackage *pkg = (GetCaretLocationPackage *) (buffer + sizeof(PackageType));
2914     *type = cGetCaretLocationPackage;
2915     pkg->vmID = vmID;
2916     pkg->AccessibleContext = AccessibleContext;
2917     pkg->index = index;
2918 
2919 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2920     PrintDebugString("WinAccessBridge::getCaretLocation(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2921 #else // JOBJECT64 is jlong (64 bit)
2922     PrintDebugString("WinAccessBridge::getCaretLocation(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2923 #endif
2924     // need to call only the HWND/VM that contains this AC
2925     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2926     if (destABWindow != (HWND) 0) {
2927         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2928             memcpy(rectInfo, (&pkg->rTextRectInfo), sizeof(AccessibleTextRectInfo));
2929             return TRUE;
2930         }
2931     }
2932 
2933     return FALSE;
2934 }
2935 
2936 
2937 /**
2938  * getEventsWaiting - gets the number of events waiting to fire
2939  *
2940  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2941  */
2942 int


2952  * getAccessibleTextLineBounds - gets the bounding rectangle for the text line
2953  *
2954  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2955  */
2956 BOOL
2957 WinAccessBridge::getAccessibleTextLineBounds(long vmID,
2958                                              JOBJECT64 AccessibleContext,
2959                                              jint index, jint *startIndex, jint *endIndex) {
2960     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2961         return FALSE;
2962     }
2963     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage)];
2964     PackageType *type = (PackageType *) buffer;
2965     GetAccessibleTextLineBoundsPackage *pkg = (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType));
2966     *type = cGetAccessibleTextLineBoundsPackage;
2967     pkg->vmID = vmID;
2968     pkg->AccessibleContext = AccessibleContext;
2969     pkg->index = index;
2970 
2971 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2972     PrintDebugString("WinAccessBridge::getAccessibleTextLineBounds(%X, %p, %d, )", vmID, AccessibleContext, index);
2973 #else // JOBJECT64 is jlong (64 bit)
2974     PrintDebugString("WinAccessBridge::getAccessibleTextLineBounds(%X, %016I64X, %d, )", vmID, AccessibleContext, index);
2975 #endif
2976     // need to call only the HWND/VM that contains this AC
2977     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2978     if (destABWindow != (HWND) 0) {
2979         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2980             *startIndex = pkg->rLineStart;
2981             *endIndex = pkg->rLineEnd;
2982             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
2983             return TRUE;
2984         }
2985     }
2986 
2987     return FALSE;
2988 }
2989 
2990 
2991 /**
2992  * getAccessibleTextLineBounds - performs the Java code:
2993  *   ...[[[FIXME]]] fill in this comment...
2994  *
2995  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2996  */
2997 BOOL
2998 WinAccessBridge::getAccessibleTextRange(long vmID,
2999                                         JOBJECT64 AccessibleContext,
3000                                         jint start, jint end, wchar_t *text, short len) {
3001     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3002         return FALSE;
3003     }
3004     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage)];
3005     PackageType *type = (PackageType *) buffer;
3006     GetAccessibleTextRangePackage *pkg = (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType));
3007     *type = cGetAccessibleTextRangePackage;
3008     pkg->vmID = vmID;
3009     pkg->AccessibleContext = AccessibleContext;
3010     pkg->start = start;
3011     pkg->end = end;
3012 
3013 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
3014     PrintDebugString("WinAccessBridge::getAccessibleTextRange(%X, %p, %d, %d, )", vmID, AccessibleContext, start, end);
3015 #else // JOBJECT64 is jlong (64 bit)
3016     PrintDebugString("WinAccessBridge::getAccessibleTextRange(%X, %016I64X, %d, %d, )", vmID, AccessibleContext, start, end);
3017 #endif
3018     // need to call only the HWND/VM that contains this AC
3019     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3020     if (destABWindow != (HWND) 0) {
3021         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
3022             wcsncpy(text, pkg->rText, len);
3023             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
3024             return TRUE;
3025         }
3026     }
3027 
3028     return FALSE;
3029 }
3030 
3031 
3032 
3033 
3034 /********** AccessibleValue routines ***************/
3035 
3036 BOOL


3273     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3274     if (destABWindow != (HWND) 0) {
3275         sendMemoryPackage(buffer, sizeof(buffer), destABWindow);
3276     }
3277 }
3278 
3279 
3280 /*********** Event handling methods **********************************/
3281 
3282 /**
3283  * addEventNotification - tell all Java-launched AccessBridge DLLs
3284  *                        that we want events of the specified type
3285  *
3286  * [[[FIXME]]] since we're just sending a long & a source window,
3287  *                         we could use a private message rather than WM_COPYDATA
3288  *                         (though we still may want it to be synchronous; dunno...)
3289  *
3290  */
3291 void
3292 WinAccessBridge::addJavaEventNotification(jlong type) {
3293     PrintDebugString("WinAccessBridge::addJavaEventNotification(%016I64X)", type);
3294     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3295         return;
3296     }
3297 
3298     char buffer[sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage)];
3299     PackageType *pkgType = (PackageType *) buffer;
3300     AddJavaEventNotificationPackage *pkg = (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
3301     *pkgType = cAddJavaEventNotificationPackage;
3302     pkg->type = type;
3303     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3304 
3305     PrintDebugString("  ->pkgType = %X, eventType = %016I64X, DLLwindow = %p",
3306                      *pkgType, pkg->type, pkg->DLLwindow);
3307 
3308     // send addEventNotification message to all JVMs
3309     isVMInstanceChainInUse = true;
3310     AccessBridgeJavaVMInstance *current = javaVMs;
3311     while (current != (AccessBridgeJavaVMInstance *) 0) {
3312         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3313         current = current->nextJVMInstance;
3314     }
3315     isVMInstanceChainInUse = false;
3316 }
3317 
3318 /**
3319  * removeEventNotification - tell all Java-launched AccessBridge DLLs
3320  *                                                       that we no longer want events of the
3321  *                                                       specified type
3322  *
3323  * [[[FIXME]]] since we're just sending a long & a source window,
3324  *                         we could use a private message rather than WM_COPYDATA
3325  *                         (though we still may want it to be synchronous; dunno...)
3326  *
3327  */
3328 void
3329 WinAccessBridge::removeJavaEventNotification(jlong type) {
3330     PrintDebugString("in WinAccessBridge::removeJavaEventNotification(%016I64X)", type);
3331     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3332         return;
3333     }
3334     char buffer[sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage)];
3335     PackageType *pkgType = (PackageType *) buffer;
3336     RemoveJavaEventNotificationPackage *pkg = (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
3337     *pkgType = cRemoveJavaEventNotificationPackage;
3338     pkg->type = type;
3339     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3340 
3341     PrintDebugString("  ->pkgType = %X, eventType = %016I64X, DLLwindow = %p",
3342                      *pkgType, pkg->type, pkg->DLLwindow);
3343 
3344     // send removeEventNotification message to all JVMs
3345     isVMInstanceChainInUse = true;
3346     AccessBridgeJavaVMInstance *current = javaVMs;
3347     while (current != (AccessBridgeJavaVMInstance *) 0) {
3348         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3349         current = current->nextJVMInstance;
3350     }
3351     isVMInstanceChainInUse = false;
3352 }
3353 
3354 
3355 /*********** Event handling methods **********************************/
3356 
3357 /**
3358  * addAccessibilityEventNotification - tell all Java-launched AccessBridge DLLs
3359  *                        that we want events of the specified type
3360  *
3361  * [[[FIXME]]] since we're just sending a long & a source window,
3362  *                         we could use a private message rather than WM_COPYDATA
3363  *                         (though we still may want it to be synchronous; dunno...)
3364  *
3365  */
3366 void
3367 WinAccessBridge::addAccessibilityEventNotification(jlong type) {
3368     PrintDebugString("in WinAccessBridge::addAccessibilityEventNotification(%016I64X)", type);
3369     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3370         return;
3371     }
3372     char buffer[sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage)];
3373     PackageType *pkgType = (PackageType *) buffer;
3374     AddAccessibilityEventNotificationPackage *pkg = (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
3375     *pkgType = cAddAccessibilityEventNotificationPackage;
3376     pkg->type = type;
3377     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3378 
3379     PrintDebugString("  ->pkgType = %X, eventType = %016I64X, DLLwindow = %X",
3380                      *pkgType, pkg->type, pkg->DLLwindow);
3381 
3382     // send addEventNotification message to all JVMs
3383     isVMInstanceChainInUse = true;
3384     AccessBridgeJavaVMInstance *current = javaVMs;
3385     while (current != (AccessBridgeJavaVMInstance *) 0) {
3386         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3387         current = current->nextJVMInstance;
3388     }
3389     isVMInstanceChainInUse = false;
3390 }
3391 
3392 /**
3393  * removeAccessibilityEventNotification - tell all Java-launched AccessBridge DLLs
3394  *                                                       that we no longer want events of the
3395  *                                                       specified type
3396  *
3397  * [[[FIXME]]] since we're just sending a long & a source window,
3398  *                         we could use a private message rather than WM_COPYDATA
3399  *                         (though we still may want it to be synchronous; dunno...)
3400  *
3401  */
3402 void
3403 WinAccessBridge::removeAccessibilityEventNotification(jlong type) {
3404     PrintDebugString("in WinAccessBridge::removeAccessibilityEventNotification(%016I64X)", type);
3405     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3406         return;
3407     }
3408     char buffer[sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage)];
3409     PackageType *pkgType = (PackageType *) buffer;
3410     RemoveAccessibilityEventNotificationPackage *pkg = (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
3411     *pkgType = cRemoveAccessibilityEventNotificationPackage;
3412     pkg->type = type;
3413     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3414 
3415     PrintDebugString("  ->pkgType = %X, eventType = %016I64X, DLLwindow = %X",
3416                      *pkgType, pkg->type, pkg->DLLwindow);
3417 
3418     // send removeEventNotification message to all JVMs
3419     isVMInstanceChainInUse = true;
3420     AccessBridgeJavaVMInstance *current = javaVMs;
3421     while (current != (AccessBridgeJavaVMInstance *) 0) {
3422         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3423         current = current->nextJVMInstance;
3424     }
3425     isVMInstanceChainInUse = false;
3426 }
3427 
3428 
3429 #define CALL_SET_EVENT_FP(function, callbackFP)         \
3430         void WinAccessBridge::function(callbackFP fp) { \
3431                 eventHandler->function(fp, this);                       \
3432                 /* eventHandler calls back to winAccessBridgeDLL to set eventMask */    \
3433         }
3434 
3435     void WinAccessBridge::setJavaShutdownFP(AccessBridge_JavaShutdownFP fp) {




  59 // protects the javaVMs chain while in use
  60 bool isVMInstanceChainInUse;
  61 
  62 /* =================================================================================== */
  63 
  64 
  65 
  66 /**
  67  * Proc for "New JVM Found" dialog
  68  */
  69 BOOL CALLBACK newJVMFoundDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) {
  70 
  71     switch (message) {
  72     case WM_COMMAND:
  73         // PrintDebugString("    newJVMDialogProc: LOWORD(wParam) = %d", LOWORD(wParam));
  74 
  75         switch (LOWORD(wParam)) {
  76 
  77             // Remind user later that a new JVM was installed
  78         case cRemindThereIsNewJVM:
  79             PrintDebugString("[INFO]:    newJVMDialogProc: cRemindThereIsNewJVM");
  80             // do nothing
  81             EndDialog(hwndDlg, wParam);
  82             return TRUE;
  83 
  84             // Do not remind user later that a new JVM was installed
  85             /*
  86         case cDoNotRemindThereIsNewJVM:
  87             PrintDebugString("    newJVMDialogProc: cDoNotRemindThereIsNewJVM");
  88             // remember to not remind the user there are new JVMs
  89             PrintDebugString("theWindowsAccessBridge = %x", theWindowsAccessBridge);
  90             if (theWindowsAccessBridge != NULL) {
  91                 dontRemindUser(newJVMs);
  92             }
  93             EndDialog(hwndDlg, wParam);
  94             return TRUE;
  95             */
  96 
  97             // Run the AccessBridge installer
  98             /*
  99         case cInstallAccessBridge:


 113         ;
 114     }
 115     return FALSE;
 116 }
 117 
 118 
 119 
 120 /* =========================================================================== */
 121 
 122 // ---------------------------------------------------------------------------
 123 
 124 extern "C" {
 125     /**
 126      * DllMain - where Windows executables will load/unload us
 127      *
 128      */
 129     BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) {
 130 
 131         switch (fdwReason) {
 132         case DLL_PROCESS_ATTACH:        // A Windows executable loaded us
 133             initializeFileLogger("_windows_access_bridge");
 134             PrintDebugString("[INFO]: DLL_PROCESS_ATTACH");
 135             theWindowsAccessBridge = new WinAccessBridge(hinstDll);
 136             break;
 137 
 138         case DLL_PROCESS_DETACH:        // A Windows executable unloaded us
 139             if (theWindowsAccessBridge != (WinAccessBridge *) 0) {
 140                 PrintDebugString("[INFO]: *** AccessBridgeDialogProc -> deleting theWindowsAccessBridge");
 141                 delete theWindowsAccessBridge;
 142             }
 143             break;
 144         }
 145 
 146         return(TRUE);
 147     }
 148 
 149     /**
 150      * Append debug info to dialog
 151      *
 152      * replaced with code to send output to debug file
 153      *
 154      */
 155     void AppendToCallInfo(char *s) {
 156 
 157         /*
 158           _CrtDbgReport(_CRT_WARN, (const char *) NULL, NULL, (const char *) NULL,
 159           (const char *) "WinAccessBridge: %s", s);
 160         */
 161 
 162         char buf[1024];
 163         sprintf(buf, "WinAccessBridge: %s", s);
 164         OutputDebugString(buf);
 165     }
 166 
 167     /**
 168      * Our window proc
 169      *
 170      */
 171     BOOL CALLBACK AccessBridgeDialogProc(HWND hDlg, UINT message, UINT wParam, LONG lParam) {
 172         COPYDATASTRUCT *sentToUs;
 173         char *package;
 174 
 175         switch (message) {
 176         case WM_INITDIALOG:
 177             PrintDebugString("[INFO]: AccessBridgeDialogProc -> Initializing");
 178             break;
 179 
 180             // call from Java with data for us to deliver
 181         case WM_COPYDATA:
 182             if (theDialogWindow == (HWND) wParam) {
 183                 PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got WM_COPYDATA from Java Bridge DLL");
 184             } else {
 185                 PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got WM_COPYDATA from HWND %p", wParam);
 186                 sentToUs = (COPYDATASTRUCT *) lParam;
 187                 package = (char *) sentToUs->lpData;
 188                 theWindowsAccessBridge->preProcessPackage(package, sentToUs->cbData);
 189             }
 190             break;
 191 
 192             // message to ourselves -> de-queue messages and send 'em
 193         case AB_MESSAGE_QUEUED:
 194             PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got AB_MESSAGE_QUEUED from ourselves");
 195             theWindowsAccessBridge->receiveAQueuedPackage();
 196             break;
 197 
 198             // a JavaAccessBridge DLL is going away
 199             //
 200             // When JavaVMDestroyed is called a AccessBridgeJavaVMInstance in the
 201             // javaVMs chain will be removed.  If that chain is in use this will
 202             // cause a crash.  One way AB_DLL_GOING_AWAY can arrive is on any
 203             // outgoing SendMessage call.  SendMessage normally spins waiting for
 204             // a response.  However, if there is an incoming SendMessage, e.g. for
 205             // AB_DLL_GOING_AWAY Windows will send that request to this DialogProc.
 206             // One seemingly easy way to combat that is to use SendMessageTimeout
 207             // with the SMTO_BLOCK flag set.  However, it has been the case that
 208             // even after using that technique AB_DLL_GOING_AWAY can still arrive
 209             // in the middle of processing the javaVMs chain.  An alternative that
 210             // was tried was to use a critical section around any access ot the
 211             // javaVMs chain but unfortunately the AB_DLL_GOING_AWAY message arrives
 212             // on the same thread and thus the use of a critical section is ineffective.
 213             // The solution then is to set a flag whenever the javaVMs chain is being
 214             // used and if that flag is set at this point the message will be posted
 215             // to the message queue.  That would delay the destruction of the instance
 216             // until the chain is not being traversed.
 217         case AB_DLL_GOING_AWAY:
 218             PrintDebugString("[INFO]: ***** AccessBridgeDialogProc -> Got AB_DLL_GOING_AWAY message");
 219             if (isVMInstanceChainInUse) {
 220                 PrintDebugString("[INFO]:   javaVMs chain in use, calling PostMessage");
 221                 PostMessage(hDlg, AB_DLL_GOING_AWAY, wParam, (LPARAM)0);
 222             } else {
 223                 PrintDebugString("[INFO]:   calling javaVMDestroyed");
 224                 theWindowsAccessBridge->JavaVMDestroyed((HWND) wParam);
 225             }
 226             break;
 227 
 228         default:
 229             // the JavaVM is saying "hi"!
 230             // wParam == sourceHwnd; lParam == JavaVMID
 231             if (message == theFromJavaHelloMsgID) {
 232                 PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got theFromJavaHelloMsgID; wParam = %p, lParam = %p", wParam, lParam);
 233                 theWindowsAccessBridge->rendezvousWithNewJavaDLL((HWND) wParam, (long ) lParam);
 234             }
 235             break;
 236         }
 237 
 238         return (FALSE);
 239     }
 240 
 241 }
 242 
 243 
 244 
 245 
 246 // ---------------------------------------------------------------------------
 247 
 248 /**
 249  * Initialize the WinAccessBridge
 250  *
 251  */
 252 WinAccessBridge::WinAccessBridge(HINSTANCE hInstance) {
 253 
 254     PrintDebugString("[INFO]: WinAccessBridge ctor");
 255 
 256     //  IntializeCriticalSection should only be called once.
 257     InitializeCriticalSection(&sendMemoryIPCLock);
 258     windowsInstance = hInstance;
 259     javaVMs = (AccessBridgeJavaVMInstance *) 0;
 260     eventHandler = new AccessBridgeEventHandler();
 261     messageQueue = new AccessBridgeMessageQueue();
 262     initBroadcastMessageIDs();          // get the unique to us broadcast msg. IDs
 263     theWindowsAccessBridge = this;
 264     isVMInstanceChainInUse = false;
 265 
 266     ShowWindow(theDialogWindow, SW_SHOW);
 267 }
 268 
 269 
 270 
 271 /**
 272  * Destroy the WinAccessBridge
 273  *
 274  */
 275 WinAccessBridge::~WinAccessBridge() {
 276     // inform all other AccessBridges that we're going away
 277     //  -> shut down all event listening
 278     //  -> release all objects held in the JVM by us
 279 
 280     PrintDebugString("[INFO]: *****in WinAccessBridge::~WinAccessBridge()");
 281 
 282     // send a broadcast msg.; let other AccessBridge DLLs know we're going away
 283     AccessBridgeJavaVMInstance *current = javaVMs;
 284     while (current != (AccessBridgeJavaVMInstance *) 0) {
 285         PrintDebugString("[INFO]:   telling %p we're going away", current->javaAccessBridgeWindow);
 286         SendMessage(current->javaAccessBridgeWindow,
 287                     AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0);
 288         current = current->nextJVMInstance;
 289     }
 290 
 291     PrintDebugString("[INFO]:   finished telling JVMs about our demise");
 292 
 293     delete eventHandler;
 294     delete messageQueue;
 295     delete javaVMs;
 296 
 297     PrintDebugString("[INFO]:   finished deleting eventHandler, messageQueue, and javaVMs");
 298     PrintDebugString("[INFO]: GOODBYE CRUEL WORLD...");
 299 
 300     DestroyWindow(theDialogWindow);
 301 }
 302 
 303 
 304 /**
 305  * Bring up our window; make a connection to the rest of the world
 306  *
 307  */
 308 BOOL
 309 WinAccessBridge::initWindow() {
 310     theDialogWindow = CreateDialog(windowsInstance,
 311                                    "ACCESSBRIDGESTATUSWINDOW", NULL,
 312                                    (DLGPROC) AccessBridgeDialogProc);
 313 
 314     // If window could not be created, return "failure".
 315     if (!theDialogWindow)
 316         return (FALSE);
 317 
 318     dialogWindow = theDialogWindow;


 322     // DEBUG_CODE(UpdateWindow (theDialogWindow));
 323 
 324     // post a broadcast msg.; let other AccessBridge DLLs know we exist
 325     PostMessage(HWND_BROADCAST, theFromWindowsHelloMsgID, (WPARAM) dialogWindow, (LPARAM) 0);
 326 
 327     return (TRUE);
 328 }
 329 
 330 // -----------------------
 331 
 332 /**
 333  * rendezvousWithNewJavaDLL
 334  *              - Build AccessBridgeJavaVMInstance data structure
 335  *                (including setting up Memory-Mapped file info)
 336  *
 337  */
 338 LRESULT
 339 WinAccessBridge::rendezvousWithNewJavaDLL(HWND JavaBridgeDLLwindow, long vmID) {
 340     LRESULT returnVal;
 341 
 342     PrintDebugString("[INFO]: in WinAccessBridge::rendezvousWithNewJavaDLL(%p, %X)",
 343                      JavaBridgeDLLwindow, vmID);
 344 
 345     isVMInstanceChainInUse = true;
 346     AccessBridgeJavaVMInstance *newVM =
 347         new AccessBridgeJavaVMInstance(dialogWindow, JavaBridgeDLLwindow, vmID, javaVMs);
 348     javaVMs = newVM;
 349     isVMInstanceChainInUse = false;
 350 
 351     returnVal = javaVMs->initiateIPC();
 352     if (returnVal == 0) {
 353 
 354         // tell the newly created JavaVM what events we're interested in, if any
 355         long javaEventMask = eventHandler->getJavaEventMask();
 356         long accessibilityEventMask = eventHandler->getAccessibilityEventMask();
 357 
 358         PrintDebugString("[INFO]:   Setting Java event mask to: %X", javaEventMask);
 359 
 360         if (javaEventMask != 0) {
 361             addJavaEventNotification(javaEventMask);
 362         }
 363 
 364         PrintDebugString("[INFO]:   Setting Accessibility event mask to: %X", accessibilityEventMask);
 365 
 366         if (accessibilityEventMask != 0) {
 367             addAccessibilityEventNotification(accessibilityEventMask);
 368         }
 369     } else {
 370         PrintDebugString("[ERROR]: Failed to initiate IPC with newly created JavaVM!!!");
 371         return FALSE;
 372     }
 373 
 374     PrintDebugString("[INFO]:   Success!!  We rendezvoused with the JavaDLL");
 375     return returnVal;
 376 }
 377 
 378 // -----------------------
 379 
 380 /**
 381  * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging
 382  *               with the Java AccessBridge DLL
 383  *
 384  *               NOTE: WM_COPYDATA is only for one-way IPC; there
 385  *               is now way to return parameters (especially big ones)
 386  *               Use sendMemoryPackage() to do that!
 387  */
 388 void
 389 WinAccessBridge::sendPackage(char *buffer, long bufsize, HWND destWindow) {
 390     COPYDATASTRUCT toCopy;
 391     toCopy.dwData = 0;          // 32-bits we could use for something...
 392     toCopy.cbData = bufsize;
 393     toCopy.lpData = buffer;
 394 


 405  *                     In the SendMessage call, the third param (WPARAM) is
 406  *                     the source HWND (theDialogWindow in this case), and
 407  *                     the fourth param (LPARAM) is the size in bytes of
 408  *                     the package put into shared memory.
 409  *
 410  */
 411 BOOL
 412 WinAccessBridge::sendMemoryPackage(char *buffer, long bufsize, HWND destWindow) {
 413     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 414         return FALSE;
 415     }
 416     AccessBridgeJavaVMInstance *ourABJavaVMInstance;
 417     ourABJavaVMInstance = javaVMs->findABJavaVMInstanceFromJavaHWND(destWindow);
 418     if (ourABJavaVMInstance != (AccessBridgeJavaVMInstance *) 0) {
 419         if (!ourABJavaVMInstance->sendMemoryPackage(buffer, bufsize)) {
 420             // return falue to the caller
 421             memset(buffer, 0, bufsize);
 422             return FALSE;
 423         }
 424     } else {
 425         PrintDebugString("[ERROR]: sending memory package: couldn't find destWindow");
 426         return FALSE;
 427     }
 428     return TRUE;
 429 }
 430 
 431 
 432 /**
 433  * queuePackage - put a package onto the queue for latter processing
 434  *
 435  */
 436 BOOL
 437 WinAccessBridge::queuePackage(char *buffer, long bufsize) {
 438     PrintDebugString("[INFO]:  in WinAccessBridge::queuePackage(%p, %d)", buffer, bufsize);
 439 
 440     AccessBridgeQueueElement *element = new AccessBridgeQueueElement(buffer, bufsize);
 441 
 442     messageQueue->add(element);
 443     PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0);
 444     return TRUE;
 445 }
 446 
 447 
 448 /**
 449  * receiveAQueuedPackage - remove a pending packge from the queue and
 450  *                         handle it. If the queue is busy, post a
 451  *                         message to self to retrieve it later
 452  *
 453  */
 454 BOOL
 455 WinAccessBridge::receiveAQueuedPackage() {
 456     AccessBridgeQueueElement *element = NULL;
 457 
 458     PrintDebugString("[INFO]: in WinAccessBridge::receiveAQueuedPackage()");
 459 
 460     // ensure against re-entrancy problems...
 461     if (messageQueue->getRemoveLockSetting() == FALSE) {
 462         messageQueue->setRemoveLock(TRUE);
 463 
 464         PrintDebugString("[INFO]:  dequeueing message");
 465 
 466         QueueReturns result = messageQueue->remove(&element);
 467 
 468         switch (result) {
 469 
 470         case cQueueBroken:
 471             PrintDebugString("[ERROR]: Queue seems to be broken!");
 472             messageQueue->setRemoveLock(FALSE);
 473             return FALSE;
 474 
 475         case cMoreMessages:
 476         case cQueueEmpty:
 477             if (element != (AccessBridgeQueueElement *) 0) {
 478                 PrintDebugString("[INFO]:  found one; sending it!");
 479                 processPackage(element->buffer, element->bufsize);
 480                 delete element;
 481             } else {
 482                 PrintDebugString("[WARN]:   ODD... element == 0!");
 483                 return FALSE;
 484             }
 485             break;
 486 
 487         case cQueueInUse:
 488             PrintDebugString("[WARN]:  Queue in use, will try again later...");
 489             PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0);
 490             break;
 491 
 492         default:
 493             messageQueue->setRemoveLock(FALSE);
 494             return FALSE;       // should never get something we don't recognize!
 495         }
 496     } else {
 497         PrintDebugString("[WARN]:  unable to dequeue message; remove lock is set");
 498         PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); // Fix for 6995891
 499     }
 500 
 501     messageQueue->setRemoveLock(FALSE);
 502     return TRUE;
 503 }
 504 
 505 // -----------------------
 506 
 507 /**
 508  * preProcessPackage
 509  *              - do triage on incoming packages; queue some, deal with others
 510  *
 511  */
 512 void
 513 WinAccessBridge::preProcessPackage(char *buffer, long bufsize) {
 514     PrintDebugString("[INFO]: PreProcessing package sent from Java:");
 515 
 516     PackageType *type = (PackageType *) buffer;
 517 
 518     switch (*type) {
 519 
 520     PrintDebugString("[INFO]:    type == %X", *type);
 521 
 522     // event packages all get queued for later handling
 523     //case cPropertyChangePackage:
 524     case cJavaShutdownPackage:
 525     case cFocusGainedPackage:
 526     case cFocusLostPackage:
 527     case cCaretUpdatePackage:
 528     case cMouseClickedPackage:
 529     case cMouseEnteredPackage:
 530     case cMouseExitedPackage:
 531     case cMousePressedPackage:
 532     case cMouseReleasedPackage:
 533     case cMenuCanceledPackage:
 534     case cMenuDeselectedPackage:
 535     case cMenuSelectedPackage:
 536     case cPopupMenuCanceledPackage:
 537     case cPopupMenuWillBecomeInvisiblePackage:
 538     case cPopupMenuWillBecomeVisiblePackage:
 539 
 540     case cPropertyCaretChangePackage:
 541     case cPropertyDescriptionChangePackage:
 542     case cPropertyNameChangePackage:
 543     case cPropertySelectionChangePackage:
 544     case cPropertyStateChangePackage:
 545     case cPropertyTextChangePackage:
 546     case cPropertyValueChangePackage:
 547     case cPropertyVisibleDataChangePackage:
 548     case cPropertyChildChangePackage:
 549     case cPropertyActiveDescendentChangePackage:
 550 
 551     case cPropertyTableModelChangePackage:
 552 
 553         queuePackage(buffer, bufsize);
 554         break;
 555 
 556         // perhaps there will be some other packages to process at some point... //
 557 
 558     default:
 559         PrintDebugString("[ERROR]:   processing FAILED!! -> don't know how to handle type = %X", *type);
 560         break;
 561     }
 562 
 563     PrintDebugString("[INFO]:    package preprocessing completed");
 564 }
 565 
 566 
 567 #define DISPATCH_EVENT_PACKAGE(packageID, eventPackage, fireEventMethod)            \
 568     case packageID:                                                                 \
 569         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
 570             eventPackage *pkg =                                                     \
 571                 (eventPackage *) (buffer + sizeof(PackageType));                    \
 572             PrintDebugString("[INFO]:    begin callback to AT, type == %X", *type);         \
 573                 theWindowsAccessBridge->eventHandler->fireEventMethod(              \
 574                     pkg->vmID, pkg->Event, pkg->AccessibleContextSource);           \
 575                 PrintDebugString("[INFO]:    event callback complete!");                    \
 576         } else {                                                                    \
 577             PrintDebugString("[ERROR]:   processing FAILED!! -> bufsize = %d; expectation = %d", \
 578                 bufsize, sizeof(PackageType) + sizeof(eventPackage));               \
 579         }                                                                           \
 580         break;
 581 
 582 #define DISPATCH_PROPERTY_CHANGE_PACKAGE(packageID, eventPackage, fireEventMethod, oldValue, newValue) \
 583     case packageID:                                                                 \
 584         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
 585             eventPackage *pkg =                                                     \
 586                 (eventPackage *) (buffer + sizeof(PackageType));                    \
 587             PrintDebugString("[INFO]:    begin callback to AT, type == %X", *type);         \
 588             theWindowsAccessBridge->eventHandler->fireEventMethod(                  \
 589                 pkg->vmID, pkg->Event, pkg->AccessibleContextSource,                \
 590                 pkg->oldValue, pkg->newValue);                                      \
 591             PrintDebugString("[INFO]:    event callback complete!");                        \
 592         } else {                                                                    \
 593             PrintDebugString("[ERROR]:   processing FAILED!! -> bufsize = %d; expectation = %d", \
 594                 bufsize, sizeof(PackageType) + sizeof(eventPackage));               \
 595         }                                                                           \
 596         break;
 597 
 598 #define DISPATCH_PROPERTY_TABLE_MODEL_CHANGE_PACKAGE(packageID, eventPackage, fireEventMethod, oldValue, newValue) \
 599     case packageID:                                                                 \
 600         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
 601             eventPackage *pkg =                                                     \
 602                 (eventPackage *) (buffer + sizeof(PackageType));                    \
 603             PrintDebugString("[INFO]:    begin callback to AT, type == %X", *type);         \
 604             theWindowsAccessBridge->eventHandler->fireEventMethod(                  \
 605                 pkg->vmID, pkg->Event, pkg->AccessibleContextSource,                \
 606                 pkg->oldValue, pkg->newValue);                                      \
 607             PrintDebugString("[INFO]:    event callback complete!");                        \
 608         } else {                                                                    \
 609             PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d", \
 610                 bufsize, sizeof(PackageType) + sizeof(eventPackage));                \
 611         }                                                                            \
 612         break;
 613 
 614 /**
 615  * processPackage - processes the output of SendMessage(WM_COPYDATA)
 616  *                  to do IPC messaging with the Java AccessBridge DLL
 617  *
 618  */
 619 void
 620 WinAccessBridge::processPackage(char *buffer, long bufsize) {
 621     PrintDebugString("[INFO]: WinAccessBridge::Processing package sent from Java:");
 622 
 623     PackageType *type = (PackageType *) buffer;
 624 
 625     switch (*type) {
 626 
 627     PrintDebugString("[INFO]:    type == %X", *type);
 628 
 629     case cJavaShutdownPackage:
 630         PrintDebugString("[INFO]:    type == cJavaShutdownPackage");
 631         if (bufsize == sizeof(PackageType) + sizeof(JavaShutdownPackage)) {
 632             JavaShutdownPackage *pkg =
 633                 (JavaShutdownPackage *) (buffer + sizeof(PackageType));
 634             theWindowsAccessBridge->eventHandler->fireJavaShutdown(pkg->vmID);
 635             PrintDebugString("[INFO]:    event callback complete!");
 636             PrintDebugString("[INFO]:    event fired!");
 637         } else {
 638             PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
 639                              bufsize, sizeof(PackageType) + sizeof(JavaShutdownPackage));
 640         }
 641         break;
 642 
 643 
 644         DISPATCH_EVENT_PACKAGE(cFocusGainedPackage, FocusGainedPackage, fireFocusGained);
 645         DISPATCH_EVENT_PACKAGE(cFocusLostPackage, FocusLostPackage, fireFocusLost);
 646 
 647         DISPATCH_EVENT_PACKAGE(cCaretUpdatePackage, CaretUpdatePackage, fireCaretUpdate);
 648 
 649         DISPATCH_EVENT_PACKAGE(cMouseClickedPackage, MouseClickedPackage, fireMouseClicked);
 650         DISPATCH_EVENT_PACKAGE(cMouseEnteredPackage, MouseEnteredPackage, fireMouseEntered);
 651         DISPATCH_EVENT_PACKAGE(cMouseExitedPackage, MouseExitedPackage, fireMouseExited);
 652         DISPATCH_EVENT_PACKAGE(cMousePressedPackage, MousePressedPackage, fireMousePressed);
 653         DISPATCH_EVENT_PACKAGE(cMouseReleasedPackage, MouseReleasedPackage, fireMouseReleased);
 654 
 655         DISPATCH_EVENT_PACKAGE(cMenuCanceledPackage, MenuCanceledPackage, fireMenuCanceled);
 656         DISPATCH_EVENT_PACKAGE(cMenuDeselectedPackage, MenuDeselectedPackage, fireMenuDeselected);
 657         DISPATCH_EVENT_PACKAGE(cMenuSelectedPackage, MenuSelectedPackage, fireMenuSelected);
 658         DISPATCH_EVENT_PACKAGE(cPopupMenuCanceledPackage, PopupMenuCanceledPackage, firePopupMenuCanceled);


 682             DISPATCH_EVENT_PACKAGE(cPropertyVisibleDataChangePackage,
 683                                    PropertyVisibleDataChangePackage, firePropertyVisibleDataChange)
 684             DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyChildChangePackage,
 685                                              PropertyChildChangePackage,
 686                                              firePropertyChildChange,
 687                                              oldChildAccessibleContext,
 688                                              newChildAccessibleContext)
 689             DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyActiveDescendentChangePackage,
 690                                              PropertyActiveDescendentChangePackage,
 691                                              firePropertyActiveDescendentChange,
 692                                              oldActiveDescendentAccessibleContext,
 693                                              newActiveDescendentAccessibleContext)
 694 
 695             DISPATCH_PROPERTY_TABLE_MODEL_CHANGE_PACKAGE(cPropertyTableModelChangePackage,
 696                                                          PropertyTableModelChangePackage,
 697                                                          firePropertyTableModelChange,
 698                                                          oldValue, newValue)
 699 
 700 
 701             default:
 702         PrintDebugString("[ERROR]:    processing FAILED!! -> don't know how to handle type = %X", *type);
 703         break;
 704     }
 705 
 706     PrintDebugString("[INFO]:    package processing completed");
 707 }
 708 
 709 
 710 // -----------------------------
 711 
 712 void
 713 WinAccessBridge::JavaVMDestroyed(HWND VMBridgeDLLWindow) {
 714     PrintDebugString("[INFO]: ***** WinAccessBridge::JavaVMDestroyed(%p)", VMBridgeDLLWindow);
 715 
 716     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 717         return;
 718     }
 719 
 720     isVMInstanceChainInUse = true;
 721     AccessBridgeJavaVMInstance *currentVM = javaVMs;
 722     AccessBridgeJavaVMInstance *previousVM = javaVMs;
 723     if (javaVMs->javaAccessBridgeWindow == VMBridgeDLLWindow) {
 724         javaVMs = javaVMs->nextJVMInstance;
 725         delete currentVM;
 726 
 727         PrintDebugString("[INFO]:   data structures successfully removed");
 728 
 729         // [[[FIXME]]] inform Windows AT that a JVM went away,
 730         // and that any jobjects it's got lying around for that JVM
 731         // are now invalid
 732 
 733     } else {
 734         while (currentVM != (AccessBridgeJavaVMInstance *) 0) {
 735             if (currentVM->javaAccessBridgeWindow == VMBridgeDLLWindow) {
 736                 previousVM->nextJVMInstance = currentVM->nextJVMInstance;
 737                 delete currentVM;
 738 
 739                 PrintDebugString("[INFO]:   data structures successfully removed");
 740 
 741                 // [[[FIXME]]] inform Windows AT that a JVM went away,
 742                 // and that any jobjects it's got lying around for that JVM
 743                 // are now invalid
 744                 isVMInstanceChainInUse = false;
 745                 return;
 746             } else {
 747                 previousVM = currentVM;
 748                 currentVM = currentVM->nextJVMInstance;
 749             }
 750         }
 751         PrintDebugString("[ERROR]: couldn't find matching data structures!");
 752     }
 753     isVMInstanceChainInUse = false;
 754 }
 755 
 756 // -----------------------
 757 
 758 /**
 759  * releaseJavaObject - lets the JavaVM know it can release the Java Object
 760  *
 761  * Note: once you have made this call, the JavaVM will garbage collect
 762  * the jobject you pass in.  If you later use that jobject in another
 763  * call, you will cause all maner of havoc!
 764  *
 765  */
 766 void
 767 WinAccessBridge::releaseJavaObject(long vmID, JOBJECT64 object) {
 768 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
 769     PrintDebugString("[INFO]: WinAccessBridge::releaseJavaObject(%X, %p)", vmID, object);
 770 #else // JOBJECT64 is jlong (64 bit)
 771     PrintDebugString("[INFO]: WinAccessBridge::releaseJavaObject(%X, %016I64X)", vmID, object);
 772 #endif
 773     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 774         return;
 775     }
 776     char buffer[sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage)];
 777     PackageType *type = (PackageType *) buffer;
 778     ReleaseJavaObjectPackage *pkg = (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType));
 779     *type = cReleaseJavaObjectPackage;
 780     pkg->vmID = vmID;
 781     pkg->object = object;
 782 
 783     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
 784     if (destABWindow != (HWND) 0) {
 785         sendPackage(buffer, sizeof(buffer), destABWindow);              // no return values!
 786     }
 787 }
 788 
 789 // -----------------------
 790 
 791 /**
 792  * getVersionInfo - fill the AccessBridgeVersionInfo struct
 793  *
 794  */
 795 BOOL
 796 WinAccessBridge::getVersionInfo(long vmID, AccessBridgeVersionInfo *info) {
 797     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 798         return FALSE;
 799     }
 800     char buffer[sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage)];
 801     PackageType *type = (PackageType *) buffer;
 802     GetAccessBridgeVersionPackage *pkg = (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType));
 803     *type = cGetAccessBridgeVersionPackage;
 804     pkg->vmID = vmID;
 805 
 806     PrintDebugString("[INFO]: WinAccessBridge::getVersionInfo(%X, )", vmID);
 807     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
 808     if (destABWindow != (HWND) 0) {
 809         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
 810             memcpy(info, &(pkg->rVersionInfo), sizeof(AccessBridgeVersionInfo));
 811             PrintDebugString("[INFO]:   VMversion: %ls\n"\
 812                              "          bridgeJavaClassVersion: %ls\n"\
 813                              "          bridgeJavaDLLVersion: %ls\n"\
 814                              "          bridgeWinDLLVersion: %ls\n"\
 815             , info->VMversion, info->bridgeJavaClassVersion, info->bridgeJavaDLLVersion, info->bridgeWinDLLVersion);
 816             return TRUE;
 817         }
 818     }
 819     return FALSE;
 820 }
 821 
 822 
 823 /********** Window-related routines ***********************************/
 824 
 825 /**
 826  * isJavaWindow - returns TRUE if the HWND is a top-level Java Window
 827  *
 828  * Note: just because the Windnow is a top-level Java window, that doesn't
 829  * mean that it is accessible.  Call getAccessibleContextFromHWND(HWND) to get the
 830  * AccessibleContext, if any, for an HWND that is a Java Window.
 831  *
 832  */
 833 BOOL
 834 WinAccessBridge::isJavaWindow(HWND window) {
 835     HWND hwnd;
 836 
 837     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 838         return FALSE;
 839     }
 840 
 841     // quick check to see if 'window' is top-level; if not, it's not interesting...
 842     // [[[FIXME]]] is this for sure an OK optimization?
 843     hwnd = getTopLevelHWND(window);
 844     if (hwnd == (HWND) NULL) {
 845         return FALSE;
 846     }
 847 
 848     PrintDebugString("[INFO]: In WinAccessBridge::isJavaWindow");
 849 
 850 
 851 
 852     char buffer[sizeof(PackageType) + sizeof(IsJavaWindowPackage)];
 853     PackageType *type = (PackageType *) buffer;
 854     IsJavaWindowPackage *pkg = (IsJavaWindowPackage *) (buffer + sizeof(PackageType));
 855     *type = cIsJavaWindowPackage;
 856     pkg->window = (jint) window;
 857 
 858     PrintDebugString("[INFO]: WinAccessBridge::isJavaWindow(%p)", window);
 859 
 860     isVMInstanceChainInUse = true;
 861     AccessBridgeJavaVMInstance *current = javaVMs;
 862     while (current != (AccessBridgeJavaVMInstance *) 0) {
 863         if (sendMemoryPackage(buffer, sizeof(buffer), current->javaAccessBridgeWindow) == TRUE) {
 864             if (pkg->rResult != 0) {
 865                 isVMInstanceChainInUse = false;
 866                 return TRUE;
 867             }
 868         }
 869         current = current->nextJVMInstance;
 870     }
 871     isVMInstanceChainInUse = false;
 872     return FALSE;
 873 
 874 
 875     /*
 876       char classname[256];
 877       HWND hwnd;
 878 


 893     // JDK 1.4 introduces new (and changes old) classnames
 894     /*
 895       else if (strstr(classname, "SunAwtToolkit") != 0) {
 896       return TRUE;
 897       } else if (strstr(classname, "javax.swing.JFrame") != 0) {
 898       return TRUE;
 899       }
 900     */
 901 
 902     return FALSE;
 903 }
 904 
 905 /**
 906  * isSameObject - returns TRUE if the two object references refer to
 907  *     the same object. Otherwise, this method returns FALSE:
 908  */
 909 BOOL
 910 WinAccessBridge::isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) {
 911 
 912 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
 913     PrintDebugString("[INFO]: WinAccessBridge::isSameObject(%p %p)", obj1, obj2);
 914 #else // JOBJECT64 is jlong (64 bit)
 915     PrintDebugString("[INFO]: WinAccessBridge::isSameObject(%016I64X %016I64X)", obj1, obj2);
 916 #endif
 917 
 918     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 919         return FALSE;
 920     }
 921 
 922     char buffer[sizeof(PackageType) + sizeof(IsSameObjectPackage)];
 923     PackageType *type = (PackageType *) buffer;
 924     IsSameObjectPackage *pkg = (IsSameObjectPackage *) (buffer + sizeof(PackageType));
 925     *type = cIsSameObjectPackage;
 926     pkg->vmID = vmID;
 927     pkg->obj1 = obj1;
 928     pkg->obj2 = obj2;
 929 
 930     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
 931     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
 932         if (pkg->rResult != 0) {
 933             PrintDebugString("[INFO]:   WinAccessBridge::isSameObject returning TRUE (same object)");
 934             return TRUE;
 935         } else {
 936             PrintDebugString("[INFO]:   WinAccessBridge::isSameObject returning FALSE (different object)");
 937             return FALSE;
 938         }
 939     }
 940     PrintDebugString("[ERROR]:   WinAccessBridge::isSameObject returning FALSE (sendMemoryPackage failed)");
 941     return FALSE;
 942 }
 943 
 944 /**
 945  * FromHWND - returns the AccessibleContext jobject for the HWND
 946  *
 947  * Note: this routine can return null, even if the HWND is a Java Window,
 948  * because the Java Window may not be accessible.
 949  *
 950  */
 951 BOOL
 952 WinAccessBridge::getAccessibleContextFromHWND(HWND window, long *vmID, JOBJECT64 *AccessibleContext) {
 953     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
 954         return FALSE;
 955     }
 956 
 957     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage)];
 958     PackageType *type = (PackageType *) buffer;
 959     GetAccessibleContextFromHWNDPackage *pkg = (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType));
 960     *type = cGetAccessibleContextFromHWNDPackage;
 961     pkg->window = (jint) window;
 962 
 963     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextFromHWND(%p, )", window);
 964 
 965     DEBUG_CODE(pkg->rVMID = (long ) 0x01010101);
 966     DEBUG_CODE(pkg->rAccessibleContext = (JOBJECT64) 0x01010101);
 967 
 968     isVMInstanceChainInUse = true;
 969     AccessBridgeJavaVMInstance *current = javaVMs;
 970     while (current != (AccessBridgeJavaVMInstance *) 0) {
 971 
 972         if (sendMemoryPackage(buffer, sizeof(buffer), current->javaAccessBridgeWindow) == TRUE) {
 973             if (pkg->rAccessibleContext != 0) {
 974                 *vmID = pkg->rVMID;
 975                 *AccessibleContext = (JOBJECT64)pkg->rAccessibleContext;
 976                 PrintDebugString("[INFO]:     current->vmID = %X, pkg->rVMID = %X", current->vmID, pkg->rVMID);

 977 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
 978                 PrintDebugString("[INFO]:     pkg->rAccessibleContext = %p", pkg->rAccessibleContext);
 979 #else // JOBJECT64 is jlong (64 bit)
 980                 PrintDebugString("[INFO]:     pkg->rAccessibleContext = %016I64X", pkg->rAccessibleContext);
 981 #endif
 982                 if (pkg->rVMID != current->vmID) {
 983                     PrintDebugString("[ERROR]: getAccessibleContextFromHWND vmIDs don't match!");
 984                     isVMInstanceChainInUse = false;
 985                     return FALSE;
 986                 }
 987                 isVMInstanceChainInUse = false;
 988                 return TRUE;
 989             }
 990         }
 991         current = current->nextJVMInstance;
 992     }
 993     isVMInstanceChainInUse = false;
 994 
 995     // This isn't really an error; it just means that the HWND was for a non-Java
 996     // window.  It's also possible the HWND was for a Java window but the JVM has
 997     // since been shut down and sendMemoryPackage returned FALSE.
 998     PrintDebugString("[ERROR]: getAccessibleContextFromHWND no matching HWND found!");
 999     return FALSE;
1000 }
1001 
1002 /**
1003  * Returns the HWND for an AccessibleContext.  Returns (HWND)0 on error.
1004  */
1005 HWND
1006 WinAccessBridge::getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext) {
1007     PrintDebugString("[INFO]:   in WinAccessBridge::getHWNDFromAccessibleContext");
1008     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1009         return (HWND)0;
1010     }
1011 
1012     char buffer[sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage)];
1013     PackageType *type = (PackageType *) buffer;
1014     GetHWNDFromAccessibleContextPackage *pkg = (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType));
1015     *type = cGetHWNDFromAccessibleContextPackage;
1016     pkg->accessibleContext = accessibleContext;
1017 
1018 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1019     PrintDebugString("[INFO]: WinAccessBridge::getHWNDFromAccessibleContext(%p)", accessibleContext);
1020 #else // JOBJECT64 is jlong (64 bit)
1021     PrintDebugString("[INFO]: WinAccessBridge::getHWNDFromAccessibleContext(%016I64X)", accessibleContext);
1022 #endif
1023 
1024     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1025     if (destABWindow != (HWND) 0) {
1026         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1027             return ((HWND)ABLongToHandle(pkg->rHWND));
1028         }
1029     }
1030     return (HWND)0;
1031 }
1032 
1033 /********** AccessibleContext routines ***********************************/
1034 
1035 /**
1036  * Walk through Java Windows, in front-to-back Z-order.
1037  * If NULL is passed it, this function starts at the top.
1038  *
1039  */
1040 HWND
1041 WinAccessBridge::getNextJavaWindow(HWND previous) {


1065  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1066  * of this functionality may be built into the platform
1067  *
1068  */
1069 BOOL
1070 WinAccessBridge::getAccessibleContextAt(long vmID, JOBJECT64 AccessibleContextParent,
1071                                         jint x, jint y, JOBJECT64 *AccessibleContext) {
1072     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1073         return FALSE;
1074     }
1075 
1076     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage)];
1077     PackageType *type = (PackageType *) buffer;
1078     GetAccessibleContextAtPackage *pkg = (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType));
1079     *type = cGetAccessibleContextAtPackage;
1080     pkg->vmID = vmID;
1081     pkg->AccessibleContext = AccessibleContextParent;
1082     pkg->x = x;
1083     pkg->y = y;
1084 
1085     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextAt(%X, %p, %d, %c)", vmID, AccessibleContextParent, x, y);
1086     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
1087     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1088         *AccessibleContext = pkg->rAccessibleContext;
1089         return TRUE;
1090     }
1091 
1092     return FALSE;
1093 }
1094 
1095 
1096 /**
1097  * getAccessibleContextWithFocus - performs the Java code:
1098  *   Accessible a = Translator.getAccessible(SwingEventMonitor.getComponentWithFocus());
1099  *   return a.getAccessibleContext();
1100  *
1101  * Note: this call explicitly goes through the AccessBridge,
1102  * so that the AccessBridge can hide expected changes in how this functions
1103  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1104  * of this functionality may be built into the platform
1105  *
1106  */
1107 BOOL
1108 WinAccessBridge::getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT64 *AccessibleContext) {
1109 
1110     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1111         return FALSE;
1112     }
1113     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage)];
1114     PackageType *type = (PackageType *) buffer;
1115     GetAccessibleContextWithFocusPackage *pkg = (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType));
1116     *type = cGetAccessibleContextWithFocusPackage;
1117 
1118     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID);
1119     // find vmID, etc. from HWND; ask that VM for the AC w/Focus
1120     HWND pkgVMID;
1121     if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) {
1122         HWND destABWindow = javaVMs->findAccessBridgeWindow((long)pkgVMID);     // ineffecient [[[FIXME]]]
1123         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1124             *vmID = pkg->rVMID;
1125             *AccessibleContext = pkg->rAccessibleContext;
1126             return TRUE;
1127         }
1128     }
1129 
1130     return FALSE;
1131 }
1132 
1133 /**
1134  * getAccessibleContextInfo - fills a struct with a bunch of information
1135  * contained in the Java Accessibility API
1136  *
1137  *
1138  * Note: if the AccessibleContext parameter is bogus, this call will blow up
1139  */
1140 BOOL
1141 WinAccessBridge::getAccessibleContextInfo(long vmID,
1142                                           JOBJECT64 accessibleContext,
1143                                           AccessibleContextInfo *info) {
1144     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1145         return FALSE;
1146     }
1147     char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage)];
1148     PackageType *type = (PackageType *) buffer;
1149     GetAccessibleContextInfoPackage *pkg = (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType));
1150     *type = cGetAccessibleContextInfoPackage;
1151     pkg->vmID = vmID;
1152     pkg->AccessibleContext = accessibleContext;
1153 
1154 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1155     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextInfo(%X, %p, )", vmID, accessibleContext);
1156 #else // JOBJECT64 is jlong (64 bit)
1157     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextInfo(%X, %016I64X, )", vmID, accessibleContext);
1158 #endif
1159     // need to call only the HWND/VM that contains this AC
1160     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1161     if (destABWindow != (HWND) 0) {
1162         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1163             memcpy(info, &(pkg->rAccessibleContextInfo), sizeof(AccessibleContextInfo));
1164             PrintDebugString("[INFO]:   name: %ls\n"\
1165                              "          description: %ls\n"\
1166                              "          role: %ls\n"\
1167                              "          role_en_US: %ls\n"\
1168                              "          states: %ls\n"\
1169                              "          states_en_US: %ls\n"\
1170             , info->name, info->description, info->role, info->role_en_US, info->states, info->states_en_US);
1171             return TRUE;
1172         }
1173     }
1174 
1175     return FALSE;
1176 }
1177 
1178 /**
1179  * getAccessibleChildFromContext - performs the Java code:
1180  *   Accessible child = ac.getAccessibleChild(i);
1181  *   return child.getAccessibleContext();
1182  *
1183  * Note: this call explicitly goes through the AccessBridge,
1184  * so that the AccessBridge can hide expected changes in how this functions
1185  * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some
1186  * of this functionality may be built into the platform
1187  *
1188  */
1189 JOBJECT64
1190 WinAccessBridge::getAccessibleChildFromContext(long vmID,
1191                                                JOBJECT64 AccessibleContext,
1192                                                jint childIndex) {
1193     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1194         return (JOBJECT64)0;
1195     }
1196     char buffer[sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage)];
1197     PackageType *type = (PackageType *) buffer;
1198     GetAccessibleChildFromContextPackage *pkg = (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType));
1199     *type = cGetAccessibleChildFromContextPackage;
1200     pkg->vmID = vmID;
1201     pkg->AccessibleContext = AccessibleContext;
1202     pkg->childIndex = childIndex;
1203 
1204 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1205     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleChildFromContext(%X, %p, %d)", vmID, AccessibleContext, childIndex);
1206 #else // JOBJECT64 is jlong (64 bit)
1207     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleChildFromContext(%X, %016I64X, %d)", vmID, AccessibleContext, childIndex);
1208 #endif
1209     // need to call only the HWND/VM that contains this AC
1210     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1211     if (destABWindow != (HWND) 0) {
1212         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1213             return pkg->rAccessibleContext;
1214         }
1215     }
1216 
1217     return (JOBJECT64) 0;
1218 }
1219 
1220 /**
1221  * getAccessibleParentFromContext - returns the parent AccessibleContext jobject
1222  *
1223  * Note: this may be null, if the AccessibleContext passed in is a top-level
1224  * window, then it has no parent.
1225  *
1226  */
1227 JOBJECT64
1228 WinAccessBridge::getAccessibleParentFromContext(long vmID,
1229                                                 JOBJECT64 AccessibleContext) {
1230     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1231         return (JOBJECT64)0;
1232     }
1233     char buffer[sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage)];
1234     PackageType *type = (PackageType *) buffer;
1235     GetAccessibleParentFromContextPackage *pkg = (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType));
1236     *type = cGetAccessibleParentFromContextPackage;
1237     pkg->vmID = vmID;
1238     pkg->AccessibleContext = AccessibleContext;
1239 
1240     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleParentFromContext(%X, %p)", vmID, AccessibleContext);
1241     // need to call only the HWND/VM that contains this AC
1242     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1243     if (destABWindow != (HWND) 0) {
1244         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1245             return pkg->rAccessibleContext;
1246         }
1247     }
1248 
1249     return (JOBJECT64) 0;
1250 }
1251 
1252 /********** AccessibleTable routines ***********************************/
1253 
1254 BOOL
1255 WinAccessBridge::getAccessibleTableInfo(long vmID,
1256                                         JOBJECT64 accessibleContext,
1257                                         AccessibleTableInfo *tableInfo) {
1258 
1259 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1260     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableInfo(%X, %p, %p)", vmID, accessibleContext,
1261                      tableInfo);
1262 #else // JOBJECT64 is jlong (64 bit)
1263     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableInfo(%X, %016I64X, %p)", vmID, accessibleContext,
1264                      tableInfo);
1265 #endif
1266 
1267     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1268         return FALSE;
1269     }
1270     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage)];
1271     PackageType *type = (PackageType *) buffer;
1272     GetAccessibleTableInfoPackage *pkg = (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType));
1273     *type = cGetAccessibleTableInfoPackage;
1274     pkg->vmID = vmID;
1275     pkg->accessibleContext = accessibleContext;
1276 
1277     // need to call only the HWND/VM that contains this AC
1278     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1279     if (destABWindow != (HWND) 0) {
1280         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1281             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
1282             if (pkg->rTableInfo.rowCount != -1) {
1283                 PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableInfo succeeded");
1284                 return TRUE;
1285             }
1286         }
1287     }
1288     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableInfo failed");
1289     return FALSE;
1290 }
1291 
1292 BOOL
1293 WinAccessBridge::getAccessibleTableCellInfo(long vmID, JOBJECT64 accessibleTable,
1294                                             jint row, jint column,
1295                                             AccessibleTableCellInfo *tableCellInfo) {
1296 
1297     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableCellInfo(%X, %p, %d, %d, %p)", vmID,
1298                      accessibleTable, row, column, tableCellInfo);
1299 
1300     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1301         return FALSE;
1302     }
1303 
1304     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage)];
1305     PackageType *type = (PackageType *) buffer;
1306     GetAccessibleTableCellInfoPackage *pkg = (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType));
1307     *type = cGetAccessibleTableCellInfoPackage;
1308     pkg->vmID = vmID;
1309     pkg->accessibleTable = accessibleTable;
1310     pkg->row = row;
1311     pkg->column = column;
1312     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1313 
1314     if (destABWindow != (HWND) 0) {
1315         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1316             PrintDebugString("[INFO]:   XXXX pkg->rTableCellInfo.accessibleContext = %p", pkg->rTableCellInfo.accessibleContext);
1317             memcpy(tableCellInfo, &(pkg->rTableCellInfo), sizeof(AccessibleTableCellInfo));
1318             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableCellInfo succeeded");
1319             return TRUE;
1320         }
1321     }
1322     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableCellInfo failed");
1323     return FALSE;
1324 }
1325 
1326 
1327 BOOL
1328 WinAccessBridge::getAccessibleTableRowHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) {
1329 
1330 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1331     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowHeader(%X, %p)", vmID, accessibleContext);
1332 #else // JOBJECT64 is jlong (64 bit)
1333     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowHeader(%X, %016I64X)", vmID, accessibleContext);
1334 #endif
1335 
1336     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1337         return FALSE;
1338     }
1339     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage)];
1340     PackageType *type = (PackageType *) buffer;
1341     GetAccessibleTableRowHeaderPackage *pkg = (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType));
1342     *type = cGetAccessibleTableRowHeaderPackage;
1343     pkg->vmID = vmID;
1344     pkg->accessibleContext = accessibleContext;
1345 
1346     // need to call only the HWND/VM that contains this AC
1347     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1348     if (destABWindow != (HWND) 0) {
1349         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1350             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowHeader succeeded");
1351             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
1352             return TRUE;
1353         }
1354     }
1355     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowHeader failed");
1356     return FALSE;
1357 }
1358 
1359 BOOL
1360 WinAccessBridge::getAccessibleTableColumnHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) {
1361 
1362 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1363     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %p)", vmID, accessibleContext);
1364 #else // JOBJECT64 is jlong (64 bit)
1365     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %016I64X)", vmID, accessibleContext);
1366 #endif
1367 
1368     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1369         return FALSE;
1370     }
1371     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage)];
1372     PackageType *type = (PackageType *) buffer;
1373     GetAccessibleTableColumnHeaderPackage *pkg = (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType));
1374     *type = cGetAccessibleTableColumnHeaderPackage;
1375     pkg->vmID = vmID;
1376     pkg->accessibleContext = accessibleContext;
1377 
1378     // need to call only the HWND/VM that contains this AC
1379     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1380     if (destABWindow != (HWND) 0) {
1381         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1382             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnHeader succeeded");
1383             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
1384             return TRUE;
1385         }
1386     }
1387     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnHeader failed");
1388     return FALSE;
1389 }
1390 
1391 JOBJECT64
1392 WinAccessBridge::getAccessibleTableRowDescription(long vmID,
1393                                                   JOBJECT64 accessibleContext,
1394                                                   jint row) {
1395 
1396 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1397     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowDescription(%X, %p, %d)", vmID, accessibleContext,
1398                      row);
1399 #else // JOBJECT64 is jlong (64 bit)
1400     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowDescription(%X, %016I64X, %d)", vmID, accessibleContext,
1401                      row);
1402 #endif
1403 
1404     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1405         return FALSE;
1406     }
1407     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage)];
1408     PackageType *type = (PackageType *) buffer;
1409     GetAccessibleTableRowDescriptionPackage *pkg = (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType));
1410     *type = cGetAccessibleTableRowDescriptionPackage;
1411     pkg->vmID = vmID;
1412     pkg->row = row;
1413     pkg->accessibleContext = accessibleContext;
1414 
1415     // need to call only the HWND/VM that contains this AC
1416     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1417     if (destABWindow != (HWND) 0) {
1418         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1419             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowDescription succeeded");
1420             return pkg->rAccessibleContext;
1421         }
1422     }
1423     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowDescription failed");
1424     return (JOBJECT64)0;
1425 }
1426 
1427 JOBJECT64
1428 WinAccessBridge::getAccessibleTableColumnDescription(long vmID,
1429                                                      JOBJECT64 accessibleContext,
1430                                                      jint column) {
1431 
1432 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1433     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %p, %d)", vmID, accessibleContext,
1434                      column);
1435 #else // JOBJECT64 is jlong (64 bit)
1436     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %016I64X, %d)", vmID, accessibleContext,
1437                      column);
1438 #endif
1439 
1440     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1441         return FALSE;
1442     }
1443     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage)];
1444     PackageType *type = (PackageType *) buffer;
1445     GetAccessibleTableColumnDescriptionPackage *pkg =
1446         (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType));
1447     *type = cGetAccessibleTableColumnDescriptionPackage;
1448     pkg->vmID = vmID;
1449     pkg->column = column;
1450     pkg->accessibleContext = accessibleContext;
1451 
1452     // need to call only the HWND/VM that contains this AC
1453     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1454     if (destABWindow != (HWND) 0) {
1455         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1456             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnDescription succeeded");
1457             return pkg->rAccessibleContext;
1458         }
1459     }
1460     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnDescription failed");
1461     return (JOBJECT64)0;
1462 }
1463 
1464 jint
1465 WinAccessBridge::getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable) {
1466 
1467 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1468     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %p)", vmID, accessibleTable);
1469 #else // JOBJECT64 is jlong (64 bit)
1470     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %016I64X)", vmID, accessibleTable);
1471 #endif
1472 
1473     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1474         return 0;
1475     }
1476     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage)];
1477     PackageType *type = (PackageType *) buffer;
1478     GetAccessibleTableRowSelectionCountPackage *pkg =
1479         (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType));
1480     *type = cGetAccessibleTableRowSelectionCountPackage;
1481     pkg->vmID = vmID;
1482     pkg->accessibleTable = accessibleTable;
1483 
1484     // need to call only the HWND/VM that contains this AC
1485     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1486     if (destABWindow != (HWND) 0) {
1487         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1488             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowSelectionCount succeeded");
1489             return pkg->rCount;
1490         }
1491     }
1492     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowSelectionCount failed");
1493     return 0;
1494 }
1495 
1496 BOOL
1497 WinAccessBridge::isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row) {
1498 
1499 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1500     PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableRowSelected(%X, %p)", vmID, accessibleTable);
1501 #else // JOBJECT64 is jlong (64 bit)
1502     PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableRowSelected(%X, %016I64X)", vmID, accessibleTable);
1503 #endif
1504 
1505     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1506         return FALSE;
1507     }
1508     char buffer[sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage)];
1509     PackageType *type = (PackageType *) buffer;
1510     IsAccessibleTableRowSelectedPackage *pkg = (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType));
1511     *type = cIsAccessibleTableRowSelectedPackage;
1512     pkg->vmID = vmID;
1513     pkg->accessibleTable = accessibleTable;
1514     pkg->row = row;
1515 
1516     // need to call only the HWND/VM that contains this AC
1517     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1518     if (destABWindow != (HWND) 0) {
1519         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1520             PrintDebugString("[INFO]:   ##### WinAccessBridge::isAccessibleTableRowSelected succeeded");
1521             return pkg->rResult;
1522         }
1523     }
1524     PrintDebugString("[ERROR]:   ##### WinAccessBridge::isAccessibleTableRowSelected failed");
1525     return FALSE;
1526 }
1527 
1528 BOOL
1529 WinAccessBridge::getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, jint *selections) {
1530 
1531 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1532     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelections(%X, %p)", vmID, accessibleTable);
1533 #else // JOBJECT64 is jlong (64 bit)
1534     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelections(%X, %016I64X)", vmID, accessibleTable);
1535 #endif
1536 
1537     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1538         return FALSE;
1539     }
1540     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage)];
1541     PackageType *type = (PackageType *) buffer;
1542     GetAccessibleTableRowSelectionsPackage *pkg =
1543         (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType));
1544     *type = cGetAccessibleTableRowSelectionsPackage;
1545     pkg->vmID = vmID;
1546     pkg->accessibleTable = accessibleTable;
1547     pkg->count = count;
1548 
1549     // need to call only the HWND/VM that contains this AC
1550     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1551     if (destABWindow != (HWND) 0) {
1552         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1553             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowSelections succeeded");
1554             memcpy(selections, pkg->rSelections, count * sizeof(jint));
1555             return TRUE;
1556         }
1557     }
1558     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowSelections failed");
1559     return FALSE;
1560 }
1561 
1562 
1563 jint
1564 WinAccessBridge::getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable) {
1565 
1566 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1567     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %p)", vmID,
1568                      accessibleTable);
1569 #else // JOBJECT64 is jlong (64 bit)
1570     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %016I64X)", vmID,
1571                      accessibleTable);
1572 #endif
1573 
1574     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1575         return FALSE;
1576     }
1577     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage)];
1578     PackageType *type = (PackageType *) buffer;
1579     GetAccessibleTableColumnSelectionCountPackage *pkg =
1580         (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType));
1581     *type = cGetAccessibleTableColumnSelectionCountPackage;
1582     pkg->vmID = vmID;
1583     pkg->accessibleTable = accessibleTable;
1584 
1585     // need to call only the HWND/VM that contains this AC
1586     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1587     if (destABWindow != (HWND) 0) {
1588         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1589             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnSelectionCount succeeded");
1590             return pkg->rCount;
1591         }
1592     }
1593     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnSelectionCount failed");
1594     return 0;
1595 }
1596 
1597 BOOL
1598 WinAccessBridge::isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column) {
1599 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1600     PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %p)", vmID, accessibleTable);
1601 #else // JOBJECT64 is jlong (64 bit)
1602     PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %016I64X)", vmID, accessibleTable);
1603 #endif
1604 
1605     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1606         return FALSE;
1607     }
1608     char buffer[sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage)];
1609     PackageType *type = (PackageType *) buffer;
1610     IsAccessibleTableColumnSelectedPackage *pkg = (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType));
1611     *type = cIsAccessibleTableColumnSelectedPackage;
1612     pkg->vmID = vmID;
1613     pkg->accessibleTable = accessibleTable;
1614     pkg->column = column;
1615 
1616     // need to call only the HWND/VM that contains this AC
1617     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1618     if (destABWindow != (HWND) 0) {
1619         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1620             PrintDebugString("[INFO]:   ##### WinAccessBridge::isAccessibleTableColumnSelected succeeded");
1621             return pkg->rResult;
1622         }
1623     }
1624     PrintDebugString("[ERROR]:   ##### WinAccessBridge::isAccessibleTableColumnSelected failed");
1625     return FALSE;
1626 }
1627 
1628 BOOL
1629 WinAccessBridge::getAccessibleTableColumnSelections(long vmID, JOBJECT64 accessibleTable, jint count,
1630                                                     jint *selections) {
1631 
1632 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1633     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %p)", vmID, accessibleTable);
1634 #else // JOBJECT64 is jlong (64 bit)
1635     PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %016I64X)", vmID, accessibleTable);
1636 #endif
1637 
1638     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1639         return FALSE;
1640     }
1641     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage)];
1642     PackageType *type = (PackageType *) buffer;
1643     GetAccessibleTableColumnSelectionsPackage *pkg =
1644         (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType));
1645     *type = cGetAccessibleTableColumnSelectionsPackage;
1646     pkg->vmID = vmID;
1647     pkg->count = count;
1648     pkg->accessibleTable = accessibleTable;
1649 
1650     // need to call only the HWND/VM that contains this AC
1651     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1652     if (destABWindow != (HWND) 0) {
1653         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1654             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnSelections succeeded");
1655             memcpy(selections, pkg->rSelections, count * sizeof(jint));
1656             return TRUE;
1657         }
1658     }
1659     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnSelections failed");
1660     return FALSE;
1661 }
1662 
1663 jint
1664 WinAccessBridge::getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index) {
1665 
1666 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1667     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRow(%X, %p, index=%d)", vmID,
1668                      accessibleTable, index);
1669 #else // JOBJECT64 is jlong (64 bit)
1670     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRow(%X, %016I64X, index=%d)", vmID,
1671                      accessibleTable, index);
1672 #endif
1673 
1674     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1675         return FALSE;
1676     }
1677     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage)];
1678     PackageType *type = (PackageType *) buffer;
1679     GetAccessibleTableRowPackage *pkg =
1680         (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType));
1681     *type = cGetAccessibleTableRowPackage;
1682     pkg->vmID = vmID;
1683     pkg->accessibleTable = accessibleTable;
1684     pkg->index = index;
1685 
1686     // need to call only the HWND/VM that contains this AC
1687     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1688     if (destABWindow != (HWND) 0) {
1689         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1690             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRow succeeded");
1691             return pkg->rRow;
1692         }
1693     }
1694     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRow failed");
1695     return 0;
1696 }
1697 
1698 jint
1699 WinAccessBridge::getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index) {
1700 
1701 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1702     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumn(%X, %p, index=%d)", vmID,
1703                      accessibleTable, index);
1704 #else // JOBJECT64 is jlong (64 bit)
1705     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumn(%X, %016I64X, index=%d)", vmID,
1706                      accessibleTable, index);
1707 #endif
1708 
1709     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1710         return FALSE;
1711     }
1712     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage)];
1713     PackageType *type = (PackageType *) buffer;
1714     GetAccessibleTableColumnPackage *pkg =
1715         (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType));
1716     *type = cGetAccessibleTableColumnPackage;
1717     pkg->vmID = vmID;
1718     pkg->accessibleTable = accessibleTable;
1719     pkg->index = index;
1720 
1721     // need to call only the HWND/VM that contains this AC
1722     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1723     if (destABWindow != (HWND) 0) {
1724         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1725             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumn succeeded");
1726             return pkg->rColumn;
1727         }
1728     }
1729     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumn failed");
1730     return 0;
1731 }
1732 
1733 jint
1734 WinAccessBridge::getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column) {
1735 
1736 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1737     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableIndex(%X, %p, row=%d, col=%d)", vmID,
1738                      accessibleTable, row, column);
1739 #else // JOBJECT64 is jlong (64 bit)
1740     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableIndex(%X, %016I64X, row=%d, col=%d)", vmID,
1741                      accessibleTable, row, column);
1742 #endif
1743 
1744     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1745         return FALSE;
1746     }
1747     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage)];
1748     PackageType *type = (PackageType *) buffer;
1749     GetAccessibleTableIndexPackage *pkg =
1750         (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType));
1751     *type = cGetAccessibleTableIndexPackage;
1752     pkg->vmID = vmID;
1753     pkg->accessibleTable = accessibleTable;
1754     pkg->row = row;
1755     pkg->column = column;
1756 
1757     // need to call only the HWND/VM that contains this AC
1758     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1759     if (destABWindow != (HWND) 0) {
1760         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1761             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableIndex succeeded");
1762             return pkg->rIndex;
1763         }
1764     }
1765     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableIndex failed");
1766     return 0;
1767 }
1768 
1769 /********** end AccessibleTable routines ******************************/
1770 
1771 BOOL
1772 WinAccessBridge::getAccessibleRelationSet(long vmID, JOBJECT64 accessibleContext,
1773                                           AccessibleRelationSetInfo *relationSetInfo) {
1774 
1775 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1776     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleRelationSet(%X, %p, %X)", vmID,
1777                      accessibleContext, relationSetInfo);
1778 #else // JOBJECT64 is jlong (64 bit)
1779     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleRelationSet(%X, %016I64X, %X)", vmID,
1780                      accessibleContext, relationSetInfo);
1781 #endif
1782 
1783     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1784         return FALSE;
1785     }
1786 
1787     char buffer[sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage)];
1788     PackageType *type = (PackageType *) buffer;
1789     GetAccessibleRelationSetPackage *pkg = (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType));
1790     *type = cGetAccessibleRelationSetPackage;
1791     pkg->vmID = vmID;
1792     pkg->accessibleContext = accessibleContext;
1793 
1794     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1795     if (destABWindow != (HWND) 0) {
1796         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1797             PrintDebugString("[INFO]:   ##### pkg->rAccessibleRelationSetInfo.relationCount = %X",
1798                              pkg->rAccessibleRelationSetInfo.relationCount);
1799             memcpy(relationSetInfo, &(pkg->rAccessibleRelationSetInfo), sizeof(AccessibleRelationSetInfo));
1800             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleRelationSet succeeded");
1801             return TRUE;
1802         }
1803     }
1804     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleRelationSet failed");
1805     return FALSE;
1806 }
1807 
1808 
1809 /********** AccessibleHypertext routines ***********/
1810 
1811 BOOL
1812 WinAccessBridge::getAccessibleHypertext(long vmID, JOBJECT64 accessibleContext,
1813                                         AccessibleHypertextInfo *hypertextInfo) {
1814 
1815 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1816     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertext(%X, %p, %X)", vmID,
1817                      accessibleContext, hypertextInfo);
1818 #else // JOBJECT64 is jlong (64 bit)
1819     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertext(%X, %016I64X, %X)", vmID,
1820                      accessibleContext, hypertextInfo);
1821 #endif
1822 
1823     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1824         return FALSE;
1825     }
1826 
1827     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage)];
1828     PackageType *type = (PackageType *) buffer;
1829     GetAccessibleHypertextPackage *pkg = (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType));
1830     *type = cGetAccessibleHypertextPackage;
1831     pkg->vmID = vmID;
1832     pkg->accessibleContext = accessibleContext;
1833 
1834     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1835     if (destABWindow != (HWND) 0) {
1836         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1837             memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo));
1838 
1839             PrintDebugString("[INFO]:   ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);
1840             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleHypertext succeeded");
1841 
1842             return TRUE;
1843         }
1844     }
1845     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHypertext failed");
1846     return FALSE;
1847 }
1848 
1849 
1850 BOOL
1851 WinAccessBridge::activateAccessibleHyperlink(long vmID, JOBJECT64 accessibleContext,
1852                                              JOBJECT64 accessibleHyperlink) {
1853 
1854 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1855     PrintDebugString("[INFO]: WinAccessBridge::activateAccessibleHyperlink(%p %p)", accessibleContext,
1856                      accessibleHyperlink);
1857 #else // JOBJECT64 is jlong (64 bit)
1858     PrintDebugString("[INFO]: WinAccessBridge::activateAccessibleHyperlink(%016I64X %016I64X)", accessibleContext,
1859                      accessibleHyperlink);
1860 #endif
1861 
1862     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1863         return FALSE;
1864     }
1865 
1866     char buffer[sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage)];
1867     PackageType *type = (PackageType *) buffer;
1868     ActivateAccessibleHyperlinkPackage *pkg = (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
1869     *type = cActivateAccessibleHyperlinkPackage;
1870     pkg->vmID = vmID;
1871     pkg->accessibleContext = accessibleContext;
1872     pkg->accessibleHyperlink = accessibleHyperlink;
1873 
1874     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
1875     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1876         return pkg->rResult;
1877     }
1878     PrintDebugString("[ERROR]:  WinAccessBridge::activateAccessibleHyperlink returning FALSE (sendMemoryPackage failed)");
1879     return FALSE;
1880 }
1881 
1882 /*
1883  * Returns the number of hyperlinks in a component
1884  * Maps to AccessibleHypertext.getLinkCount.
1885  * Returns -1 on error.
1886  */
1887 jint
1888 WinAccessBridge::getAccessibleHyperlinkCount(const long vmID,
1889                                              const AccessibleContext accessibleContext) {
1890 
1891 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1892     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %p)",
1893                      vmID, accessibleContext);
1894 #else // JOBJECT64 is jlong (64 bit)
1895     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %016I64X)",
1896                      vmID, accessibleContext);
1897 #endif
1898 
1899     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1900         return FALSE;
1901     }
1902 
1903     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage)];
1904     PackageType *type = (PackageType *) buffer;
1905     GetAccessibleHyperlinkCountPackage *pkg = (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType));
1906     *type = cGetAccessibleHyperlinkCountPackage;
1907     pkg->vmID = vmID;
1908     pkg->accessibleContext = accessibleContext;
1909 
1910     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1911     if (destABWindow != (HWND) 0) {
1912         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1913             PrintDebugString("[INFO]:   ##### hypetext link count = %d", pkg->rLinkCount);
1914             PrintDebugString("[INFO]:  ##### WinAccessBridge::getAccessibleHyperlinkCount succeeded");
1915             return pkg->rLinkCount;
1916         }
1917     }
1918     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHyperlinkCount failed");
1919     return -1;
1920 }
1921 
1922 /*
1923  * This method is used to iterate through the hyperlinks in a component.  It
1924  * returns hypertext information for a component starting at hyperlink index
1925  * nStartIndex.  No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will
1926  * be returned for each call to this method.
1927  * returns FALSE on error.
1928  */
1929 BOOL
1930 WinAccessBridge::getAccessibleHypertextExt(const long vmID,
1931                                            const AccessibleContext accessibleContext,
1932                                            const jint startIndex,
1933                                            /* OUT */ AccessibleHypertextInfo *hypertextInfo) {
1934 
1935 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1936     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextExt(%X, %p %p)", vmID,
1937                      accessibleContext, hypertextInfo);
1938 #else // JOBJECT64 is jlong (64 bit)
1939     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextExt(%X, %016I64X %p)", vmID,
1940                      accessibleContext, hypertextInfo);
1941 #endif
1942 
1943     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1944         return FALSE;
1945     }
1946 
1947     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage)];
1948     PackageType *type = (PackageType *) buffer;
1949     GetAccessibleHypertextExtPackage *pkg = (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType));
1950     *type = cGetAccessibleHypertextExtPackage;
1951     pkg->vmID = vmID;
1952     pkg->accessibleContext = accessibleContext;
1953     pkg->startIndex = startIndex;
1954 
1955     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
1956     if (destABWindow != (HWND) 0) {
1957         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
1958             PrintDebugString("[INFO]:   ##### pkg->rSuccess = %d", pkg->rSuccess);
1959 
1960             memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo));
1961             if (pkg->rSuccess == TRUE) {
1962                 PrintDebugString("[INFO]:   ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);

1963             } else {
1964                 PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHypertextExt failed");
1965             }
1966             return pkg->rSuccess;
1967         }
1968     }
1969     PrintDebugString("[ERROR]:  ##### WinAccessBridge::getAccessibleHypertextExt failed");
1970     return FALSE;
1971 }
1972 
1973 
1974 /*
1975  * Returns the index into an array of hyperlinks that is associated with
1976  * a character index in document;
1977  * Maps to AccessibleHypertext.getLinkIndex.
1978  * Returns -1 on error.
1979  */
1980 jint
1981 WinAccessBridge::getAccessibleHypertextLinkIndex(const long vmID,
1982                                                  const AccessibleHyperlink hypertext,
1983                                                  const jint charIndex) {
1984 
1985 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1986     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %p)",
1987                      vmID, hypertext);
1988 #else // JOBJECT64 is jlong (64 bit)
1989     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %016I64X)",
1990                      vmID, hypertext);
1991 #endif
1992 
1993     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
1994         return FALSE;
1995     }
1996 
1997     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage)];
1998     PackageType *type = (PackageType *) buffer;
1999     GetAccessibleHypertextLinkIndexPackage *pkg = (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType));
2000     *type = cGetAccessibleHypertextLinkIndexPackage;
2001     pkg->vmID = vmID;
2002     pkg->hypertext = hypertext;
2003     pkg->charIndex = charIndex;
2004 
2005     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2006     if (destABWindow != (HWND) 0) {
2007         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2008             PrintDebugString("[INFO]:   ##### hypetext link index = %d", pkg->rLinkIndex);
2009             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleHypertextLinkIndex  succeeded");
2010             return pkg->rLinkIndex;
2011         }
2012     }
2013     PrintDebugString("[ERROR]  ##### WinAccessBridge::getAccessibleHypertextLinkIndex  failed");
2014     return -1;
2015 }
2016 
2017 /*
2018  * Returns the nth hyperlink in a document.
2019  * Maps to AccessibleHypertext.getLink.
2020  * Returns -1 on error
2021  */
2022 BOOL
2023 WinAccessBridge::getAccessibleHyperlink(const long vmID,
2024                                         const AccessibleHyperlink hypertext,
2025                                         const jint linkIndex,
2026                                         /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) {
2027 
2028 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2029     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlink(%X, %p, %p)", vmID,
2030                      hypertext, hyperlinkInfo);
2031 #else // JOBJECT64 is jlong (64 bit)
2032     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlink(%X, %016I64X, %p)", vmID,
2033                      hypertext, hyperlinkInfo);
2034 #endif
2035 
2036     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2037         return FALSE;
2038     }
2039 
2040     char buffer[sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage)];
2041     PackageType *type = (PackageType *) buffer;
2042     GetAccessibleHyperlinkPackage *pkg = (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
2043     *type = cGetAccessibleHyperlinkPackage;
2044     pkg->vmID = vmID;
2045     pkg->hypertext = hypertext;
2046     pkg->linkIndex = linkIndex;
2047 
2048     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2049     if (destABWindow != (HWND) 0) {
2050         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2051             memcpy(hyperlinkInfo, &(pkg->rAccessibleHyperlinkInfo),
2052                    sizeof(AccessibleHyperlinkInfo));
2053             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleHypertext succeeded");
2054             return TRUE;
2055         }
2056     }
2057     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHypertext failed");
2058     return FALSE;
2059 }
2060 
2061 
2062 /********** AccessibleKeyBinding routines ***********/
2063 
2064 BOOL
2065 WinAccessBridge::getAccessibleKeyBindings(long vmID, JOBJECT64 accessibleContext,
2066                                           AccessibleKeyBindings *keyBindings) {
2067 
2068 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2069     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleKeyBindings(%X, %p, %p)", vmID,
2070                      accessibleContext, keyBindings);
2071 #else // JOBJECT64 is jlong (64 bit)
2072     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleKeyBindings(%X, %016I64X, %p)", vmID,
2073                      accessibleContext, keyBindings);
2074 #endif
2075 
2076     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2077         return FALSE;
2078     }
2079 
2080     char buffer[sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage)];
2081     PackageType *type = (PackageType *) buffer;
2082     GetAccessibleKeyBindingsPackage *pkg = (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType));
2083     *type = cGetAccessibleKeyBindingsPackage;
2084     pkg->vmID = vmID;
2085     pkg->accessibleContext = accessibleContext;
2086 
2087     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2088     if (destABWindow != (HWND) 0) {
2089         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2090             memcpy(keyBindings, &(pkg->rAccessibleKeyBindings), sizeof(AccessibleKeyBindings));
2091 
2092             PrintDebugString("[INFO]:   ##### keyBindings.keyBindingsCount = %d", keyBindings->keyBindingsCount);
2093             for (int i = 0; i < keyBindings->keyBindingsCount; ++i) {
2094                 PrintDebugString("[INFO]:   Key Binding # %d"\
2095                 "                           Modifiers: 0x%x"\
2096                 "                           Character (hex):  0x%x"\
2097                 "                           Character (wide char):  %lc"\
2098                 , i+1, keyBindings->keyBindingInfo[i].modifiers, keyBindings->keyBindingInfo[i].character, keyBindings->keyBindingInfo[i].character);
2099             }
2100             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleKeyBindings succeeded");
2101 
2102             return TRUE;
2103         }
2104     }
2105     PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleKeyBindings failed");
2106     return FALSE;
2107 }
2108 
2109 BOOL
2110 WinAccessBridge::getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, AccessibleIcons *icons) {
2111 
2112 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2113     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleIcons(%X, %p, %p)", vmID,
2114                      accessibleContext, icons);
2115 #else // JOBJECT64 is jlong (64 bit)
2116     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleIcons(%X, %016I64X, %p)", vmID,
2117                      accessibleContext, icons);
2118 #endif
2119 
2120     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2121         return FALSE;
2122     }
2123 
2124     char buffer[sizeof(PackageType) + sizeof(GetAccessibleIconsPackage)];
2125     PackageType *type = (PackageType *) buffer;
2126     GetAccessibleIconsPackage *pkg = (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType));
2127     *type = cGetAccessibleIconsPackage;
2128     pkg->vmID = vmID;
2129     pkg->accessibleContext = accessibleContext;
2130 
2131     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2132     if (destABWindow != (HWND) 0) {
2133         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2134             memcpy(icons, &(pkg->rAccessibleIcons), sizeof(AccessibleIcons));
2135 
2136             PrintDebugString("[INFO]:   ##### icons.iconsCount = %d", icons->iconsCount);
2137             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleIcons succeeded");
2138 
2139             return TRUE;
2140         }
2141     }
2142     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleIcons failed");
2143     return FALSE;
2144 }
2145 
2146 BOOL
2147 WinAccessBridge::getAccessibleActions(long vmID, JOBJECT64 accessibleContext, AccessibleActions *actions) {
2148 
2149 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2150     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleActions(%X, %p, %p)", vmID,
2151                      accessibleContext, actions);
2152 #else // JOBJECT64 is jlong (64 bit)
2153     PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleActions(%X, %016I64X, %p)", vmID,
2154                      accessibleContext, actions);
2155 #endif
2156 
2157     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2158         return FALSE;
2159     }
2160 
2161     char buffer[sizeof(PackageType) + sizeof(GetAccessibleActionsPackage)];
2162     PackageType *type = (PackageType *) buffer;
2163     GetAccessibleActionsPackage *pkg = (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType));
2164     *type = cGetAccessibleActionsPackage;
2165     pkg->vmID = vmID;
2166     pkg->accessibleContext = accessibleContext;
2167 
2168     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2169     if (destABWindow != (HWND) 0) {
2170         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2171             memcpy(actions, &(pkg->rAccessibleActions), sizeof(AccessibleActions));
2172 
2173             PrintDebugString("[INFO]:   ##### actions.actionsCount = %d", actions->actionsCount);
2174             PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleActions succeeded");
2175 
2176             return TRUE;
2177         }
2178     }
2179     PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleActions failed");
2180     return FALSE;
2181 }
2182 
2183 BOOL
2184 WinAccessBridge::doAccessibleActions(long vmID, JOBJECT64 accessibleContext,
2185                                      AccessibleActionsToDo *actionsToDo, jint *failure) {
2186 
2187 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2188     PrintDebugString("[INFO]: WinAccessBridge::doAccessibleActions(%p #actions %d %ls)", accessibleContext,
2189                      actionsToDo->actionsCount,
2190                      actionsToDo->actions[0].name);
2191 #else // JOBJECT64 is jlong (64 bit)
2192     PrintDebugString("[INFO]: WinAccessBridge::doAccessibleActions(%016I64X #actions %d %ls)", accessibleContext,
2193                      actionsToDo->actionsCount,
2194                      actionsToDo->actions[0].name);
2195 #endif
2196 
2197     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2198         return FALSE;
2199     }
2200     char buffer[sizeof(PackageType) + sizeof(DoAccessibleActionsPackage)];
2201     PackageType *type = (PackageType *) buffer;
2202     DoAccessibleActionsPackage *pkg = (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType));
2203     *type = cDoAccessibleActionsPackage;
2204     pkg->vmID = vmID;
2205     pkg->accessibleContext = accessibleContext;
2206     memcpy((void *)(&(pkg->actionsToDo)), (void *)actionsToDo, sizeof(AccessibleActionsToDo));
2207     pkg->failure = -1;
2208 
2209     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
2210     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2211         *failure = pkg->failure;
2212         return pkg->rResult;
2213     }
2214     PrintDebugString("[ERROR]:   WinAccessBridge::doAccessibleActions returning FALSE (sendMemoryPackage failed)");
2215     return FALSE;
2216 }
2217 
2218 /* ====== Utility methods ====== */
2219 
2220 /**
2221  * Sets a text field to the specified string. Returns whether successful.
2222  */
2223 BOOL
2224 WinAccessBridge::setTextContents (const long vmID, const AccessibleContext accessibleContext,
2225                                   const wchar_t *text) {
2226 
2227     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2228         return FALSE;
2229     }
2230     char buffer[sizeof(PackageType) + sizeof(SetTextContentsPackage)];
2231     PackageType *type = (PackageType *) buffer;
2232     SetTextContentsPackage *pkg = (SetTextContentsPackage *) (buffer + sizeof(PackageType));
2233     *type = cSetTextContentsPackage;
2234     pkg->vmID = vmID;
2235     pkg->accessibleContext = accessibleContext;
2236     wcsncpy(pkg->text, text, sizeof(pkg->text)/sizeof(wchar_t)); // wide character copy
2237 
2238 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2239     PrintDebugString("[INFO]: WinAccessBridge::setTextContents(%X, %016I64X %ls)", vmID, accessibleContext, text);
2240 #else // JOBJECT64 is jlong (64 bit)
2241     PrintDebugString("[INFO]: WinAccessBridge::setTextContents(%X, %p %ls)", vmID, accessibleContext, text);
2242 #endif
2243     // need to call only the HWND/VM that contains this AC
2244     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2245     if (destABWindow != (HWND) 0) {
2246         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2247             return pkg->rResult;
2248         }
2249     }
2250     return FALSE;
2251 }
2252 
2253 /**
2254  * Returns the Accessible Context of a Page Tab object that is the
2255  * ancestor of a given object.  If the object is a Page Tab object
2256  * or a Page Tab ancestor object was found, returns the object
2257  * AccessibleContext.
2258  * If there is no ancestor object that has an Accessible Role of Page Tab,
2259  * returns (AccessibleContext)0.
2260  */
2261 AccessibleContext
2262 WinAccessBridge::getParentWithRole (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) {
2263 
2264     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2265         return (JOBJECT64)0;
2266     }
2267     char buffer[sizeof(PackageType) + sizeof(GetParentWithRolePackage)];
2268     PackageType *type = (PackageType *) buffer;
2269     GetParentWithRolePackage *pkg = (GetParentWithRolePackage *) (buffer + sizeof(PackageType));
2270     *type = cGetParentWithRolePackage;
2271     pkg->vmID = vmID;
2272     pkg->accessibleContext = accessibleContext;
2273     memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role));
2274 
2275 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2276     PrintDebugString("[INFO]: WinAccessBridge::getParentWithRole(%X, %p)", vmID, accessibleContext);
2277 #else // JOBJECT64 is jlong (64 bit)
2278     PrintDebugString("[INFO]: WinAccessBridge::getParentWithRole(%X, %016I64X)", vmID, accessibleContext);
2279 #endif
2280     PrintDebugString("[INFO]:   pkg->vmID: %X"\
2281                      "          pkg->accessibleContext: %p"\
2282                      "          pkg->role: %ls"\
2283                      , pkg->vmID, pkg->accessibleContext, pkg->role);
2284     // need to call only the HWND/VM that contains this AC
2285     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2286     if (destABWindow != (HWND) 0) {
2287         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2288             PrintDebugString("[INFO]:   pkg->rAccessibleContext: %p", pkg->rAccessibleContext);
2289             return pkg->rAccessibleContext;
2290         }
2291     }
2292     return (JOBJECT64) 0;
2293 }
2294 
2295 
2296 /**
2297  * Returns the Accessible Context for the top level object in
2298  * a Java Window.  This is same Accessible Context that is obtained
2299  * from GetAccessibleContextFromHWND for that window.  Returns
2300  * (AccessibleContext)0 on error.
2301  */
2302 AccessibleContext
2303 WinAccessBridge::getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) {
2304 
2305     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2306         return (JOBJECT64)0;
2307     }
2308     char buffer[sizeof(PackageType) + sizeof(GetTopLevelObjectPackage)];
2309     PackageType *type = (PackageType *) buffer;
2310     GetTopLevelObjectPackage *pkg = (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType));
2311     *type = cGetTopLevelObjectPackage;
2312     pkg->vmID = vmID;
2313     pkg->accessibleContext = accessibleContext;
2314 
2315 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2316     PrintDebugString("[INFO]: WinAccessBridge::getTopLevelObject(%X, %p)", vmID, accessibleContext);
2317 #else // JOBJECT64 is jlong (64 bit)
2318     PrintDebugString("[INFO]: WinAccessBridge::getTopLevelObject(%X, %016I64X)", vmID, accessibleContext);
2319 #endif
2320     // need to call only the HWND/VM that contains this AC
2321     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2322     if (destABWindow != (HWND) 0) {
2323         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2324             return pkg->rAccessibleContext;
2325         }
2326     }
2327     return (JOBJECT64) 0;
2328 }
2329 
2330 /**
2331  * If there is an Ancestor object that has an Accessible Role of
2332  * Internal Frame, returns the Accessible Context of the Internal
2333  * Frame object.  Otherwise, returns the top level object for that
2334  * Java Window.  Returns (AccessibleContext)0 on error.
2335  */
2336 AccessibleContext
2337 WinAccessBridge::getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) {
2338 
2339     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2340         return (JOBJECT64)0;
2341     }
2342     char buffer[sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage)];
2343     PackageType *type = (PackageType *) buffer;
2344     GetParentWithRoleElseRootPackage *pkg = (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType));
2345     *type = cGetParentWithRoleElseRootPackage;
2346     pkg->vmID = vmID;
2347     pkg->accessibleContext = accessibleContext;
2348     memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role));
2349 
2350 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2351     PrintDebugString("[INFO]: WinAccessBridge::getParentWithRoleElseRoot(%X, %p)", vmID, accessibleContext);
2352 #else // JOBJECT64 is jlong (64 bit)
2353     PrintDebugString("[INFO]: WinAccessBridge::getParentWithRoleElseRoot(%X, %016I64X)", vmID, accessibleContext);
2354 #endif
2355     // need to call only the HWND/VM that contains this AC
2356     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2357     if (destABWindow != (HWND) 0) {
2358         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2359             return pkg->rAccessibleContext;
2360         }
2361     }
2362     return (JOBJECT64) 0;
2363 }
2364 
2365 /**
2366  * Returns how deep in the object hierarchy a given object is.
2367  * The top most object in the object hierarchy has an object depth of 0.
2368  * Returns -1 on error.
2369  */
2370 int
2371 WinAccessBridge::getObjectDepth (const long vmID, const AccessibleContext accessibleContext) {
2372 
2373     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2374         return -1;
2375     }
2376     char buffer[sizeof(PackageType) + sizeof(GetObjectDepthPackage)];
2377     PackageType *type = (PackageType *) buffer;
2378     GetObjectDepthPackage *pkg = (GetObjectDepthPackage *) (buffer + sizeof(PackageType));
2379     *type = cGetObjectDepthPackage;
2380     pkg->vmID = vmID;
2381     pkg->accessibleContext = accessibleContext;
2382 
2383 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2384     PrintDebugString("[INFO]: WinAccessBridge::getObjectDepth(%X, %p)", vmID, accessibleContext);
2385 #else // JOBJECT64 is jlong (64 bit)
2386     PrintDebugString("[INFO]: WinAccessBridge::getObjectDepth(%X, %016I64X)", vmID, accessibleContext);
2387 #endif
2388     // need to call only the HWND/VM that contains this AC
2389     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2390     if (destABWindow != (HWND) 0) {
2391         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2392             return pkg->rResult;
2393         }
2394     }
2395     return -1;
2396 }
2397 
2398 /**
2399  * Returns the Accessible Context of the currently ActiveDescendent of an object.
2400  * Returns (AccessibleContext)0 on error.
2401  */
2402 AccessibleContext
2403 WinAccessBridge::getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) {
2404 
2405     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2406         return (JOBJECT64)0;
2407     }
2408     char buffer[sizeof(PackageType) + sizeof(GetActiveDescendentPackage)];
2409     PackageType *type = (PackageType *) buffer;
2410     GetActiveDescendentPackage *pkg = (GetActiveDescendentPackage *) (buffer + sizeof(PackageType));
2411     *type = cGetActiveDescendentPackage;
2412     pkg->vmID = vmID;
2413     pkg->accessibleContext = accessibleContext;
2414 
2415 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2416     PrintDebugString("[INFO]: WinAccessBridge::getActiveDescendent(%X, %p)", vmID, accessibleContext);
2417 #else // JOBJECT64 is jlong (64 bit)
2418     PrintDebugString("[INFO]: WinAccessBridge::getActiveDescendent(%X, %016I64X)", vmID, accessibleContext);
2419 #endif
2420     // need to call only the HWND/VM that contains this AC
2421     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2422     if (destABWindow != (HWND) 0) {
2423         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2424             return pkg->rAccessibleContext;
2425         }
2426     }
2427     return (JOBJECT64) 0;
2428 }
2429 
2430 /**
2431  * Additional methods for Teton
2432  */
2433 
2434 /**
2435  * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns
2436  * whether successful.
2437  *
2438  * Bug ID 4916682 - Implement JAWS AccessibleName policy
2439  */
2440 BOOL
2441 WinAccessBridge::getVirtualAccessibleName(long vmID, AccessibleContext accessibleContext,
2442                                           wchar_t *name, int len) {
2443 
2444     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2445         return FALSE;
2446     }
2447     char buffer[sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage)];
2448     PackageType *type = (PackageType *) buffer;
2449     GetVirtualAccessibleNamePackage *pkg = (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType));
2450     *type = cGetVirtualAccessibleNamePackage;
2451     pkg->vmID = vmID;
2452     pkg->accessibleContext = accessibleContext;
2453     size_t max = (len > sizeof(pkg->rName)) ? sizeof(pkg->rName) : len;
2454     pkg->len = (int)max;
2455 
2456 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2457     PrintDebugString("[INFO]: WinAccessBridge::getVirtualAccessibleName(%X, %p)", vmID, accessibleContext);
2458 #else // JOBJECT64 is jlong (64 bit)
2459     PrintDebugString("[INFO]: WinAccessBridge::getVirtualAccessibleName(%X, %016I64X)", vmID, accessibleContext);
2460 #endif
2461     // need to call only the HWND/VM that contains this AC
2462     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2463     if (destABWindow != (HWND) 0) {
2464         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2465             wcsncpy(name, pkg->rName, max);
2466             PrintDebugString("[INFO]:     WinAccessBridge::getVirtualAccessibleName: Virtual name = %ls", name);
2467             return TRUE;
2468         }
2469     }
2470     return FALSE;
2471 }
2472 
2473 /**
2474  * Request focus for a component. Returns whether successful;
2475  *
2476  * Bug ID 4944757 - requestFocus method needed
2477  */
2478 BOOL
2479 WinAccessBridge::requestFocus(long vmID, AccessibleContext accessibleContext) {
2480 
2481     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2482         return FALSE;
2483     }
2484     char buffer[sizeof(PackageType) + sizeof(RequestFocusPackage)];
2485     PackageType *type = (PackageType *) buffer;
2486     RequestFocusPackage *pkg = (RequestFocusPackage *) (buffer + sizeof(PackageType));
2487     *type = cRequestFocusPackage;
2488     pkg->vmID = vmID;
2489     pkg->accessibleContext = accessibleContext;
2490 
2491 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2492     PrintDebugString("[INFO]: WinAccessBridge::requestFocus(%X, %p)", vmID, accessibleContext);
2493 #else // JOBJECT64 is jlong (64 bit)
2494     PrintDebugString("[INFO]: WinAccessBridge::requestFocus(%X, %016I64X)", vmID, accessibleContext);
2495 #endif
2496     // need to call only the HWND/VM that contains this AC
2497     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2498     if (destABWindow != (HWND) 0) {
2499         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2500             return TRUE;
2501         }
2502     }
2503     return FALSE;
2504 }
2505 
2506 /**
2507  * Selects text between two indices.  Selection includes the text at the start index
2508  * and the text at the end index. Returns whether successful;
2509  *
2510  * Bug ID 4944758 - selectTextRange method needed
2511  */
2512 BOOL
2513 WinAccessBridge::selectTextRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex) {
2514     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2515         return FALSE;
2516     }
2517     char buffer[sizeof(PackageType) + sizeof(SelectTextRangePackage)];
2518     PackageType *type = (PackageType *) buffer;
2519     SelectTextRangePackage *pkg = (SelectTextRangePackage *) (buffer + sizeof(PackageType));
2520     *type = cSelectTextRangePackage;
2521     pkg->vmID = vmID;
2522     pkg->accessibleContext = accessibleContext;
2523     pkg->startIndex = startIndex;
2524     pkg->endIndex = endIndex;
2525 
2526 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2527     PrintDebugString("[INFO]:     WinAccessBridge::selectTextRange(%X, %p %d %d)", vmID, accessibleContext,
2528                      startIndex, endIndex);
2529 #else // JOBJECT64 is jlong (64 bit)
2530     PrintDebugString("[INFO]:     WinAccessBridge::selectTextRange(%X, %016I64X %d %d)", vmID, accessibleContext,
2531                      startIndex, endIndex);
2532 #endif
2533     // need to call only the HWND/VM that contains this AC
2534     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2535     if (destABWindow != (HWND) 0) {
2536         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2537             return TRUE;
2538         }
2539     }
2540     return FALSE;
2541 }
2542 
2543 /**
2544  * Get text attributes between two indices.  The attribute list includes the text at the
2545  * start index and the text at the end index. Returns whether successful;
2546  *
2547  * Bug ID 4944761 - getTextAttributes between two indices method needed
2548  */
2549 BOOL
2550 WinAccessBridge::getTextAttributesInRange(long vmID, AccessibleContext accessibleContext,
2551                                           int startIndex, int endIndex,
2552                                           AccessibleTextAttributesInfo *attributes, short *len) {
2553 
2554     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2555         return FALSE;
2556     }
2557     char buffer[sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage)];
2558     PackageType *type = (PackageType *) buffer;
2559     GetTextAttributesInRangePackage *pkg = (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType));
2560     *type = cGetTextAttributesInRangePackage;
2561     pkg->vmID = vmID;
2562     pkg->accessibleContext = accessibleContext;
2563     pkg->startIndex = startIndex;
2564     pkg->endIndex = endIndex;
2565     memcpy(&(pkg->attributes), attributes, sizeof(AccessibleTextAttributesInfo));
2566 
2567 
2568 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2569     PrintDebugString("[INFO]:     WinAccessBridge::getTextAttributesInRange(%X, %p %d %d)", vmID, accessibleContext,
2570                      startIndex, endIndex);
2571 #else // JOBJECT64 is jlong (64 bit)
2572     PrintDebugString("[INFO]:     WinAccessBridge::getTextAttributesInRange(%X, %016I64X %d %d)", vmID, accessibleContext,
2573                      startIndex, endIndex);
2574 #endif
2575     // need to call only the HWND/VM that contains this AC
2576     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2577     if (destABWindow != (HWND) 0) {
2578         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2579             *attributes = pkg->attributes;
2580             *len = pkg->rLength;
2581             return TRUE;
2582         }
2583     }
2584     return FALSE;
2585 }
2586 
2587 /**
2588  * Gets the number of visible children of a component. Returns -1 on error.
2589  *
2590  * Bug ID 4944762- getVisibleChildren for list-like components needed
2591  */
2592 int
2593 WinAccessBridge::getVisibleChildrenCount(long vmID, AccessibleContext accessibleContext) {
2594 
2595     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2596         return -1;
2597     }
2598     char buffer[sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage)];
2599     PackageType *type = (PackageType *) buffer;
2600     GetVisibleChildrenCountPackage *pkg = (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType));
2601     *type = cGetVisibleChildrenCountPackage;
2602     pkg->vmID = vmID;
2603     pkg->accessibleContext = accessibleContext;
2604 
2605 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2606     PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildrenCount(%X, %p)", vmID, accessibleContext);
2607 #else // JOBJECT64 is jlong (64 bit)
2608     PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildrenCount(%X, %016I64X)", vmID, accessibleContext);
2609 #endif
2610     // need to call only the HWND/VM that contains this AC
2611     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2612     if (destABWindow != (HWND) 0) {
2613         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2614             return pkg->rChildrenCount;
2615         }
2616     }
2617     return -1;
2618 }
2619 
2620 /**
2621  * Gets the visible children of an AccessibleContext. Returns whether successful;
2622  *
2623  * Bug ID 4944762- getVisibleChildren for list-like components needed
2624  */
2625 BOOL
2626 WinAccessBridge::getVisibleChildren(long vmID, AccessibleContext accessibleContext, int startIndex,
2627                                     VisibleChildrenInfo *visibleChildrenInfo) {
2628 
2629     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2630         return FALSE;
2631     }
2632     char buffer[sizeof(PackageType) + sizeof(GetVisibleChildrenPackage)];
2633     PackageType *type = (PackageType *) buffer;
2634     GetVisibleChildrenPackage *pkg = (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType));
2635     *type = cGetVisibleChildrenPackage;
2636     pkg->vmID = vmID;
2637     pkg->accessibleContext = accessibleContext;
2638     pkg->startIndex = startIndex;
2639 
2640 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2641     PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildren(%X, %p)", vmID, accessibleContext);
2642 #else // JOBJECT64 is jlong (64 bit)
2643     PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildren(%X, %016I64X)", vmID, accessibleContext);
2644 #endif
2645     // need to call only the HWND/VM that contains this AC
2646     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2647     if (destABWindow != (HWND) 0) {
2648         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2649             memcpy(visibleChildrenInfo, &(pkg->rVisibleChildrenInfo), sizeof(pkg->rVisibleChildrenInfo));
2650             return pkg->rSuccess;
2651         }
2652     }
2653     return FALSE;
2654 }
2655 
2656 /**
2657  * Set the caret to a text position. Returns whether successful;
2658  *
2659  * Bug ID 4944770 - setCaretPosition method needed
2660  */
2661 BOOL
2662 WinAccessBridge::setCaretPosition(long vmID, AccessibleContext accessibleContext, int position) {
2663 
2664     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2665         return FALSE;
2666     }
2667     char buffer[sizeof(PackageType) + sizeof(SetCaretPositionPackage)];
2668     PackageType *type = (PackageType *) buffer;
2669     SetCaretPositionPackage *pkg = (SetCaretPositionPackage *) (buffer + sizeof(PackageType));
2670     *type = cSetCaretPositionPackage;
2671     pkg->vmID = vmID;
2672     pkg->accessibleContext = accessibleContext;
2673     pkg->position = position;
2674 
2675 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2676     PrintDebugString("[INFO]: WinAccessBridge::setCaretPosition(%X, %p %ls)", vmID, accessibleContext);
2677 #else // JOBJECT64 is jlong (64 bit)
2678     PrintDebugString("[INFO]: WinAccessBridge::setCaretPosition(%X, %016I64X %ls)", vmID, accessibleContext);
2679 #endif
2680     // need to call only the HWND/VM that contains this AC
2681     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2682     if (destABWindow != (HWND) 0) {
2683         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2684             return TRUE;
2685         }
2686     }
2687     return FALSE;
2688 }
2689 
2690 
2691 /********** AccessibleText routines ***********************************/
2692 
2693 /**
2694  * getAccessibleTextInfo - fills a struct with a bunch of information
2695  * contained in the Java Accessibility AccessibleText API
2696  *
2697  *
2698  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2699  */
2700 BOOL
2701 WinAccessBridge::getAccessibleTextInfo(long vmID,
2702                                        JOBJECT64 AccessibleContext,
2703                                        AccessibleTextInfo *textInfo,
2704                                        jint x, jint y) {
2705     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2706         return FALSE;
2707     }
2708     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage)];
2709     PackageType *type = (PackageType *) buffer;
2710     GetAccessibleTextInfoPackage *pkg = (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType));
2711     *type = cGetAccessibleTextInfoPackage;
2712     pkg->vmID = vmID;
2713     pkg->AccessibleContext = AccessibleContext;
2714     pkg->x = x;
2715     pkg->y = y;
2716 
2717 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2718     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextInfo(%X, %p, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y);
2719 #else // JOBJECT64 is jlong (64 bit)
2720     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextInfo(%X, %016I64X, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y);
2721 #endif
2722     // need to call only the HWND/VM that contains this AC
2723     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2724     if (destABWindow != (HWND) 0) {
2725         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2726             memcpy(textInfo, &(pkg->rTextInfo), sizeof(AccessibleTextInfo));
2727             if (pkg->rTextInfo.charCount != -1) {
2728                 PrintDebugString("[INFO]:   charCount: %d"\
2729                                  "          caretIndex: %d"\
2730                                  "          indexAtPoint: %d"\
2731                                  , textInfo->charCount, textInfo->caretIndex, textInfo->indexAtPoint);
2732                 return TRUE;
2733             }
2734         }
2735     }
2736 
2737     return FALSE;
2738 }
2739 
2740 /**
2741  * getAccessibleTextItems - fills a struct with letter, word, and sentence info
2742  * of the AccessibleText interface at a given index
2743  *
2744  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2745  */
2746 BOOL
2747 WinAccessBridge::getAccessibleTextItems(long vmID,
2748                                         JOBJECT64 AccessibleContext,
2749                                         AccessibleTextItemsInfo *textItems,
2750                                         jint index) {
2751     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2752         return FALSE;
2753     }
2754     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage)];
2755     PackageType *type = (PackageType *) buffer;
2756     GetAccessibleTextItemsPackage *pkg = (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType));
2757     *type = cGetAccessibleTextItemsPackage;
2758     pkg->vmID = vmID;
2759     pkg->AccessibleContext = AccessibleContext;
2760     pkg->index = index;
2761     // zero things out, in case the call fails
2762     pkg->rTextItemsInfo.letter = '\0';
2763     pkg->rTextItemsInfo.word[0] = '\0';
2764     pkg->rTextItemsInfo.sentence[0] = '\0';
2765 
2766 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2767     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextItems(%X, %p, %p, %d)", vmID, AccessibleContext, textItems, index);
2768 #else // JOBJECT64 is jlong (64 bit)
2769     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextItems(%X, %016I64X, %p, %d)", vmID, AccessibleContext, textItems, index);
2770 #endif
2771     // need to call only the HWND/VM that contains this AC
2772     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2773     if (destABWindow != (HWND) 0) {
2774         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2775             memcpy(textItems, &(pkg->rTextItemsInfo), sizeof(AccessibleTextItemsInfo));
2776             if (pkg->rTextItemsInfo.letter != '/0') {
2777                 return TRUE;
2778             }
2779         }
2780     }
2781 
2782     return FALSE;
2783 }
2784 
2785 /**
2786  * getAccessibleTextSelectionInfo - returns information about the selected
2787  * text of the object implementing AccessibleText
2788  *
2789  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2790  */
2791 BOOL
2792 WinAccessBridge::getAccessibleTextSelectionInfo(long vmID,
2793                                                 JOBJECT64 AccessibleContext,
2794                                                 AccessibleTextSelectionInfo *selectionInfo) {
2795     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2796         return FALSE;
2797     }
2798     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage)];
2799     PackageType *type = (PackageType *) buffer;
2800     GetAccessibleTextSelectionInfoPackage *pkg = (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType));
2801     *type = cGetAccessibleTextSelectionInfoPackage;
2802     pkg->vmID = vmID;
2803     pkg->AccessibleContext = AccessibleContext;
2804 
2805 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2806     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextSelectionInfo(%X, %p, %p)", vmID, AccessibleContext, selectionInfo);
2807 #else // JOBJECT64 is jlong (64 bit)
2808     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextSelectionInfo(%X, %016I64X, %p)", vmID, AccessibleContext, selectionInfo);
2809 #endif
2810     // need to call only the HWND/VM that contains this AC
2811     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2812     if (destABWindow != (HWND) 0) {
2813         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2814             memcpy(selectionInfo, &(pkg->rTextSelectionItemsInfo), sizeof(AccessibleTextSelectionInfo));
2815             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
2816             return TRUE;
2817         }
2818     }
2819 
2820     return FALSE;
2821 }
2822 
2823 /**
2824  * getAccessibleTextAttributes - performs the Java code:
2825  *   ...[[[FIXME]]] fill in this comment...
2826  *
2827  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2828  */
2829 BOOL
2830 WinAccessBridge::getAccessibleTextAttributes(long vmID,
2831                                              JOBJECT64 AccessibleContext,
2832                                              jint index,
2833                                              AccessibleTextAttributesInfo *attributes) {
2834     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2835         return FALSE;
2836     }
2837     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage)];
2838     PackageType *type = (PackageType *) buffer;
2839     GetAccessibleTextAttributeInfoPackage *pkg = (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType));
2840     *type = cGetAccessibleTextAttributeInfoPackage;
2841     pkg->vmID = vmID;
2842     pkg->AccessibleContext = AccessibleContext;
2843     pkg->index = index;
2844 
2845 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2846     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextAttributes(%X, %p, %d, %p)", vmID, AccessibleContext, index, attributes);
2847 #else // JOBJECT64 is jlong (64 bit)
2848     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextAttributes(%X, %016I64X, %d, %p)", vmID, AccessibleContext, index, attributes);
2849 #endif
2850     // need to call only the HWND/VM that contains this AC
2851     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2852     if (destABWindow != (HWND) 0) {
2853         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2854             memcpy(attributes, &(pkg->rAttributeInfo), sizeof(AccessibleTextAttributesInfo));
2855             return TRUE;
2856         }
2857     }
2858 
2859     return FALSE;
2860 }
2861 
2862 /**
2863  * getAccessibleTextRect - gets the text bounding rectangle
2864  *
2865  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2866  */
2867 BOOL
2868 WinAccessBridge::getAccessibleTextRect(long vmID,
2869                                        JOBJECT64 AccessibleContext,
2870                                        AccessibleTextRectInfo *rectInfo,
2871                                        jint index) {
2872     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2873         return FALSE;
2874     }
2875     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage)];
2876     PackageType *type = (PackageType *) buffer;
2877     GetAccessibleTextRectInfoPackage *pkg = (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType));
2878     *type = cGetAccessibleTextRectInfoPackage;
2879     pkg->vmID = vmID;
2880     pkg->AccessibleContext = AccessibleContext;
2881     pkg->index = index;
2882 
2883 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2884     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRect(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2885 #else // JOBJECT64 is jlong (64 bit)
2886     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRect(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2887 #endif
2888     // need to call only the HWND/VM that contains this AC
2889     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2890     if (destABWindow != (HWND) 0) {
2891         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2892             memcpy(rectInfo, (&pkg->rTextRectInfo), sizeof(AccessibleTextRectInfo));
2893             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
2894             return TRUE;
2895         }
2896     }
2897 
2898     return FALSE;
2899 }
2900 
2901 
2902 /**
2903  * getAccessibleTextRect - gets the text bounding rectangle
2904  *
2905  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2906  */
2907 BOOL
2908 WinAccessBridge::getCaretLocation(long vmID,
2909                                        JOBJECT64 AccessibleContext,
2910                                        AccessibleTextRectInfo *rectInfo,
2911                                        jint index) {
2912     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2913         return FALSE;
2914     }
2915     char buffer[sizeof(PackageType) + sizeof(GetCaretLocationPackage)];
2916     PackageType *type = (PackageType *) buffer;
2917     GetCaretLocationPackage *pkg = (GetCaretLocationPackage *) (buffer + sizeof(PackageType));
2918     *type = cGetCaretLocationPackage;
2919     pkg->vmID = vmID;
2920     pkg->AccessibleContext = AccessibleContext;
2921     pkg->index = index;
2922 
2923 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2924     PrintDebugString("[INFO]: WinAccessBridge::getCaretLocation(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2925 #else // JOBJECT64 is jlong (64 bit)
2926     PrintDebugString("[INFO]: WinAccessBridge::getCaretLocation(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index);
2927 #endif
2928     // need to call only the HWND/VM that contains this AC
2929     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2930     if (destABWindow != (HWND) 0) {
2931         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2932             memcpy(rectInfo, (&pkg->rTextRectInfo), sizeof(AccessibleTextRectInfo));
2933             return TRUE;
2934         }
2935     }
2936 
2937     return FALSE;
2938 }
2939 
2940 
2941 /**
2942  * getEventsWaiting - gets the number of events waiting to fire
2943  *
2944  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2945  */
2946 int


2956  * getAccessibleTextLineBounds - gets the bounding rectangle for the text line
2957  *
2958  * Note: if the AccessibleContext parameter is bogus, this call will blow up
2959  */
2960 BOOL
2961 WinAccessBridge::getAccessibleTextLineBounds(long vmID,
2962                                              JOBJECT64 AccessibleContext,
2963                                              jint index, jint *startIndex, jint *endIndex) {
2964     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
2965         return FALSE;
2966     }
2967     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage)];
2968     PackageType *type = (PackageType *) buffer;
2969     GetAccessibleTextLineBoundsPackage *pkg = (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType));
2970     *type = cGetAccessibleTextLineBoundsPackage;
2971     pkg->vmID = vmID;
2972     pkg->AccessibleContext = AccessibleContext;
2973     pkg->index = index;
2974 
2975 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2976     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextLineBounds(%X, %p, %d, )", vmID, AccessibleContext, index);
2977 #else // JOBJECT64 is jlong (64 bit)
2978     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextLineBounds(%X, %016I64X, %d, )", vmID, AccessibleContext, index);
2979 #endif
2980     // need to call only the HWND/VM that contains this AC
2981     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
2982     if (destABWindow != (HWND) 0) {
2983         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
2984             *startIndex = pkg->rLineStart;
2985             *endIndex = pkg->rLineEnd;
2986             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
2987             return TRUE;
2988         }
2989     }
2990 
2991     return FALSE;
2992 }
2993 
2994 
2995 /**
2996  * getAccessibleTextLineBounds - performs the Java code:
2997  *   ...[[[FIXME]]] fill in this comment...
2998  *
2999  * Note: if the AccessibleContext parameter is bogus, this call will blow up
3000  */
3001 BOOL
3002 WinAccessBridge::getAccessibleTextRange(long vmID,
3003                                         JOBJECT64 AccessibleContext,
3004                                         jint start, jint end, wchar_t *text, short len) {
3005     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3006         return FALSE;
3007     }
3008     char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage)];
3009     PackageType *type = (PackageType *) buffer;
3010     GetAccessibleTextRangePackage *pkg = (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType));
3011     *type = cGetAccessibleTextRangePackage;
3012     pkg->vmID = vmID;
3013     pkg->AccessibleContext = AccessibleContext;
3014     pkg->start = start;
3015     pkg->end = end;
3016 
3017 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
3018     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRange(%X, %p, %d, %d, )", vmID, AccessibleContext, start, end);
3019 #else // JOBJECT64 is jlong (64 bit)
3020     PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRange(%X, %016I64X, %d, %d, )", vmID, AccessibleContext, start, end);
3021 #endif
3022     // need to call only the HWND/VM that contains this AC
3023     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3024     if (destABWindow != (HWND) 0) {
3025         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
3026             wcsncpy(text, pkg->rText, len);
3027             // [[[FIXME]]] should test to see if valid info returned; return FALSE if not
3028             return TRUE;
3029         }
3030     }
3031 
3032     return FALSE;
3033 }
3034 
3035 
3036 
3037 
3038 /********** AccessibleValue routines ***************/
3039 
3040 BOOL


3277     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
3278     if (destABWindow != (HWND) 0) {
3279         sendMemoryPackage(buffer, sizeof(buffer), destABWindow);
3280     }
3281 }
3282 
3283 
3284 /*********** Event handling methods **********************************/
3285 
3286 /**
3287  * addEventNotification - tell all Java-launched AccessBridge DLLs
3288  *                        that we want events of the specified type
3289  *
3290  * [[[FIXME]]] since we're just sending a long & a source window,
3291  *                         we could use a private message rather than WM_COPYDATA
3292  *                         (though we still may want it to be synchronous; dunno...)
3293  *
3294  */
3295 void
3296 WinAccessBridge::addJavaEventNotification(jlong type) {
3297     PrintDebugString("[INFO]: WinAccessBridge::addJavaEventNotification(%016I64X)", type);
3298     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3299         return;
3300     }
3301 
3302     char buffer[sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage)];
3303     PackageType *pkgType = (PackageType *) buffer;
3304     AddJavaEventNotificationPackage *pkg = (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
3305     *pkgType = cAddJavaEventNotificationPackage;
3306     pkg->type = type;
3307     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3308 
3309     PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %p",
3310                      *pkgType, pkg->type, pkg->DLLwindow);
3311 
3312     // send addEventNotification message to all JVMs
3313     isVMInstanceChainInUse = true;
3314     AccessBridgeJavaVMInstance *current = javaVMs;
3315     while (current != (AccessBridgeJavaVMInstance *) 0) {
3316         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3317         current = current->nextJVMInstance;
3318     }
3319     isVMInstanceChainInUse = false;
3320 }
3321 
3322 /**
3323  * removeEventNotification - tell all Java-launched AccessBridge DLLs
3324  *                                                       that we no longer want events of the
3325  *                                                       specified type
3326  *
3327  * [[[FIXME]]] since we're just sending a long & a source window,
3328  *                         we could use a private message rather than WM_COPYDATA
3329  *                         (though we still may want it to be synchronous; dunno...)
3330  *
3331  */
3332 void
3333 WinAccessBridge::removeJavaEventNotification(jlong type) {
3334     PrintDebugString("[INFO]: in WinAccessBridge::removeJavaEventNotification(%016I64X)", type);
3335     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3336         return;
3337     }
3338     char buffer[sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage)];
3339     PackageType *pkgType = (PackageType *) buffer;
3340     RemoveJavaEventNotificationPackage *pkg = (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
3341     *pkgType = cRemoveJavaEventNotificationPackage;
3342     pkg->type = type;
3343     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3344 
3345     PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %p",
3346                      *pkgType, pkg->type, pkg->DLLwindow);
3347 
3348     // send removeEventNotification message to all JVMs
3349     isVMInstanceChainInUse = true;
3350     AccessBridgeJavaVMInstance *current = javaVMs;
3351     while (current != (AccessBridgeJavaVMInstance *) 0) {
3352         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3353         current = current->nextJVMInstance;
3354     }
3355     isVMInstanceChainInUse = false;
3356 }
3357 
3358 
3359 /*********** Event handling methods **********************************/
3360 
3361 /**
3362  * addAccessibilityEventNotification - tell all Java-launched AccessBridge DLLs
3363  *                        that we want events of the specified type
3364  *
3365  * [[[FIXME]]] since we're just sending a long & a source window,
3366  *                         we could use a private message rather than WM_COPYDATA
3367  *                         (though we still may want it to be synchronous; dunno...)
3368  *
3369  */
3370 void
3371 WinAccessBridge::addAccessibilityEventNotification(jlong type) {
3372     PrintDebugString("[INFO]: in WinAccessBridge::addAccessibilityEventNotification(%016I64X)", type);
3373     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3374         return;
3375     }
3376     char buffer[sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage)];
3377     PackageType *pkgType = (PackageType *) buffer;
3378     AddAccessibilityEventNotificationPackage *pkg = (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
3379     *pkgType = cAddAccessibilityEventNotificationPackage;
3380     pkg->type = type;
3381     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3382 
3383     PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %X",
3384                      *pkgType, pkg->type, pkg->DLLwindow);
3385 
3386     // send addEventNotification message to all JVMs
3387     isVMInstanceChainInUse = true;
3388     AccessBridgeJavaVMInstance *current = javaVMs;
3389     while (current != (AccessBridgeJavaVMInstance *) 0) {
3390         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3391         current = current->nextJVMInstance;
3392     }
3393     isVMInstanceChainInUse = false;
3394 }
3395 
3396 /**
3397  * removeAccessibilityEventNotification - tell all Java-launched AccessBridge DLLs
3398  *                                                       that we no longer want events of the
3399  *                                                       specified type
3400  *
3401  * [[[FIXME]]] since we're just sending a long & a source window,
3402  *                         we could use a private message rather than WM_COPYDATA
3403  *                         (though we still may want it to be synchronous; dunno...)
3404  *
3405  */
3406 void
3407 WinAccessBridge::removeAccessibilityEventNotification(jlong type) {
3408     PrintDebugString("[INFO]: in WinAccessBridge::removeAccessibilityEventNotification(%016I64X)", type);
3409     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
3410         return;
3411     }
3412     char buffer[sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage)];
3413     PackageType *pkgType = (PackageType *) buffer;
3414     RemoveAccessibilityEventNotificationPackage *pkg = (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
3415     *pkgType = cRemoveAccessibilityEventNotificationPackage;
3416     pkg->type = type;
3417     pkg->DLLwindow = ABHandleToLong(dialogWindow);
3418 
3419     PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %X",
3420                      *pkgType, pkg->type, pkg->DLLwindow);
3421 
3422     // send removeEventNotification message to all JVMs
3423     isVMInstanceChainInUse = true;
3424     AccessBridgeJavaVMInstance *current = javaVMs;
3425     while (current != (AccessBridgeJavaVMInstance *) 0) {
3426         current->sendPackage(buffer, sizeof(buffer));           // no return values!
3427         current = current->nextJVMInstance;
3428     }
3429     isVMInstanceChainInUse = false;
3430 }
3431 
3432 
3433 #define CALL_SET_EVENT_FP(function, callbackFP)         \
3434         void WinAccessBridge::function(callbackFP fp) { \
3435                 eventHandler->function(fp, this);                       \
3436                 /* eventHandler calls back to winAccessBridgeDLL to set eventMask */    \
3437         }
3438 
3439     void WinAccessBridge::setJavaShutdownFP(AccessBridge_JavaShutdownFP fp) {


< prev index next >