1 /*
   2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * A DLL which is loaded by Java applications to handle communication
  28  * between Java VMs purposes of Accessbility.
  29  */
  30 
  31 #include "AccessBridgeDebug.h"
  32 #include "JavaAccessBridge.h"
  33 #include "com_sun_java_accessibility_internal_AccessBridge.h" // programatically generated by JNI
  34 #include "accessBridgeResource.h"
  35 #include "accessBridgeCallbacks.h"
  36 #include "AccessBridgeMessages.h"
  37 
  38 
  39 #include <windows.h>
  40 #include <stdio.h>
  41 
  42 #include <jawt.h>
  43 #include <jawt_md.h>
  44 
  45 JavaAccessBridge *theJavaAccessBridge;
  46 HWND theDialogWindow;
  47 
  48 // re-entrance lock for receiving memory messages
  49 CRITICAL_SECTION receiveMemoryIPCLock;
  50 
  51 
  52 // unique broadcast msg. IDs gotten dymanically
  53 extern UINT theFromJavaHelloMsgID;
  54 extern UINT theFromWindowsHelloMsgID;
  55 
  56 
  57 // ---------------------------------------------------------------------------
  58 
  59 extern "C" {
  60     /**
  61      * DllMain - where Windows executables will load/unload us
  62      *
  63      */
  64     BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) {
  65 
  66         switch (fdwReason) {
  67         case DLL_PROCESS_ATTACH:
  68             InitializeCriticalSection(&receiveMemoryIPCLock);
  69             theJavaAccessBridge = new JavaAccessBridge(hinstDll);
  70             break;
  71 
  72         case DLL_PROCESS_DETACH:        // A Windows executable unloaded us
  73             if (theJavaAccessBridge != (JavaAccessBridge *) 0) {
  74                 delete theJavaAccessBridge;
  75                 DeleteCriticalSection(&receiveMemoryIPCLock);
  76             }
  77             break;
  78         }
  79         return TRUE;
  80     }
  81 
  82     /**
  83      * Open a native window (and init the wrappers we'll be using)
  84      *
  85      */
  86     JNIEXPORT void JNICALL
  87     Java_com_sun_java_accessibility_internal_AccessBridge_runDLL(JNIEnv *env, jobject obj) {
  88         PrintDebugString("\r\nJavaAccessBridge.DLL runDLL() called");
  89         theJavaAccessBridge->javaRun(env, obj);
  90     }
  91 
  92     /**
  93      * Our window proc
  94      *
  95      */
  96     BOOL APIENTRY AccessBridgeDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
  97         int command;
  98         COPYDATASTRUCT *sentToUs;
  99         char *package;
 100 
 101         switch (message) {
 102         case WM_INITDIALOG:
 103             PrintDebugString("In AccessBridgeDialog - Initializing");
 104             break;
 105 
 106         case WM_COMMAND:
 107             command = LOWORD (wParam);
 108             PrintDebugString("In AccessBridgeDialog - Got WM_COMMAND, command: %X", command);
 109             break;
 110 
 111             // call from Java with data for us to deliver
 112         case WM_COPYDATA:
 113             if (theDialogWindow == (HWND) wParam) {
 114                 PrintDebugString("In AccessBridgeDialog - Got WM_COPYDATA from ourselves");
 115             } else {
 116                 PrintDebugString("In AccessBridgeDialog - Got WM_COPYDATA from HWND %p", wParam);
 117                 sentToUs = (COPYDATASTRUCT *) lParam;
 118                 package = (char *) sentToUs->lpData;
 119                 theJavaAccessBridge->processPackage(package, sentToUs->cbData);
 120             }
 121             break;
 122 
 123             // call from Java with data for us retrieve from memory mapped file and deliver
 124         case AB_MESSAGE_WAITING:
 125             // wParam == sourceHwnd
 126             // lParam == buffer size in shared memory
 127             if (theDialogWindow == (HWND) wParam) {
 128                 PrintDebugString("In AccessBridgeDialog - Got AB_MESSAGE_WAITING from ourselves");
 129             } else {
 130                 PrintDebugString("In AccessBridgeDialog - Got AB_MESSAGE_WAITING from HWND %p", wParam);
 131                 LRESULT returnVal = theJavaAccessBridge->receiveMemoryPackage((HWND) wParam, (long) lParam);
 132             }
 133             break;
 134 
 135             // a JavaAccessBridge DLL is going away
 136         case AB_DLL_GOING_AWAY:
 137             PrintDebugString("In AccessBridgeDialog - Got AB_DLL_GOING_AWAY message");
 138             theJavaAccessBridge->WindowsATDestroyed((HWND) wParam);
 139             break;
 140 
 141         default:
 142             // the Windows AT is saying "hi"!
 143             // wParam == sourceHwnc; lParam unused
 144             if (message == theFromWindowsHelloMsgID) {
 145                 // A new Windows AT just said "hi";
 146                 // say "hi" back so it can mate up with us
 147                 // otherwise don't do anything (e.g. don't set up data structures yet)
 148                 PrintDebugString("In AccessBridgeDialog - Got theFromWindowsHelloMsgID message");
 149                 theJavaAccessBridge->postHelloToWindowsDLLMsg((HWND) wParam);
 150             }
 151         }
 152         return FALSE;
 153     }
 154 
 155 }
 156 
 157 
 158 // -----------------------------
 159 
 160 
 161 /**
 162  * Initialize the JavaAccessBridge
 163  *
 164  */
 165 JavaAccessBridge::JavaAccessBridge(HINSTANCE hInstance) {
 166     windowsInstance = hInstance;
 167     ATs = (AccessBridgeATInstance *) 0;
 168     initBroadcastMessageIDs();          // get the unique to us broadcast msg. IDs
 169 }
 170 
 171 extern DWORD JavaBridgeThreadId;
 172 
 173 /**
 174  * Destroy the JavaAccessBridge
 175  *
 176  */
 177 JavaAccessBridge::~JavaAccessBridge() {
 178     // inform all other AccessBridges that we're going away
 179 
 180     PrintDebugString("\r\nin JavaAccessBridge::~JavaAccessBridge()");
 181 
 182     // Send a shutdown message for those applications like StarOffice that do
 183     // send a shutdown message themselves.
 184     javaShutdown(NULL, 0);
 185 
 186     AccessBridgeATInstance *current = ATs;
 187     while (current != (AccessBridgeATInstance *) 0) {
 188         PrintDebugString("  telling %p we're going away", current->winAccessBridgeWindow);
 189                 SendMessage(current->winAccessBridgeWindow,
 190                     AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0);
 191         current = current->nextATInstance;
 192     }
 193 
 194     PrintDebugString("  finished telling ATs about our demise");
 195 
 196         if(JavaBridgeThreadId)
 197                 {
 198                 PostThreadMessage(JavaBridgeThreadId,WM_USER+1,0,0);
 199                 Sleep(100);
 200                 }
 201 
 202     delete ATs;
 203 
 204     PrintDebugString("  finished deleting ATs");
 205     PrintDebugString("GOODBYE CRUEL WORLD...");
 206 }
 207 
 208 
 209 void
 210 JavaAccessBridge::javaRun(JNIEnv *env, jobject obj) {
 211     MSG msg;
 212 
 213     PrintDebugString("JavaAccessBridge::javaRun(%p, %p) called", env, obj);
 214 
 215     if (env->GetJavaVM(&javaVM) != 0) {
 216         return; // huh!?!?!
 217     }
 218     PrintDebugString("  -> javaVM = %p", javaVM);
 219 
 220     if (javaVM->AttachCurrentThread((void **) &windowsThreadJNIEnv, NULL) != 0) {
 221         return; // huh!?!?!
 222     }
 223     PrintDebugString("  -> windowsThreadJNIEnv = %p", windowsThreadJNIEnv);
 224 
 225     javaThreadABObject = env->NewGlobalRef(obj);
 226     windowsThreadABObject = windowsThreadJNIEnv->NewGlobalRef(obj);
 227 
 228     // initialize the Java thread AccessBridge entry points
 229     javaThreadEntryPoints = new AccessBridgeJavaEntryPoints(env, javaThreadABObject);
 230     if (javaThreadEntryPoints->BuildJavaEntryPoints() == FALSE) {
 231         return;         // couldn't build our entry points; let's get out of here!
 232     }
 233     PrintDebugString("  all Java thread entry points successfully found.");
 234 
 235     // initialize the Windows thread AccessBridge entry points
 236     windowsThreadEntryPoints = new AccessBridgeJavaEntryPoints(windowsThreadJNIEnv,
 237                                                                windowsThreadABObject);
 238     if (windowsThreadEntryPoints->BuildJavaEntryPoints() == FALSE) {
 239         return;         // couldn't build our entry points; let's get out of here!
 240     }
 241     PrintDebugString("  all Windows thread entry points successfully found.");
 242 
 243 
 244     // open our window
 245     if (initWindow() == TRUE) {
 246         PrintDebugString("  Window created.  HWND = %p", dialogWindow);
 247 
 248         // post a broadcast msg.; let other AccessBridge DLLs know we exist
 249         postHelloToWindowsDLLMsg(HWND_BROADCAST);
 250 
 251         // do that message loop thing
 252         while (GetMessage(&msg, NULL, 0, 0)) {
 253             TranslateMessage(&msg);
 254             DispatchMessage(&msg);
 255         }
 256     } else {
 257         PrintDebugString("  FAILED TO CREATE WINDOW!!!");
 258     }
 259 
 260     javaVM->DetachCurrentThread();
 261 }
 262 
 263 /**
 264  * Bring up our window; make a connection to the rest of the world
 265  *
 266  */
 267 BOOL
 268 JavaAccessBridge::initWindow() {
 269     theDialogWindow = CreateDialog(windowsInstance,
 270                                    "ACCESSBRIDGESTATUSWINDOW", NULL,
 271                                    (DLGPROC) AccessBridgeDialogProc);
 272 
 273     // If window could not be created, return "failure".
 274     if (!theDialogWindow)
 275         return FALSE;
 276 
 277     dialogWindow = theDialogWindow;
 278 
 279     // Make the window visible, update its client area, & return "success".
 280     // DEBUG_CODE(ShowWindow (theDialogWindow, SW_SHOWNORMAL));
 281     // DEBUG_CODE(UpdateWindow (theDialogWindow));
 282 
 283     return TRUE;
 284 }
 285 
 286 
 287 
 288 // -----------------------
 289 
 290 
 291 /**
 292  * postHelloToWindowsDLLMsg
 293  *          - PostMessage(theFromJavaHelloMsgID) to let one or
 294  *            all WindowDLLs we're here and have a vmID
 295  *
 296  *            destHwnd is either a single hwnd or HWND_BROADCAST
 297  *              (former if a reply, latter if we're just born)
 298  *            wParam is our HWND
 299  *            lParam is our vmID
 300  *
 301  */
 302 void
 303 JavaAccessBridge::postHelloToWindowsDLLMsg(HWND destHwnd) {
 304     PrintDebugString("\r\nIn JavaAccessBridge::postHelloToWindowsDLLMsg");
 305     PrintDebugString("  calling PostMessage(%p, %X, %p, %p)",
 306                      destHwnd, theFromJavaHelloMsgID, dialogWindow, dialogWindow);
 307     PostMessage(destHwnd, theFromJavaHelloMsgID, (WPARAM) dialogWindow, (LPARAM) dialogWindow);
 308 }
 309 
 310 
 311 // -----------------------
 312 
 313 /**
 314  * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging
 315  *                                with the Java AccessBridge DLL
 316  *
 317  */
 318 void
 319 JavaAccessBridge::sendPackage(char *buffer, int bufsize, HWND destHwnd) {
 320     COPYDATASTRUCT toCopy;
 321     toCopy.dwData = 0;          // 32-bits we could use for something...
 322     toCopy.cbData = bufsize;
 323     toCopy.lpData = buffer;
 324 
 325     SendMessage(destHwnd, WM_COPYDATA, (WPARAM) dialogWindow, (LPARAM) &toCopy);
 326 }
 327 
 328 
 329 /**
 330  * sendJavaEventPackage - walk through ATs, sending event messages to 'em
 331  *
 332  */
 333 void
 334 JavaAccessBridge::sendJavaEventPackage(char *buffer, int bufsize, long type) {
 335 
 336     PrintDebugString("JavaAccessBridge::sendJavaEventPackage(), type = %X", type);
 337 
 338     if (ATs == (AccessBridgeATInstance *) 0) {
 339         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
 340     }
 341 
 342     AccessBridgeATInstance *ati = ATs;
 343     while (ati != (AccessBridgeATInstance *) 0) {
 344         ati->sendJavaEventPackage(buffer, bufsize, type);
 345         ati = ati->nextATInstance;
 346     }
 347 }
 348 
 349 /**
 350  * sendAccessibilityEventPackage - walk through ATs, sending event messages to 'em
 351  *
 352  */
 353 void
 354 JavaAccessBridge::sendAccessibilityEventPackage(char *buffer, int bufsize, long type) {
 355 
 356     PrintDebugString("JavaAccessBridge::sendAccessibilityEventPackage(), type = %X", type);
 357 
 358     if (ATs == (AccessBridgeATInstance *) 0) {
 359         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
 360     }
 361 
 362     AccessBridgeATInstance *ati = ATs;
 363     while (ati != (AccessBridgeATInstance *) 0) {
 364         ati->sendAccessibilityEventPackage(buffer, bufsize, type);
 365         ati = ati->nextATInstance;
 366     }
 367 }
 368 
 369 
 370 
 371 
 372 /**
 373  * receiveMemoryPackage - uses Memory-Mapped files to do IPC messaging
 374  *                        with the Java AccessBridge DLL, receiving the
 375  *                        message from Java AccessBridge DLL by reading the
 376  *                        contents of the shared memory mapped file that
 377  *                        is used for Java-initiated messages
 378  *
 379  */
 380 BOOL
 381 JavaAccessBridge::receiveMemoryPackage(HWND srcWindow, long bufsize) {
 382     char *IPCview;
 383 
 384     PrintDebugString("\r\nJavaAccessBridge::receiveMemoryPackage(%p, %d)", srcWindow, bufsize);
 385 
 386     // look-up the appropriate IPCview based on the srcHWND of the Windows AccessBridge DLL
 387     if (ATs == (AccessBridgeATInstance *) 0) {
 388         PrintDebugString("  ERROR! - ATs == 0 (shouldn't happen in receiveMemoryPackage()!");
 389         return FALSE;
 390     }
 391     AccessBridgeATInstance *ati = ATs->findABATInstanceFromATHWND(srcWindow);
 392     if (ati != (AccessBridgeATInstance *) 0) {
 393         IPCview = (char *) ati->memoryMappedView;
 394 
 395         // wait for the lock if someone else has it (re-entrancy)
 396         EnterCriticalSection(&receiveMemoryIPCLock);
 397         {
 398             // set byte at end of buffer to indicate to caller that we have reached this point
 399             IPCview[bufsize] = 1;
 400 
 401             // process the package
 402             processPackage(IPCview, bufsize);
 403         }
 404         // release re-entrance lock
 405         LeaveCriticalSection(&receiveMemoryIPCLock);
 406 
 407         return TRUE;
 408 
 409     } else {
 410         //DEBUG_CODE(AppendToCallInfo("ERROR receiving memory package: couldn't find srcWindow"));
 411         PrintDebugString("ERROR receiving memory package: couldn't find srcWindow");
 412         return FALSE;
 413     }
 414 }
 415 
 416 /**
 417  * processPackage - processes the output of SendMessage(WM_COPYDATA)
 418  *                                      to do IPC messaging with the Windows AccessBridge DLL
 419  *
 420  */
 421 LRESULT
 422 JavaAccessBridge::processPackage(char *buffer, int bufsize) {
 423     PrintDebugString("\r\nProcessing package sent from Windows, bufsize = %d:", bufsize);
 424 
 425     PackageType *type = (PackageType *) buffer;
 426     LRESULT returnVal = 0;
 427     PrintDebugString("  PackageType = %X:", *type);
 428     jobject rAC;
 429 
 430     switch (*type) {
 431 
 432 
 433     case cMemoryMappedFileCreatedPackage:
 434         // Windows is telling us it created a memory mapped file for us to use
 435         // in repsonding to various information querying packages (see below)
 436         PrintDebugString("   type == cMemoryMappedFileCreatedPackage");
 437         if (bufsize == (sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage))) {
 438             MemoryMappedFileCreatedPackage *pkg =
 439                 (MemoryMappedFileCreatedPackage *) (buffer + sizeof(PackageType));
 440             returnVal = MemoryMappedFileCreated((HWND)ABLongToHandle(pkg->bridgeWindow), pkg->filename);
 441         } else {
 442             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 443                              bufsize, sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage));
 444         }
 445         break;
 446 
 447         // ------------ information querying packages ------------------
 448 
 449     case cReleaseJavaObjectPackage:
 450         PrintDebugString("   type == cReleaseJavaObjectPackage");
 451         if (bufsize == (sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage))) {
 452             ReleaseJavaObjectPackage *pkg =
 453                 (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType));
 454             releaseJavaObject((jobject)pkg->object);
 455         } else {
 456             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 457                              bufsize, sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage));
 458         }
 459         break;
 460 
 461     case cGetAccessBridgeVersionPackage:
 462         PrintDebugString("   type == cGetAccessBridgeVersionPackage");
 463         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage))) {
 464             GetAccessBridgeVersionPackage *pkg =
 465                 (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType));
 466             windowsThreadEntryPoints->getVersionInfo(&(pkg->rVersionInfo));
 467         } else {
 468             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 469                              bufsize, sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage));
 470         }
 471         break;
 472 
 473     case cIsJavaWindowPackage:
 474         PrintDebugString("   type == cIsJavaWindowPackage");
 475         if (bufsize == (sizeof(PackageType) + sizeof(IsJavaWindowPackage))) {
 476             IsJavaWindowPackage *pkg =
 477                 (IsJavaWindowPackage *) (buffer + sizeof(PackageType));
 478             pkg->rResult =
 479                 windowsThreadEntryPoints->isJavaWindow(pkg->window);
 480             PrintDebugString("     -> returning result = %d", pkg->rResult);
 481         } else {
 482             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 483                              bufsize, sizeof(PackageType) + sizeof(IsJavaWindowPackage));
 484         }
 485         break;
 486 
 487     case cIsSameObjectPackage:
 488         PrintDebugString("   type == cIsSameObjectPackage");
 489         if (bufsize == (sizeof(PackageType) + sizeof(IsSameObjectPackage))) {
 490             IsSameObjectPackage *pkg =
 491                 (IsSameObjectPackage *) (buffer + sizeof(PackageType));
 492             pkg->rResult =
 493                 windowsThreadEntryPoints->isSameObject((jobject)pkg->obj1, (jobject)pkg->obj2);
 494             PrintDebugString("     -> returning result = %d", pkg->rResult);
 495         } else {
 496             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 497                              bufsize, sizeof(PackageType) + sizeof(IsSameObjectPackage));
 498         }
 499         break;
 500 
 501 
 502     case cGetAccessibleContextFromHWNDPackage:
 503         PrintDebugString("   type == cGetAccessibleContextFromHWNDPackage");
 504         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage))) {
 505             GetAccessibleContextFromHWNDPackage *pkg =
 506                 (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType));
 507             rAC = windowsThreadEntryPoints->getAccessibleContextFromHWND(pkg->window);
 508             pkg->rAccessibleContext = (JOBJECT64)rAC;
 509             pkg->rVMID = HandleToLong(dialogWindow);
 510             PrintDebugString("     -> returning AC = %p, vmID = %X", rAC, pkg->rVMID);
 511         } else {
 512             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 513                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage));
 514         }
 515         break;
 516 
 517 
 518     case cGetHWNDFromAccessibleContextPackage:
 519         PrintDebugString("   type == cGetHWNDFromAccessibleContextPackage");
 520         if (bufsize == (sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage))) {
 521             GetHWNDFromAccessibleContextPackage *pkg =
 522                 (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType));
 523             pkg->rHWND =
 524                 ABHandleToLong( windowsThreadEntryPoints->getHWNDFromAccessibleContext((jobject)pkg->accessibleContext) );
 525             PrintDebugString("     -> returning HWND = %p", pkg->rHWND);
 526         } else {
 527             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 528                              bufsize, sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage));
 529         }
 530         break;
 531 
 532 
 533         /* ===== utility methods ===== */
 534 
 535     case cSetTextContentsPackage:
 536         PrintDebugString("   type == cSetTextContentsPackage");
 537         if (bufsize == (sizeof(PackageType) + sizeof(SetTextContentsPackage))) {
 538             SetTextContentsPackage *pkg =
 539                 (SetTextContentsPackage *) (buffer + sizeof(PackageType));
 540             pkg->rResult =
 541                 windowsThreadEntryPoints->setTextContents((jobject)pkg->accessibleContext, pkg->text);
 542             PrintDebugString("     -> returning result = %d", pkg->rResult);
 543         } else {
 544             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 545                              bufsize, sizeof(PackageType) + sizeof(SetTextContentsPackage));
 546         }
 547         break;
 548 
 549     case cGetParentWithRolePackage:
 550         if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRolePackage))) {
 551             GetParentWithRolePackage *pkg =
 552                 (GetParentWithRolePackage *) (buffer + sizeof(PackageType));
 553             rAC = windowsThreadEntryPoints->getParentWithRole((jobject)pkg->accessibleContext, pkg->role);
 554             pkg->rAccessibleContext = (JOBJECT64)rAC;
 555             PrintDebugString("   type == cGetParentWithRolePackage");
 556             PrintDebugString("     pkg->vmID: %X", pkg->vmID);
 557             PrintDebugString("     pkg->accessibleContext: %p", (jobject)pkg->accessibleContext);
 558             PrintDebugString("     pkg->role: %ls", pkg->role);
 559             PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
 560         } else {
 561             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 562                              bufsize, sizeof(PackageType) + sizeof(GetParentWithRolePackage));
 563         }
 564         break;
 565 
 566     case cGetTopLevelObjectPackage:
 567         PrintDebugString("   type == cGetTopLevelObjectPackage");
 568         if (bufsize == (sizeof(PackageType) + sizeof(GetTopLevelObjectPackage))) {
 569             GetTopLevelObjectPackage *pkg =
 570                 (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType));
 571             rAC = windowsThreadEntryPoints->getTopLevelObject((jobject)pkg->accessibleContext);
 572             pkg->rAccessibleContext = (JOBJECT64)rAC;
 573             PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
 574         } else {
 575             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 576                              bufsize, sizeof(PackageType) + sizeof(GetTopLevelObjectPackage));
 577         }
 578         break;
 579 
 580     case cGetParentWithRoleElseRootPackage:
 581         PrintDebugString("   type == cGetParentWithRoleElseRootPackage");
 582         if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage))) {
 583             GetParentWithRoleElseRootPackage *pkg =
 584                 (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType));
 585             rAC = windowsThreadEntryPoints->getParentWithRoleElseRoot((jobject)pkg->accessibleContext, pkg->role);
 586             pkg->rAccessibleContext = (JOBJECT64)rAC;
 587             PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
 588         } else {
 589             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 590                              bufsize, sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage));
 591         }
 592         break;
 593 
 594     case cGetObjectDepthPackage:
 595         PrintDebugString("   type == cGetObjectDepthPackage");
 596         if (bufsize == (sizeof(PackageType) + sizeof(GetObjectDepthPackage))) {
 597             GetObjectDepthPackage *pkg =
 598                 (GetObjectDepthPackage *) (buffer + sizeof(PackageType));
 599             pkg->rResult =
 600                 windowsThreadEntryPoints->getObjectDepth((jobject)pkg->accessibleContext);
 601             PrintDebugString("     -> returning rResult = %d", pkg->rResult);
 602         } else {
 603             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 604                              bufsize, sizeof(PackageType) + sizeof(GetObjectDepthPackage));
 605         }
 606         break;
 607 
 608     case cGetActiveDescendentPackage:
 609         PrintDebugString("   type == cGetActiveDescendentPackage");
 610         if (bufsize == (sizeof(PackageType) + sizeof(GetActiveDescendentPackage))) {
 611             GetActiveDescendentPackage *pkg =
 612                 (GetActiveDescendentPackage *) (buffer + sizeof(PackageType));
 613             rAC = windowsThreadEntryPoints->getActiveDescendent((jobject)pkg->accessibleContext);
 614             pkg->rAccessibleContext = (JOBJECT64)rAC;
 615             PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
 616         } else {
 617             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 618                              bufsize, sizeof(PackageType) + sizeof(GetActiveDescendentPackage));
 619         }
 620         break;
 621 
 622     case cGetAccessibleContextAtPackage:
 623         PrintDebugString("   type == cGetAccessibleContextAtPackage");
 624         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage))) {
 625             GetAccessibleContextAtPackage *pkg =
 626                 (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType));
 627             pkg->rAccessibleContext = (JOBJECT64)
 628                 windowsThreadEntryPoints->getAccessibleContextAt(pkg->x, pkg->y,
 629                                                                  (jobject)pkg->AccessibleContext);
 630         } else {
 631             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 632                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage));
 633         }
 634         break;
 635 
 636     case cGetAccessibleContextWithFocusPackage:
 637         PrintDebugString("   type == cGetAccessibleContextWithFocusPackage");
 638         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage))) {
 639             GetAccessibleContextWithFocusPackage *pkg =
 640                 (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType));
 641             pkg->rAccessibleContext = (JOBJECT64)
 642                 windowsThreadEntryPoints->getAccessibleContextWithFocus();
 643                         pkg->rVMID =  HandleToLong(dialogWindow);
 644         } else {
 645             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 646                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage));
 647         }
 648         break;
 649 
 650     case cGetAccessibleContextInfoPackage:
 651         PrintDebugString("   type == cGetAccessibleContextInfoPackage");
 652         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage))) {
 653             GetAccessibleContextInfoPackage *pkg =
 654                 (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType));
 655             windowsThreadEntryPoints->getAccessibleContextInfo(
 656                                                                (jobject)pkg->AccessibleContext, &(pkg->rAccessibleContextInfo));
 657         } else {
 658             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 659                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage));
 660         }
 661         break;
 662 
 663     case cGetAccessibleChildFromContextPackage:
 664         PrintDebugString("   type == cGetAccessibleChildFromContextPackage");
 665         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage))) {
 666             GetAccessibleChildFromContextPackage *pkg =
 667                 (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType));
 668             pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleChildFromContext(
 669                                                                                               (jobject)pkg->AccessibleContext, pkg->childIndex);
 670         } else {
 671             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 672                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage));
 673         }
 674         break;
 675 
 676     case cGetAccessibleParentFromContextPackage:
 677         PrintDebugString("   type == cGetAccessibleParentFromContextPackage");
 678         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage))) {
 679             GetAccessibleParentFromContextPackage *pkg =
 680                 (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType));
 681             pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleParentFromContext(
 682                                                                                                (jobject)pkg->AccessibleContext);
 683         } else {
 684             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
 685                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage));
 686         }
 687         break;
 688 
 689         // ------------ begin AccessibleTable packages ------------------
 690 
 691     case cGetAccessibleTableInfoPackage:
 692         PrintDebugString("   ##### type == cGetAccessibleTableInfoPackage");
 693         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage))) {
 694             GetAccessibleTableInfoPackage *pkg =
 695                 (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType));
 696             windowsThreadEntryPoints->getAccessibleTableInfo((jobject)pkg->accessibleContext,
 697                                                              &(pkg->rTableInfo));
 698             PrintDebugString("   ##### processing succeeded");
 699         } else {
 700             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 701                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage));
 702         }
 703         break;
 704 
 705     case cGetAccessibleTableCellInfoPackage:
 706         PrintDebugString("   ##### type == cGetAccessibleTableCellInfoPackage");
 707         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage))) {
 708             GetAccessibleTableCellInfoPackage *pkg =
 709                 (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType));
 710             windowsThreadEntryPoints->getAccessibleTableCellInfo((jobject)pkg->accessibleTable, pkg->row,
 711                                                                  pkg->column, &(pkg->rTableCellInfo));
 712             PrintDebugString("   ##### processing succeeded");
 713         } else {
 714             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 715                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage));
 716         }
 717         break;
 718 
 719     case cGetAccessibleTableRowHeaderPackage:
 720         PrintDebugString("   ##### type == cGetAccessibleTableRowHeaderPackage");
 721         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage))) {
 722             GetAccessibleTableRowHeaderPackage *pkg =
 723                 (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType));
 724             windowsThreadEntryPoints->getAccessibleTableRowHeader((jobject)pkg->accessibleContext,
 725                                                                   &(pkg->rTableInfo));
 726             PrintDebugString("   ##### processing succeeded");
 727         } else {
 728             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 729                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage));
 730         }
 731         break;
 732 
 733     case cGetAccessibleTableColumnHeaderPackage:
 734         PrintDebugString("   ##### type == cGetAccessibleTableColumnHeaderPackage");
 735         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage))) {
 736             GetAccessibleTableColumnHeaderPackage *pkg =
 737                 (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType));
 738             windowsThreadEntryPoints->getAccessibleTableColumnHeader((jobject)pkg->accessibleContext,
 739                                                                      &(pkg->rTableInfo));
 740             PrintDebugString("   ##### processing succeeded");
 741         } else {
 742             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 743                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage));
 744         }
 745         break;
 746 
 747 
 748     case cGetAccessibleTableRowDescriptionPackage:
 749         PrintDebugString("   ##### type == cGetAccessibleTableRowDescriptionPackage");
 750         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage))) {
 751             GetAccessibleTableRowDescriptionPackage *pkg =
 752                 (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType));
 753             pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableRowDescription(
 754                                                                                                  (jobject)pkg->accessibleContext, pkg->row);
 755             PrintDebugString("   ##### processing succeeded");
 756         } else {
 757             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 758                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage));
 759         }
 760         break;
 761 
 762     case cGetAccessibleTableColumnDescriptionPackage:
 763         PrintDebugString("   ##### type == cGetAccessibleTableColumnDescriptionPackage");
 764         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage))) {
 765             GetAccessibleTableColumnDescriptionPackage *pkg =
 766                 (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType));
 767             pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableColumnDescription(
 768                                                                                                     (jobject)pkg->accessibleContext, pkg->column);
 769             PrintDebugString("   ##### processing succeeded");
 770         } else {
 771             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 772                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage));
 773         }
 774         break;
 775 
 776     case cGetAccessibleTableColumnSelectionCountPackage:
 777         PrintDebugString("   ##### type == cGetAccessibleTableColumnSelectionCountPackage");
 778         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage))) {
 779             GetAccessibleTableColumnSelectionCountPackage *pkg =
 780                 (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType));
 781             pkg->rCount = windowsThreadEntryPoints->getAccessibleTableColumnSelectionCount(
 782                                                                                            (jobject)pkg->accessibleTable);
 783             PrintDebugString("   ##### processing succeeded");
 784         } else {
 785             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 786                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage));
 787         }
 788         break;
 789 
 790     case cGetAccessibleTableRowSelectionCountPackage:
 791         PrintDebugString("   ##### type == cGetAccessibleTableRowSelectionCountPackage");
 792         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage))) {
 793             GetAccessibleTableRowSelectionCountPackage *pkg =
 794                 (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType));
 795 
 796             pkg->rCount = windowsThreadEntryPoints->getAccessibleTableRowSelectionCount(
 797                                                                                         (jobject)pkg->accessibleTable);
 798 
 799             PrintDebugString("   ##### processing succeeded");
 800         } else {
 801             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 802                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage));
 803         }
 804         break;
 805 
 806     case cIsAccessibleTableRowSelectedPackage:
 807         PrintDebugString("   ##### type == cIsAccessibleTableRowSelectedPackage");
 808         if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage))) {
 809             IsAccessibleTableRowSelectedPackage *pkg =
 810                 (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType));
 811             pkg->rResult = windowsThreadEntryPoints->isAccessibleTableRowSelected(
 812                                                                                   (jobject)pkg->accessibleTable, pkg->row);
 813             PrintDebugString("   ##### processing succeeded");
 814         } else {
 815             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 816                              bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage));
 817         }
 818         break;
 819 
 820     case cIsAccessibleTableColumnSelectedPackage:
 821         PrintDebugString("   ##### type == cIsAccessibleTableColumnSelectedPackage");
 822         if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage))) {
 823             IsAccessibleTableColumnSelectedPackage *pkg =
 824                 (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType));
 825             pkg->rResult = windowsThreadEntryPoints->isAccessibleTableColumnSelected(
 826                                                                                      (jobject)pkg->accessibleTable, pkg->column);
 827             PrintDebugString("   ##### processing succeeded");
 828         } else {
 829             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 830                              bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage));
 831         }
 832         break;
 833 
 834     case cGetAccessibleTableColumnSelectionsPackage:
 835         PrintDebugString("   ##### type == cGetAccessibleTableColumnSelectionsPackage");
 836         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage))) {
 837             GetAccessibleTableColumnSelectionsPackage *pkg =
 838                 (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType));
 839             PrintDebugString("     ##### cGetAccessibleTableColumnSelectionsPackage count=%d", pkg->count);
 840             windowsThreadEntryPoints->getAccessibleTableColumnSelections(
 841                                                                          (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections);
 842 
 843             for (int i = 0; i < pkg->count; i++) {
 844                 PrintDebugString("     ##### cGetAccessibleTableColumnSelectionsPackage(%d)=%d", i, pkg->rSelections[i]);
 845             }
 846 
 847             PrintDebugString("   ##### processing succeeded");
 848         } else {
 849             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 850                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage));
 851         }
 852         break;
 853 
 854 
 855     case cGetAccessibleTableRowSelectionsPackage:
 856         PrintDebugString("   ##### type == cGetAccessibleTableRowSelectionsPackage");
 857         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage))) {
 858             GetAccessibleTableRowSelectionsPackage *pkg =
 859                 (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType));
 860             windowsThreadEntryPoints->getAccessibleTableRowSelections(
 861                                                                       (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections);
 862             PrintDebugString("   ##### processing succeeded");
 863         } else {
 864             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 865                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage));
 866         }
 867         break;
 868 
 869     case cGetAccessibleTableRowPackage:
 870         PrintDebugString("   ##### type == cGetAccessibleTableRowPackage");
 871         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage))) {
 872             GetAccessibleTableRowPackage *pkg =
 873                 (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType));
 874             pkg->rRow = windowsThreadEntryPoints->getAccessibleTableRow(
 875                                                                         (jobject)pkg->accessibleTable, pkg->index);
 876             PrintDebugString("   ##### processing succeeded");
 877         } else {
 878             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 879                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage));
 880         }
 881         break;
 882 
 883     case cGetAccessibleTableColumnPackage:
 884         PrintDebugString("   ##### type == cGetAccessibleTableColumnPackage");
 885         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage))) {
 886             GetAccessibleTableColumnPackage *pkg =
 887                 (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType));
 888             pkg->rColumn = windowsThreadEntryPoints->getAccessibleTableColumn(
 889                                                                               (jobject)pkg->accessibleTable, pkg->index);
 890             PrintDebugString("   ##### processing succeeded");
 891         } else {
 892             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 893                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage));
 894         }
 895         break;
 896 
 897     case cGetAccessibleTableIndexPackage:
 898         PrintDebugString("   ##### type == cGetAccessibleTableIndexPackage");
 899         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage))) {
 900             GetAccessibleTableIndexPackage *pkg =
 901                 (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType));
 902             pkg->rIndex = windowsThreadEntryPoints->getAccessibleTableIndex(
 903                                                                             (jobject)pkg->accessibleTable, pkg->row, pkg->column);
 904             PrintDebugString("   ##### processing succeeded");
 905         } else {
 906             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 907                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage));
 908         }
 909         break;
 910 
 911         // ------------ end AccessibleTable packages ------------------
 912 
 913 
 914         // ------------ begin AccessibleRelationSet packages ------------------
 915 
 916     case cGetAccessibleRelationSetPackage:
 917         PrintDebugString("   ##### type == cGetAccessibleRelationSetPackage");
 918         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage))) {
 919             GetAccessibleRelationSetPackage *pkg =
 920                 (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType));
 921             windowsThreadEntryPoints->getAccessibleRelationSet(
 922                                                                (jobject)pkg->accessibleContext, &(pkg->rAccessibleRelationSetInfo));
 923             PrintDebugString("   ##### processing succeeded");
 924         } else {
 925             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 926                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage));
 927         }
 928         break;
 929 
 930         // ------------ end AccessibleRelationSet packages ------------------
 931 
 932         // ------------ begin AccessibleHypertext packages ------------------
 933 
 934     case cGetAccessibleHypertextPackage:
 935         PrintDebugString("   ##### type == cGetAccessibleHypertextPackage");
 936         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage))) {
 937             GetAccessibleHypertextPackage *pkg =
 938                 (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType));
 939             windowsThreadEntryPoints->getAccessibleHypertext(
 940                                                              (jobject)pkg->accessibleContext, &(pkg->rAccessibleHypertextInfo));
 941             PrintDebugString("   ##### processing succeeded");
 942         } else {
 943             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 944                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage));
 945         }
 946         break;
 947 
 948     case cActivateAccessibleHyperlinkPackage:
 949         PrintDebugString("   ##### type == cActivateAccessibleHyperlinkPackage");
 950         if (bufsize == (sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage))) {
 951             ActivateAccessibleHyperlinkPackage *pkg =
 952                 (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
 953             pkg->rResult = windowsThreadEntryPoints->activateAccessibleHyperlink(
 954                                                                                  (jobject)pkg->accessibleContext, (jobject)pkg->accessibleHyperlink);
 955             PrintDebugString("   ##### processing succeeded");
 956         } else {
 957             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 958                              bufsize, sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage));
 959         }
 960         break;
 961 
 962     case cGetAccessibleHyperlinkCountPackage:
 963         PrintDebugString("   ##### type == cGetAccessibleHyperlinkCountPackage");
 964         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage))) {
 965             GetAccessibleHyperlinkCountPackage *pkg =
 966                 (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType));
 967             pkg->rLinkCount = windowsThreadEntryPoints->getAccessibleHyperlinkCount(
 968                                                                                     (jobject)pkg->accessibleContext);
 969             PrintDebugString("   ##### processing succeeded: pkg->rLinkCount = %d", pkg->rLinkCount);
 970         } else {
 971             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 972                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage));
 973         }
 974         break;
 975 
 976     case cGetAccessibleHypertextExtPackage:
 977         PrintDebugString("   ##### type == cGetAccessibleHypertextExtPackage");
 978         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage))) {
 979             GetAccessibleHypertextExtPackage *pkg =
 980                 (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType));
 981             pkg->rSuccess = windowsThreadEntryPoints->getAccessibleHypertextExt(
 982                                                                                 (jobject)pkg->accessibleContext, pkg->startIndex, &(pkg->rAccessibleHypertextInfo));
 983             PrintDebugString("   ##### processing succeeded");
 984         } else {
 985             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
 986                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage));
 987         }
 988         break;
 989 
 990     case cGetAccessibleHypertextLinkIndexPackage:
 991         PrintDebugString("   ##### type == cGetAccessibleHypertextLinkIndexPackage");
 992         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage))) {
 993             GetAccessibleHypertextLinkIndexPackage *pkg =
 994                 (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType));
 995             pkg->rLinkIndex = windowsThreadEntryPoints->getAccessibleHypertextLinkIndex(
 996                                                                                         (jobject)pkg->hypertext, pkg->charIndex);
 997             PrintDebugString("   ##### processing succeeded");
 998         } else {
 999             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1000                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage));
1001         }
1002         break;
1003 
1004     case cGetAccessibleHyperlinkPackage:
1005         PrintDebugString("   ##### type == cGetAccessibleHyperlinkPackage");
1006         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage))) {
1007             GetAccessibleHyperlinkPackage *pkg =
1008                 (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
1009             windowsThreadEntryPoints->getAccessibleHyperlink((jobject)pkg->hypertext, pkg->linkIndex,
1010                                                              &(pkg->rAccessibleHyperlinkInfo));
1011             PrintDebugString("   ##### processing succeeded");
1012         } else {
1013             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1014                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage));
1015         }
1016         break;
1017 
1018         // ------------ end AccessibleHypertext packages
1019 
1020         // ------------ begin Accessible KeyBindings, Icons and Actions
1021 
1022     case cGetAccessibleKeyBindingsPackage:
1023         PrintDebugString("   ##### type == cGetAccessibleKeyBindingsPackage");
1024         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage))) {
1025             GetAccessibleKeyBindingsPackage *pkg =
1026                 (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType));
1027             windowsThreadEntryPoints->getAccessibleKeyBindings (
1028                                                                 (jobject)pkg->accessibleContext, &(pkg->rAccessibleKeyBindings));
1029             PrintDebugString("   ##### processing succeeded");
1030         } else {
1031             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1032                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage));
1033         }
1034         break;
1035 
1036     case cGetAccessibleIconsPackage:
1037         PrintDebugString("   ##### type == cGetAccessibleIconsPackage");
1038         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleIconsPackage))) {
1039             GetAccessibleIconsPackage *pkg =
1040                 (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType));
1041             windowsThreadEntryPoints->getAccessibleIcons (
1042                                                           (jobject)pkg->accessibleContext, &(pkg->rAccessibleIcons));
1043             PrintDebugString("   ##### processing succeeded");
1044         } else {
1045             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1046                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleIconsPackage));
1047         }
1048         break;
1049 
1050 
1051     case cGetAccessibleActionsPackage:
1052         PrintDebugString("   ##### type == cGetAccessibleActionsPackage");
1053         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleActionsPackage))) {
1054             GetAccessibleActionsPackage *pkg =
1055                 (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType));
1056             windowsThreadEntryPoints->getAccessibleActions (
1057                                                             (jobject)pkg->accessibleContext, &(pkg->rAccessibleActions));
1058             PrintDebugString("   ##### processing succeeded");
1059         } else {
1060             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1061                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleActionsPackage));
1062         }
1063         break;
1064 
1065     case cDoAccessibleActionsPackage:
1066         PrintDebugString("   ##### type == cDoAccessibleActionsPackage");
1067         if (bufsize == (sizeof(PackageType) + sizeof(DoAccessibleActionsPackage))) {
1068             DoAccessibleActionsPackage *pkg =
1069                 (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType));
1070             pkg->rResult =
1071                 windowsThreadEntryPoints->doAccessibleActions((jobject)pkg->accessibleContext, &(pkg->actionsToDo),
1072                                                               &(pkg->failure));
1073             PrintDebugString("   ##### processing succeeded");
1074         } else {
1075             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1076                              bufsize, sizeof(PackageType) + sizeof(DoAccessibleActionsPackage));
1077         }
1078         break;
1079 
1080         // ------------ begin addtional methods for Teton
1081 
1082     case cGetVirtualAccessibleNamePackage:
1083         PrintDebugString("   ##### type == GetVirtualAccessibleNamePackage");
1084         if (bufsize == (sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage))) {
1085             GetVirtualAccessibleNamePackage *pkg =
1086                 (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType));
1087             windowsThreadEntryPoints->getVirtualAccessibleName ((const jobject)pkg->accessibleContext,
1088                                                              pkg->rName,
1089                                                              pkg->len);
1090             PrintDebugString("   ##### processing succeeded");
1091         } else {
1092             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1093                              bufsize, sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage));
1094         }
1095         break;
1096 
1097     case cRequestFocusPackage:
1098         PrintDebugString("   ##### type == RequestFocusPackage");
1099         if (bufsize == (sizeof(PackageType) + sizeof(RequestFocusPackage))) {
1100             RequestFocusPackage *pkg =
1101                 (RequestFocusPackage *) (buffer + sizeof(PackageType));
1102             windowsThreadEntryPoints->requestFocus (
1103                                                     (jobject)pkg->accessibleContext);
1104             PrintDebugString("   ##### processing succeeded");
1105         } else {
1106             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1107                              bufsize, sizeof(PackageType) + sizeof(RequestFocusPackage));
1108         }
1109         break;
1110 
1111     case cSelectTextRangePackage:
1112         PrintDebugString("   ##### type == SelectTextRangePackage");
1113         if (bufsize == (sizeof(PackageType) + sizeof(SelectTextRangePackage))) {
1114             SelectTextRangePackage *pkg =
1115                 (SelectTextRangePackage *) (buffer + sizeof(PackageType));
1116             windowsThreadEntryPoints->selectTextRange (
1117                                                        (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex);
1118             PrintDebugString("   ##### processing succeeded");
1119         } else {
1120             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1121                              bufsize, sizeof(PackageType) + sizeof(SelectTextRangePackage));
1122         }
1123         break;
1124 
1125     case cGetTextAttributesInRangePackage:
1126         PrintDebugString("   ##### type == GetTextAttributesInRangePackage");
1127         if (bufsize == (sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage))) {
1128             GetTextAttributesInRangePackage *pkg =
1129                 (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType));
1130             windowsThreadEntryPoints->getTextAttributesInRange (
1131                                                                 (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex,
1132                                                                 (AccessibleTextAttributesInfo *)&(pkg->attributes),
1133                                                                 &(pkg->rLength));
1134             PrintDebugString("   ##### processing succeeded");
1135         } else {
1136             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1137                              bufsize, sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage));
1138         }
1139         break;
1140 
1141 
1142     case cGetVisibleChildrenCountPackage:
1143         PrintDebugString("   ##### type == GetVisibleChildrenCountPackage");
1144         if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage))) {
1145             GetVisibleChildrenCountPackage *pkg =
1146                 (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType));
1147             pkg->rChildrenCount = windowsThreadEntryPoints->getVisibleChildrenCount ((jobject)pkg->accessibleContext);
1148 
1149             PrintDebugString("   ##### processing succeeded");
1150         } else {
1151             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1152                              bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage));
1153         }
1154         break;
1155 
1156     case cGetVisibleChildrenPackage:
1157         PrintDebugString("   ##### type == GetVisibleChildrenPackage");
1158         if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenPackage))) {
1159             GetVisibleChildrenPackage *pkg =
1160                 (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType));
1161             pkg->rSuccess = windowsThreadEntryPoints->getVisibleChildren ((jobject)pkg->accessibleContext,
1162                                                                           pkg->startIndex,
1163                                                                           &(pkg->rVisibleChildrenInfo));
1164 
1165             PrintDebugString("   ##### processing succeeded");
1166         } else {
1167             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1168                              bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenPackage));
1169         }
1170         break;
1171 
1172     case cSetCaretPositionPackage:
1173         PrintDebugString("   ##### type == SetCaretPositionPackage");
1174         if (bufsize == (sizeof(PackageType) + sizeof(SetCaretPositionPackage))) {
1175             SetCaretPositionPackage *pkg =
1176                 (SetCaretPositionPackage *) (buffer + sizeof(PackageType));
1177             windowsThreadEntryPoints->setCaretPosition (
1178                                                         (jobject)pkg->accessibleContext, pkg->position);
1179             PrintDebugString("   ##### processing succeeded");
1180         } else {
1181             PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
1182                              bufsize, sizeof(PackageType) + sizeof(SetCaretPositionPackage));
1183         }
1184         break;
1185 
1186         // ------------ end additional methods for Teton
1187 
1188         // ------------ end Accessible KeyBindings, Icons and Actions
1189 
1190         // ------------ Accessible Text packages ------------------
1191 
1192     case cGetAccessibleTextInfoPackage:
1193         PrintDebugString("   type == cGetAccessibleTextInfoPackage");
1194         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage))) {
1195             GetAccessibleTextInfoPackage *pkg =
1196                 (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType));
1197             windowsThreadEntryPoints->getAccessibleTextInfo((jobject)pkg->AccessibleContext,
1198                                                             &(pkg->rTextInfo), pkg->x, pkg->y);
1199         } else {
1200             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1201                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage));
1202         }
1203         break;
1204 
1205     case cGetAccessibleTextItemsPackage:
1206         PrintDebugString("   type == cGetAccessibleTextItemsPackage");
1207         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage))) {
1208             GetAccessibleTextItemsPackage *pkg =
1209                 (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType));
1210             windowsThreadEntryPoints->getAccessibleTextItems((jobject)pkg->AccessibleContext,
1211                                                              &(pkg->rTextItemsInfo), pkg->index);
1212         } else {
1213             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1214                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage));
1215         }
1216         break;
1217 
1218     case cGetAccessibleTextSelectionInfoPackage:
1219         PrintDebugString("   type == cGetAccessibleTextSelectionInfoPackage");
1220         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage))) {
1221             GetAccessibleTextSelectionInfoPackage *pkg =
1222                 (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType));
1223             windowsThreadEntryPoints->getAccessibleTextSelectionInfo(
1224                                                                      (jobject)pkg->AccessibleContext, &(pkg->rTextSelectionItemsInfo));
1225         } else {
1226             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1227                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage));
1228         }
1229         break;
1230 
1231     case cGetAccessibleTextAttributeInfoPackage:
1232         PrintDebugString("   type == cGetAccessibleTextAttributeInfoPackage");
1233         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage))) {
1234             GetAccessibleTextAttributeInfoPackage *pkg =
1235                 (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType));
1236             windowsThreadEntryPoints->getAccessibleTextAttributes(
1237                                                                   (jobject)pkg->AccessibleContext, pkg->index, (AccessibleTextAttributesInfo *) &(pkg->rAttributeInfo));
1238         } else {
1239             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1240                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage));
1241         }
1242         break;
1243 
1244     case cGetAccessibleTextRectInfoPackage:
1245         PrintDebugString("   type == cGetAccessibleTextRectInfoPackage");
1246         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage))) {
1247             GetAccessibleTextRectInfoPackage *pkg =
1248                 (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType));
1249             windowsThreadEntryPoints->getAccessibleTextRect((jobject)pkg->AccessibleContext,
1250                                                             &(pkg->rTextRectInfo), pkg->index);
1251         } else {
1252             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1253                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage));
1254         }
1255         break;
1256 
1257     case cGetCaretLocationPackage:
1258         PrintDebugString("   type == cGetCaretLocationPackage");
1259         if (bufsize == (sizeof(PackageType) + sizeof(GetCaretLocationPackage))) {
1260             GetCaretLocationPackage *pkg =
1261                 (GetCaretLocationPackage *) (buffer + sizeof(PackageType));
1262             windowsThreadEntryPoints->getCaretLocation((jobject)pkg->AccessibleContext,
1263                                                             &(pkg->rTextRectInfo), pkg->index);
1264         } else {
1265             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1266                              bufsize, sizeof(PackageType) + sizeof(GetCaretLocationPackage));
1267         }
1268         break;
1269 
1270     case cGetAccessibleTextLineBoundsPackage:
1271         PrintDebugString("   type == cGetAccessibleTextLineBoundsPackage");
1272         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage))) {
1273             GetAccessibleTextLineBoundsPackage *pkg =
1274                 (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType));
1275             windowsThreadEntryPoints->getAccessibleTextLineBounds((jobject)pkg->AccessibleContext,
1276                                                                   pkg->index, &(pkg->rLineStart), &(pkg->rLineEnd));
1277         } else {
1278             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1279                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage));
1280         }
1281         break;
1282 
1283     case cGetAccessibleTextRangePackage:
1284         PrintDebugString("   type == cGetAccessibleTextRangePackage");
1285         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage))) {
1286             GetAccessibleTextRangePackage *pkg =
1287                 (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType));
1288             windowsThreadEntryPoints->getAccessibleTextRange((jobject)pkg->AccessibleContext,
1289                                                              pkg->start, pkg->end, (wchar_t *) &(pkg->rText), (sizeof(pkg->rText) / sizeof(wchar_t)));
1290         } else {
1291             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1292                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage));
1293         }
1294         break;
1295 
1296 
1297         // ------------ Accessible Value packages ------------------
1298 
1299     case cGetCurrentAccessibleValueFromContextPackage:
1300         PrintDebugString("   type == cGetCurrentAccessibleValueFromContextPackage");
1301         if (bufsize == (sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage))) {
1302             GetCurrentAccessibleValueFromContextPackage *pkg =
1303                 (GetCurrentAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
1304             windowsThreadEntryPoints->getCurrentAccessibleValueFromContext((jobject)pkg->AccessibleContext,
1305                                                                            (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
1306         } else {
1307             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1308                              bufsize, sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage));
1309         }
1310         break;
1311 
1312     case cGetMaximumAccessibleValueFromContextPackage:
1313         PrintDebugString("   type == cGetMaximumAccessibleValueFromContextPackage");
1314         if (bufsize == (sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage))) {
1315             GetMaximumAccessibleValueFromContextPackage *pkg =
1316                 (GetMaximumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
1317             windowsThreadEntryPoints->getMaximumAccessibleValueFromContext((jobject)pkg->AccessibleContext,
1318                                                                            (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
1319         } else {
1320             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1321                              bufsize, sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage));
1322         }
1323         break;
1324 
1325     case cGetMinimumAccessibleValueFromContextPackage:
1326         PrintDebugString("   type == cGetMinimumAccessibleValueFromContextPackage");
1327         if (bufsize == (sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage))) {
1328             GetMinimumAccessibleValueFromContextPackage *pkg =
1329                 (GetMinimumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
1330             windowsThreadEntryPoints->getMinimumAccessibleValueFromContext((jobject)pkg->AccessibleContext,
1331                                                                            (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
1332         } else {
1333             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1334                              bufsize, sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage));
1335         }
1336         break;
1337 
1338         // ------------ Accessible Selection packages ------------------
1339 
1340     case cAddAccessibleSelectionFromContextPackage:
1341         PrintDebugString("   type == cAddAccessibleSelectionFromContextPackage");
1342         if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage))) {
1343             AddAccessibleSelectionFromContextPackage *pkg =
1344                 (AddAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
1345             windowsThreadEntryPoints->addAccessibleSelectionFromContext((jobject)pkg->AccessibleContext,
1346                                                                         pkg->index);
1347         } else {
1348             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1349                              bufsize, sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage));
1350         }
1351         break;
1352 
1353     case cClearAccessibleSelectionFromContextPackage:
1354         PrintDebugString("   type == cClearAccessibleSelectionFromContextPackage");
1355         if (bufsize == (sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage))) {
1356             ClearAccessibleSelectionFromContextPackage *pkg =
1357                 (ClearAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
1358             windowsThreadEntryPoints->clearAccessibleSelectionFromContext((jobject)pkg->AccessibleContext);
1359         } else {
1360             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1361                              bufsize, sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage));
1362         }
1363         break;
1364 
1365     case cGetAccessibleSelectionFromContextPackage:
1366         PrintDebugString("   type == cGetAccessibleSelectionFromContextPackage");
1367         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage))) {
1368             GetAccessibleSelectionFromContextPackage *pkg =
1369                 (GetAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
1370             pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleSelectionFromContext(
1371                                                                                                   (jobject)pkg->AccessibleContext, pkg->index);
1372         } else {
1373             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1374                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage));
1375         }
1376         break;
1377 
1378     case cGetAccessibleSelectionCountFromContextPackage:
1379         PrintDebugString("   type == cGetAccessibleSelectionCountFromContextPackage");
1380         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage))) {
1381             GetAccessibleSelectionCountFromContextPackage *pkg =
1382                 (GetAccessibleSelectionCountFromContextPackage *) (buffer + sizeof(PackageType));
1383             pkg->rCount = windowsThreadEntryPoints->getAccessibleSelectionCountFromContext(
1384                                                                                            (jobject)pkg->AccessibleContext);
1385         } else {
1386             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1387                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage));
1388         }
1389         break;
1390 
1391     case cIsAccessibleChildSelectedFromContextPackage:
1392         PrintDebugString("   type == cIsAccessibleChildSelectedFromContextPackage");
1393         if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage))) {
1394             IsAccessibleChildSelectedFromContextPackage *pkg =
1395                 (IsAccessibleChildSelectedFromContextPackage *) (buffer + sizeof(PackageType));
1396             pkg->rResult = windowsThreadEntryPoints->isAccessibleChildSelectedFromContext(
1397                                                                                           (jobject)pkg->AccessibleContext, pkg->index);
1398         } else {
1399             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1400                              bufsize, sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage));
1401         }
1402         break;
1403 
1404     case cRemoveAccessibleSelectionFromContextPackage:
1405         PrintDebugString("   type == cRemoveAccessibleSelectionFromContextPackage");
1406         if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage))) {
1407             RemoveAccessibleSelectionFromContextPackage *pkg =
1408                 (RemoveAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
1409             windowsThreadEntryPoints->removeAccessibleSelectionFromContext((jobject)pkg->AccessibleContext,
1410                                                                            pkg->index);
1411         } else {
1412             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1413                              bufsize, sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage));
1414         }
1415         break;
1416 
1417     case cSelectAllAccessibleSelectionFromContextPackage:
1418         PrintDebugString("   type == cSelectAllAccessibleSelectionFromContextPackage");
1419         if (bufsize == (sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage))) {
1420             SelectAllAccessibleSelectionFromContextPackage *pkg =
1421                 (SelectAllAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
1422             windowsThreadEntryPoints->selectAllAccessibleSelectionFromContext((jobject)pkg->AccessibleContext);
1423         } else {
1424             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1425                              bufsize, sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage));
1426         }
1427         break;
1428 
1429 
1430         // ------------ event notification management packages ------------------
1431 
1432     case cAddJavaEventNotificationPackage:
1433         PrintDebugString("   type = cAddJavaEventNotificationPackage");
1434         if (bufsize == (sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage))) {
1435             AddJavaEventNotificationPackage *pkg =
1436                 (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
1437             addJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow ) );
1438         } else {
1439             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1440                              bufsize, sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage));
1441         }
1442         break;
1443 
1444     case cRemoveJavaEventNotificationPackage:
1445         PrintDebugString("   type = cRemoveJavaEventNotificationPackage");
1446         if (bufsize == (sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage))) {
1447             RemoveJavaEventNotificationPackage *pkg =
1448                 (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
1449             removeJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow ));
1450         } else {
1451             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1452                              bufsize, sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage));
1453         }
1454         break;
1455 
1456     case cAddAccessibilityEventNotificationPackage:
1457         PrintDebugString("   type = cAddAccessibilityEventNotificationPackage");
1458         if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage))) {
1459             AddAccessibilityEventNotificationPackage *pkg =
1460                 (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
1461             addAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow));
1462         } else {
1463             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1464                              bufsize, sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage));
1465         }
1466         break;
1467 
1468     case cRemoveAccessibilityEventNotificationPackage:
1469         PrintDebugString("   type = cRemoveAccessibilityEventNotificationPackage");
1470         if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage))) {
1471             RemoveAccessibilityEventNotificationPackage *pkg =
1472                 (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
1473             removeAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow));
1474         } else {
1475             PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
1476                              bufsize, sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage));
1477         }
1478         break;
1479 
1480     default:
1481         PrintDebugString("   processing FAILED!! -> don't know how to handle type = %X", *type);
1482         returnVal = -1;
1483         break;
1484     }
1485 
1486     PrintDebugString("   package processing completed");
1487     return returnVal;
1488 }
1489 
1490 
1491 // -----------------------------
1492 
1493 
1494 /**
1495  * MemoryMappedFileCreated
1496  *          - WindowsDLL letting us know it's created a memory-mapped file
1497  *            for IPC.  We need to open it and write a magic string into
1498  *            it to let the WindowsDLL know all is OK.  Also we need to
1499  *            set up our own data structures to communicate with the
1500  *            WindowsDLL
1501  *
1502  */
1503 LRESULT
1504 JavaAccessBridge::MemoryMappedFileCreated(HWND ATBridgeDLLWindow, char *filename) {
1505     PrintDebugString("  in MemoryMappedFileCreated(%p, %s)!", ATBridgeDLLWindow, filename);
1506     AccessBridgeATInstance *newAT =
1507         new AccessBridgeATInstance(dialogWindow, ATBridgeDLLWindow, filename, ATs);
1508     PrintDebugString("    just created a new ATInstance = %p, old = %p", newAT, ATs);
1509     ATs = newAT;
1510 
1511     LRESULT returnVal = ATs->initiateIPC();
1512     if (returnVal == 0) {
1513         PrintDebugString("  Successfully initiated IPC with AT!!!");
1514     } else {
1515         PrintDebugString("  ERROR: Failed to initiate IPC with AT!!!");
1516     }
1517 
1518     return returnVal;
1519 }
1520 
1521 
1522 /**
1523  * WindowsATDestroyed - lets the JavaABDLL know a Windows AT disappeared
1524  *
1525  */
1526 void
1527 JavaAccessBridge::WindowsATDestroyed(HWND ATBridgeDLLWindow) {
1528     PrintDebugString("\r\nin JavaAccessBridge::WindowsATDestroyed(%p)", ATBridgeDLLWindow);
1529     if (ATs == (AccessBridgeATInstance *) 0) {
1530         PrintDebugString("  ERROR!! -> ATs == 0! (shouldn't happen here)");
1531         return;
1532     }
1533 
1534     AccessBridgeATInstance *currentAT = ATs;
1535     AccessBridgeATInstance *previousAT = ATs;
1536     if (ATs->winAccessBridgeWindow == ATBridgeDLLWindow) {
1537         ATs = ATs->nextATInstance;
1538         // remove event notification for this AT
1539         removeJavaEventNotification(currentAT->javaEventMask, ATBridgeDLLWindow);
1540         removeAccessibilityEventNotification(currentAT->accessibilityEventMask, ATBridgeDLLWindow);
1541         delete currentAT;
1542         PrintDebugString("  data structures successfully removed");
1543     } else {
1544         while (currentAT != (AccessBridgeATInstance *) NULL) {
1545             if (currentAT->winAccessBridgeWindow == ATBridgeDLLWindow) {
1546                 previousAT->nextATInstance = currentAT->nextATInstance;
1547                 delete currentAT;
1548                 PrintDebugString("  data structures successfully removed");
1549                 return;
1550             } else {
1551                 previousAT = currentAT;
1552                 currentAT = currentAT->nextATInstance;
1553             }
1554         }
1555         PrintDebugString("  ERROR!! couldn't find matching data structures!");
1556     }
1557 }
1558 
1559 
1560 // -----------------------------
1561 
1562 
1563 /**
1564  * releaseJavaObject - lets the JavaVM know it can release the Java Object
1565  *
1566  * Note: once you have made this call, the JavaVM will garbage collect
1567  * the jobject you pass in.  If you later use that jobject in another
1568  * call, you will cause all maner of havoc!
1569  *
1570  */
1571 void
1572 JavaAccessBridge::releaseJavaObject(jobject object) {
1573     PrintDebugString("In JavaAccessBridge::releaseJavaObject");
1574     PrintDebugString("  object X: %p", object);
1575     if (windowsThreadJNIEnv != (JNIEnv *) 0) {
1576         windowsThreadJNIEnv->DeleteGlobalRef(object);
1577         PrintDebugString("  global reference deleted.", object);
1578     } else {
1579         PrintDebugString("  Error! windowsThreadJNIEnv == 0");
1580     }
1581 }
1582 
1583 // -----------------------------
1584 
1585 /**
1586  * addJavaEventNotification - this AT now wants this type of events
1587  *
1588  */
1589 void
1590 JavaAccessBridge::addJavaEventNotification(jlong type, HWND DLLwindow) {
1591     // walk through list of ATs, find this one and add this type
1592     // and, if we weren't listening for these before, ask Java for 'em
1593     PrintDebugString("  adding Java event type %016I64X to HWND %p", type, DLLwindow);
1594     AccessBridgeATInstance *ati = ATs;
1595     long globalEventMask = 0;
1596     while (ati != (AccessBridgeATInstance *) 0) {
1597         if (ati->winAccessBridgeWindow == DLLwindow) {
1598             ati->javaEventMask |= type;
1599             PrintDebugString("  found HWND, javaEventMask now is %X", ati->javaEventMask);
1600         } else {
1601             globalEventMask |= ati->javaEventMask;
1602         }
1603         ati = ati->nextATInstance;
1604     }
1605     PrintDebugString("  union of all Java AT event masks: %X", globalEventMask);
1606     if (!(globalEventMask & type)) {
1607         // no other ATs wanted this event;
1608         // start getting them from Java
1609         PrintDebugString("  no other AT wanted this Java event (so not registered); adding to AccessBridge.java");
1610         windowsThreadEntryPoints->addJavaEventNotification(type);
1611     }
1612 }
1613 
1614 /**
1615  * removeJavaEventNotification - this AT no longer wants this type of events
1616  *
1617  */
1618 void
1619 JavaAccessBridge::removeJavaEventNotification(jlong type, HWND DLLwindow) {
1620     // walk through list of ATs, find this one and remove this type
1621     // and, if no other AT wants 'em either, tell Java we no longer want 'em
1622     PrintDebugString("  removing Java event type %016I64X from HWND %p", type, DLLwindow);
1623     AccessBridgeATInstance *ati = ATs;
1624     long globalEventMask = 0;
1625     while (ati != (AccessBridgeATInstance *) 0) {
1626         if (ati->winAccessBridgeWindow == DLLwindow) {
1627             ati->javaEventMask &= (0xFFFFFFFF - type);
1628             PrintDebugString("  found HWND, javaEventMask now is %X", ati->javaEventMask);
1629         } else {
1630             globalEventMask |= ati->javaEventMask;
1631         }
1632         ati = ati->nextATInstance;
1633     }
1634     PrintDebugString("  union of all Java AT event masks: %X", globalEventMask);
1635     if (!(globalEventMask & type)) {
1636         // no other ATs wanted this event;
1637         // stop getting them from Java
1638         PrintDebugString("  no other AT wanted this Java event (so can remove); removing from AccessBridge.java");
1639         windowsThreadEntryPoints->removeJavaEventNotification(type);
1640     }
1641 }
1642 
1643 
1644 /**
1645  * addAccesibilityEventNotification - this AT now wants this type of events
1646  *
1647  */
1648 void
1649 JavaAccessBridge::addAccessibilityEventNotification(jlong type, HWND DLLwindow) {
1650     // walk through list of ATs, find this one and add this type
1651     // and, if we weren't listening for these before, ask Java for 'em
1652     PrintDebugString("  adding Accesibility event type %016I64X to HWND %p", type, DLLwindow);
1653     AccessBridgeATInstance *ati = ATs;
1654     long globalEventMask = 0;
1655     while (ati != (AccessBridgeATInstance *) 0) {
1656         if (ati->winAccessBridgeWindow == DLLwindow) {
1657             ati->accessibilityEventMask |= type;
1658             PrintDebugString("  found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask);
1659         } else {
1660             globalEventMask |= ati->accessibilityEventMask;
1661         }
1662         ati = ati->nextATInstance;
1663     }
1664     PrintDebugString("  union of all Accessibility AT event masks: %X", globalEventMask);
1665     if (!(globalEventMask & type)) {
1666         // no other ATs wanted this event;
1667         // start getting them from Java
1668         PrintDebugString("  no other AT wanted this Accesibility event (so not registered); adding to AccessBridge.java");
1669         windowsThreadEntryPoints->addAccessibilityEventNotification(type);
1670     }
1671 }
1672 
1673 /**
1674  * removeAccesibilityEventNotification - this AT no longer wants this type of events
1675  *
1676  */
1677 void
1678 JavaAccessBridge::removeAccessibilityEventNotification(jlong type, HWND DLLwindow) {
1679     // walk through list of ATs, find this one and remove this type
1680     // and, if no other AT wants 'em either, tell Java we no longer want 'em
1681     PrintDebugString("  removing Accesibility event type %016I64X from HWND %p", type, DLLwindow);
1682     AccessBridgeATInstance *ati = ATs;
1683     long globalEventMask = 0;
1684     while (ati != (AccessBridgeATInstance *) 0) {
1685         if (ati->winAccessBridgeWindow == DLLwindow) {
1686             ati->accessibilityEventMask &= (0xFFFFFFFF - type);
1687             PrintDebugString("  found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask);
1688         } else {
1689             globalEventMask |= ati->accessibilityEventMask;
1690         }
1691         ati = ati->nextATInstance;
1692     }
1693     PrintDebugString("  union of all Accessibility AT event masks: %X", globalEventMask);
1694     if (!(globalEventMask & type)) {
1695         // no other ATs wanted this event;
1696         // stop getting them from Java
1697         PrintDebugString("  no other AT wanted this Accessibility event (so can remove); removing from AccessBridge.java");
1698         windowsThreadEntryPoints->removeAccessibilityEventNotification(type);
1699     }
1700 }
1701 
1702 
1703 
1704 
1705 /**
1706  * firePropertyCaretChange
1707  *
1708  */
1709 void
1710 JavaAccessBridge::firePropertyCaretChange(JNIEnv *env, jobject callingObj,
1711                                           jobject event, jobject source,
1712                                           jint oldValue, jint newValue) {
1713 
1714     PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyCaretChanged(%p, %p, %p, %p, %d, %d)",
1715                      env, callingObj, event,
1716                      source, oldValue, newValue);
1717 
1718     // sanity check
1719     if (ATs == (AccessBridgeATInstance *) 0) {
1720         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
1721         return;         // panic!
1722     }
1723 
1724     // common setup
1725     char buffer[sizeof(PackageType) + sizeof(PropertyCaretChangePackage)];
1726     PackageType *type = (PackageType *) buffer;
1727     PropertyCaretChangePackage *pkg = (PropertyCaretChangePackage *) (buffer + sizeof(PackageType));
1728     *type = cPropertyCaretChangePackage;
1729     pkg->vmID = (long) dialogWindow;
1730 
1731     // make new Global Refs and send events only to those ATs that want 'em
1732     AccessBridgeATInstance *ati = ATs;
1733     while (ati != (AccessBridgeATInstance *) 0) {
1734         if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) {
1735 
1736             PrintDebugString("  sending to AT");
1737 
1738             // make new GlobalRefs for this AT
1739             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
1740             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
1741 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1742             PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
1743             PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
1744 #else // JOBJECT64 is jlong (64 bit)
1745             PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
1746             PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
1747 #endif
1748 
1749             pkg->oldPosition = oldValue;
1750             pkg->newPosition = newValue;
1751 
1752             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyCaretChangeEvent);
1753         }
1754         ati = ati->nextATInstance;
1755     }
1756     PrintDebugString("  done with propertyCaretChange event");
1757 }
1758 
1759 /**
1760  * firePropertyDescriptionChange
1761  *
1762  */
1763 void
1764 JavaAccessBridge::firePropertyDescriptionChange(JNIEnv *env, jobject callingObj,
1765                                                 jobject event, jobject source,
1766                                                 jstring oldValue, jstring newValue){
1767 
1768     PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyDescriptionChanged(%p, %p, %p, %p, %p, %p)",
1769                      env, callingObj, event,
1770                      source, oldValue, newValue);
1771 
1772     // sanity check
1773     if (ATs == (AccessBridgeATInstance *) 0) {
1774         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
1775         return;         // panic!
1776     }
1777 
1778     // common setup
1779     const wchar_t *stringBytes;
1780     char buffer[sizeof(PackageType) + sizeof(PropertyDescriptionChangePackage)];
1781     PackageType *type = (PackageType *) buffer;
1782     PropertyDescriptionChangePackage *pkg = (PropertyDescriptionChangePackage *) (buffer + sizeof(PackageType));
1783     *type = cPropertyDescriptionChangePackage;
1784     pkg->vmID = (long) dialogWindow;
1785 
1786     // make new Global Refs and send events only to those ATs that want 'em
1787     AccessBridgeATInstance *ati = ATs;
1788     while (ati != (AccessBridgeATInstance *) 0) {
1789         if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) {
1790 
1791             PrintDebugString("  sending to AT");
1792 
1793             // make new GlobalRefs for this AT
1794             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
1795             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
1796 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1797             PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
1798             PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
1799 #else // JOBJECT64 is jlong (64 bit)
1800             PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
1801             PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
1802 #endif
1803 
1804             if (oldValue != (jstring) 0) {
1805                 stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
1806                 if (stringBytes == NULL) {
1807                     if (!env->ExceptionCheck()) {
1808                         jclass cls = env->FindClass("java/lang/OutOfMemoryError");
1809                         if (cls != NULL) {
1810                             env->ThrowNew(cls, NULL);
1811                         }
1812                     }
1813                     return;
1814                 }
1815                 wcsncpy(pkg->oldDescription, stringBytes, (sizeof(pkg->oldDescription) / sizeof(wchar_t)));
1816                 env->ReleaseStringChars(oldValue, stringBytes);
1817             } else {
1818                 wcsncpy(pkg->oldDescription, L"(null)", (sizeof(pkg->oldDescription) / sizeof(wchar_t)));
1819             }
1820 
1821             if (newValue != (jstring) 0) {
1822                 stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
1823                 if (stringBytes == NULL) {
1824                    if (!env->ExceptionCheck()) {
1825                         jclass cls = env->FindClass("java/lang/OutOfMemoryError");
1826                         if (cls != NULL) {
1827                             env->ThrowNew(cls, NULL);
1828                         }
1829                     }
1830                     return;
1831                 }
1832                 wcsncpy(pkg->newDescription, stringBytes, (sizeof(pkg->newDescription) / sizeof(wchar_t)));
1833                 env->ReleaseStringChars(newValue, stringBytes);
1834             } else {
1835                 wcsncpy(pkg->newDescription, L"(null)", (sizeof(pkg->newDescription) / sizeof(wchar_t)));
1836             }
1837 
1838             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyDescriptionChangeEvent);
1839         }
1840         ati = ati->nextATInstance;
1841     }
1842     PrintDebugString("  done with propertyDescriptionChange event");
1843 }
1844 
1845 /**
1846  * firePropertyNameChange
1847  *
1848  */
1849 void
1850 JavaAccessBridge::firePropertyNameChange(JNIEnv *env, jobject callingObj,
1851                                          jobject event, jobject source,
1852                                          jstring oldValue, jstring newValue){
1853 
1854     PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyNameChanged(%p, %p, %p, %p, %p, %p)",
1855                      env, callingObj, event,
1856                      source, oldValue, newValue);
1857 
1858     // sanity check
1859     if (ATs == (AccessBridgeATInstance *) 0) {
1860         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
1861         return;         // panic!
1862     }
1863 
1864     // common setup
1865     const wchar_t *stringBytes;
1866     char buffer[sizeof(PackageType) + sizeof(PropertyNameChangePackage)];
1867     PackageType *type = (PackageType *) buffer;
1868     PropertyNameChangePackage *pkg = (PropertyNameChangePackage *) (buffer + sizeof(PackageType));
1869     *type = cPropertyNameChangePackage;
1870     pkg->vmID = (long) dialogWindow;
1871 
1872     // make new Global Refs and send events only to those ATs that want 'em
1873     AccessBridgeATInstance *ati = ATs;
1874     while (ati != (AccessBridgeATInstance *) 0) {
1875         if (ati->accessibilityEventMask & cPropertyNameChangeEvent) {
1876 
1877             PrintDebugString("  sending to AT");
1878 
1879             // make new GlobalRefs for this AT
1880             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
1881             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
1882 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1883             PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
1884             PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
1885 #else // JOBJECT64 is jlong (64 bit)
1886             PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
1887             PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
1888 #endif
1889 
1890             if (oldValue != (jstring) 0) {
1891                 stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
1892                 if (stringBytes == NULL) {
1893                     if (!env->ExceptionCheck()) {
1894                         jclass cls = env->FindClass("java/lang/OutOfMemoryError");
1895                         if (cls != NULL) {
1896                             env->ThrowNew(cls, NULL);
1897                         }
1898                     }
1899                     return;
1900                 }
1901                 wcsncpy(pkg->oldName, stringBytes, (sizeof(pkg->oldName) / sizeof(wchar_t)));
1902                 env->ReleaseStringChars(oldValue, stringBytes);
1903             } else {
1904                 wcsncpy(pkg->oldName, L"(null)", (sizeof(pkg->oldName) / sizeof(wchar_t)));
1905             }
1906 
1907             if (newValue != (jstring) 0) {
1908                 stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
1909                 if (stringBytes == NULL) {
1910                     if (!env->ExceptionCheck()) {
1911                         jclass cls = env->FindClass("java/lang/OutOfMemoryError");
1912                         if (cls != NULL) {
1913                             env->ThrowNew(cls, NULL);
1914                         }
1915                     }
1916                     return;
1917                 }
1918                 wcsncpy(pkg->newName, stringBytes, (sizeof(pkg->newName) / sizeof(wchar_t)));
1919                 env->ReleaseStringChars(newValue, stringBytes);
1920             } else {
1921                 wcsncpy(pkg->newName, L"(null)", (sizeof(pkg->newName) / sizeof(wchar_t)));
1922             }
1923 
1924             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyNameChangeEvent);
1925         }
1926         ati = ati->nextATInstance;
1927     }
1928     PrintDebugString("  done with propertyNameChange event");
1929 }
1930 
1931 
1932 /**
1933  * firePropertySelectionChange
1934  *
1935  */
1936 void
1937 JavaAccessBridge::firePropertySelectionChange(JNIEnv *env, jobject callingObj,
1938                                               jobject event, jobject source) {
1939 
1940     PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertySelectionChanged(%p, %p, %p, %p)",
1941                      env, callingObj, event, source);
1942 
1943     // sanity check
1944     if (ATs == (AccessBridgeATInstance *) 0) {
1945         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
1946         return;         // panic!
1947     }
1948 
1949     // common setup
1950     char buffer[sizeof(PackageType) + sizeof(PropertySelectionChangePackage)];
1951     PackageType *type = (PackageType *) buffer;
1952     PropertySelectionChangePackage *pkg = (PropertySelectionChangePackage *) (buffer + sizeof(PackageType));
1953     *type = cPropertySelectionChangePackage;
1954     pkg->vmID = (long) dialogWindow;
1955 
1956     // make new Global Refs and send events only to those ATs that want 'em
1957     AccessBridgeATInstance *ati = ATs;
1958     while (ati != (AccessBridgeATInstance *) 0) {
1959         if (ati->accessibilityEventMask & cPropertySelectionChangeEvent) {
1960 
1961             PrintDebugString("  sending to AT");
1962 
1963             // make new GlobalRefs for this AT
1964             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
1965             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
1966 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
1967             PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
1968             PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
1969 #else // JOBJECT64 is jlong (64 bit)
1970             PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
1971             PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
1972 #endif
1973 
1974             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertySelectionChangeEvent);
1975         }
1976         ati = ati->nextATInstance;
1977     }
1978     PrintDebugString("  done with propertySelectionChange event");
1979 }
1980 
1981 
1982 /**
1983  * firePropertyStateChange
1984  *
1985  */
1986 void
1987 JavaAccessBridge::firePropertyStateChange(JNIEnv *env, jobject callingObj,
1988                                           jobject event, jobject source,
1989                                           jstring oldValue, jstring newValue){
1990 
1991     PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyStateChanged(%p, %p, %p, %p, %p, %p)",
1992                      env, callingObj, event,
1993                      source, oldValue, newValue);
1994 
1995     // sanity check
1996     if (ATs == (AccessBridgeATInstance *) 0) {
1997         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
1998         return;         // panic!
1999     }
2000 
2001     // common setup
2002     const wchar_t *stringBytes;
2003     char buffer[sizeof(PackageType) + sizeof(PropertyStateChangePackage)];
2004     PackageType *type = (PackageType *) buffer;
2005     PropertyStateChangePackage *pkg = (PropertyStateChangePackage *) (buffer + sizeof(PackageType));
2006     *type = cPropertyStateChangePackage;
2007     pkg->vmID = (long) dialogWindow;
2008 
2009     // make new Global Refs and send events only to those ATs that want 'em
2010     AccessBridgeATInstance *ati = ATs;
2011     while (ati != (AccessBridgeATInstance *) 0) {
2012         if (ati->accessibilityEventMask & cPropertyStateChangeEvent) {
2013 
2014             PrintDebugString("  sending to AT");
2015 
2016             // make new GlobalRefs for this AT
2017             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
2018             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
2019 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2020             PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
2021             PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
2022 #else // JOBJECT64 is jlong (64 bit)
2023             PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
2024             PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
2025 #endif
2026 
2027             if (oldValue != (jstring) 0) {
2028                 stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
2029                 if (stringBytes == NULL) {
2030                     if (!env->ExceptionCheck()) {
2031                         jclass cls = env->FindClass("java/lang/OutOfMemoryError");
2032                         if (cls != NULL) {
2033                             env->ThrowNew(cls, NULL);
2034                         }
2035                     }
2036                     return;
2037                 }
2038                 wcsncpy(pkg->oldState, stringBytes, (sizeof(pkg->oldState) / sizeof(wchar_t)));
2039                 env->ReleaseStringChars(oldValue, stringBytes);
2040             } else {
2041                 wcsncpy(pkg->oldState, L"(null)", (sizeof(pkg->oldState) / sizeof(wchar_t)));
2042             }
2043 
2044             if (newValue != (jstring) 0) {
2045                 stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
2046                 if (stringBytes == NULL) {
2047                     if (!env->ExceptionCheck()) {
2048                         jclass cls = env->FindClass("java/lang/OutOfMemoryError");
2049                         if (cls != NULL) {
2050                             env->ThrowNew(cls, NULL);
2051                         }
2052                     }
2053                     return;
2054                 }
2055                 wcsncpy(pkg->newState, stringBytes, (sizeof(pkg->newState) / sizeof(wchar_t)));
2056                 env->ReleaseStringChars(newValue, stringBytes);
2057             } else {
2058                 wcsncpy(pkg->newState, L"(null)", (sizeof(pkg->newState) / sizeof(wchar_t)));
2059             }
2060 
2061             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyStateChangeEvent);
2062         }
2063         ati = ati->nextATInstance;
2064     }
2065     PrintDebugString("  done with propertyStateChange event");
2066 }
2067 
2068 
2069 /**
2070  * firePropertyTextChange
2071  *
2072  */
2073 void
2074 JavaAccessBridge::firePropertyTextChange(JNIEnv *env, jobject callingObj,
2075                                          jobject event, jobject source) {
2076 
2077     PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyTextChanged(%p, %p, %p, %p)",
2078                      env, callingObj, event, source);
2079 
2080     // sanity check
2081     if (ATs == (AccessBridgeATInstance *) 0) {
2082         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
2083         return;         // panic!
2084     }
2085 
2086     // common setup
2087     char buffer[sizeof(PackageType) + sizeof(PropertyTextChangePackage)];
2088     PackageType *type = (PackageType *) buffer;
2089     PropertyTextChangePackage *pkg = (PropertyTextChangePackage *) (buffer + sizeof(PackageType));
2090     *type = cPropertyTextChangePackage;
2091     pkg->vmID = (long) dialogWindow;
2092 
2093     // make new Global Refs and send events only to those ATs that want 'em
2094     AccessBridgeATInstance *ati = ATs;
2095     while (ati != (AccessBridgeATInstance *) 0) {
2096         if (ati->accessibilityEventMask & cPropertyTextChangeEvent) {
2097 
2098             PrintDebugString("  sending to AT");
2099 
2100             // make new GlobalRefs for this AT
2101             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
2102             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
2103 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2104             PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
2105             PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
2106 #else // JOBJECT64 is jlong (64 bit)
2107             PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
2108             PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
2109 #endif
2110 
2111             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTextChangeEvent);
2112         }
2113         ati = ati->nextATInstance;
2114     }
2115     PrintDebugString("  done with propertyTextChange event");
2116 }
2117 
2118 
2119 /**
2120  * firePropertyValueChange
2121  *
2122  */
2123 void
2124 JavaAccessBridge::firePropertyValueChange(JNIEnv *env, jobject callingObj,
2125                                           jobject event, jobject source,
2126                                           jstring oldValue, jstring newValue){
2127 
2128     PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyValueChanged(%p, %p, %p, %p, %p, %p)",
2129                      env, callingObj, event,
2130                      source, oldValue, newValue);
2131 
2132     // sanity check
2133     if (ATs == (AccessBridgeATInstance *) 0) {
2134         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
2135         return;         // panic!
2136     }
2137 
2138     // common setup
2139     const wchar_t *stringBytes;
2140     char buffer[sizeof(PackageType) + sizeof(PropertyValueChangePackage)];
2141     PackageType *type = (PackageType *) buffer;
2142     PropertyValueChangePackage *pkg = (PropertyValueChangePackage *) (buffer + sizeof(PackageType));
2143     *type = cPropertyValueChangePackage;
2144     pkg->vmID = (long) dialogWindow;
2145 
2146     // make new Global Refs and send events only to those ATs that want 'em
2147     AccessBridgeATInstance *ati = ATs;
2148     while (ati != (AccessBridgeATInstance *) 0) {
2149         if (ati->accessibilityEventMask & cPropertyValueChangeEvent) {
2150 
2151             PrintDebugString("  sending to AT");
2152 
2153             // make new GlobalRefs for this AT
2154             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
2155             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
2156 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2157             PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
2158             PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
2159 #else // JOBJECT64 is jlong (64 bit)
2160             PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
2161             PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
2162 #endif
2163 
2164             if (oldValue != (jstring) 0) {
2165                 stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
2166                 if (stringBytes == NULL) {
2167                     if (!env->ExceptionCheck()) {
2168                         jclass cls = env->FindClass("java/lang/OutOfMemoryError");
2169                         if (cls != NULL) {
2170                             env->ThrowNew(cls, NULL);
2171                         }
2172                     }
2173                     return;
2174                 }
2175                 wcsncpy(pkg->oldValue, stringBytes, (sizeof(pkg->oldValue) / sizeof(wchar_t)));
2176                 env->ReleaseStringChars(oldValue, stringBytes);
2177             } else {
2178                 wcsncpy(pkg->oldValue, L"(null)", (sizeof(pkg->oldValue) / sizeof(wchar_t)));
2179             }
2180 
2181             if (newValue != (jstring) 0) {
2182                 stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
2183                 if (stringBytes == NULL) {
2184                     if (!env->ExceptionCheck()) {
2185                         jclass cls = env->FindClass("java/lang/OutOfMemoryError");
2186                         if (cls != NULL) {
2187                             env->ThrowNew(cls, NULL);
2188                         }
2189                     }
2190                     return;
2191                 }
2192                 wcsncpy(pkg->newValue, stringBytes, (sizeof(pkg->newValue) / sizeof(wchar_t)));
2193                 env->ReleaseStringChars(newValue, stringBytes);
2194             } else {
2195                 wcsncpy(pkg->newValue, L"(null)", (sizeof(pkg->newValue) / sizeof(wchar_t)));
2196             }
2197 
2198             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyValueChangeEvent);
2199         }
2200         ati = ati->nextATInstance;
2201     }
2202     PrintDebugString("  done with propertyValueChange event");
2203 }
2204 
2205 /**
2206  * firePropertyVisibleDataChange
2207  *
2208  */
2209 void
2210 JavaAccessBridge::firePropertyVisibleDataChange(JNIEnv *env, jobject callingObj,
2211                                                 jobject event, jobject source) {
2212 
2213     PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyVisibleDataChanged(%p, %p, %p, %p)",
2214                      env, callingObj, event, source);
2215 
2216     // sanity check
2217     if (ATs == (AccessBridgeATInstance *) 0) {
2218         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
2219         return;         // panic!
2220     }
2221 
2222     // common setup
2223     char buffer[sizeof(PackageType) + sizeof(PropertyVisibleDataChangePackage)];
2224     PackageType *type = (PackageType *) buffer;
2225     PropertyVisibleDataChangePackage *pkg = (PropertyVisibleDataChangePackage *) (buffer + sizeof(PackageType));
2226     *type = cPropertyVisibleDataChangePackage;
2227     pkg->vmID = (long) dialogWindow;
2228 
2229     // make new Global Refs and send events only to those ATs that want 'em
2230     AccessBridgeATInstance *ati = ATs;
2231     while (ati != (AccessBridgeATInstance *) 0) {
2232         if (ati->accessibilityEventMask & cPropertyVisibleDataChangeEvent) {
2233 
2234             PrintDebugString("  sending to AT");
2235 
2236             // make new GlobalRefs for this AT
2237             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
2238             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
2239 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2240             PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
2241             PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
2242 #else // JOBJECT64 is jlong (64 bit)
2243             PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
2244             PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
2245 #endif
2246 
2247             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyVisibleDataChangeEvent);
2248         }
2249         ati = ati->nextATInstance;
2250     }
2251     PrintDebugString("  done with propertyVisibleDataChange event");
2252 }
2253 
2254 
2255 /**
2256  * firePropertyChildChange
2257  *
2258  */
2259 void
2260 JavaAccessBridge::firePropertyChildChange(JNIEnv *env, jobject callingObj,
2261                                           jobject event, jobject source,
2262                                           jobject oldValue, jobject newValue){
2263 
2264     PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyChildPropertyChanged(%p, %p, %p, %p, %p, %p)",
2265                      env, callingObj, event,
2266                      source, oldValue, newValue);
2267 
2268     // sanity check
2269     if (ATs == (AccessBridgeATInstance *) 0) {
2270         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
2271         return;         // panic!
2272     }
2273 
2274     // common setup
2275     char buffer[sizeof(PackageType) + sizeof(PropertyChildChangePackage)];
2276     PackageType *type = (PackageType *) buffer;
2277     PropertyChildChangePackage *pkg = (PropertyChildChangePackage *) (buffer + sizeof(PackageType));
2278     *type = cPropertyChildChangePackage;
2279     pkg->vmID = (long) dialogWindow;
2280 
2281     // make new Global Refs and send events only to those ATs that want 'em
2282     AccessBridgeATInstance *ati = ATs;
2283     while (ati != (AccessBridgeATInstance *) 0) {
2284         if (ati->accessibilityEventMask & cPropertyChildChangeEvent) {
2285 
2286             PrintDebugString("  sending to AT");
2287 
2288             // make new GlobalRefs for this AT
2289             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
2290             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
2291             pkg->oldChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue);
2292             pkg->newChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue);
2293 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2294             PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
2295             PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
2296             PrintDebugString("  GlobalRef'd OldChildAC: %p", pkg->oldChildAccessibleContext);
2297             PrintDebugString("  GlobalRef'd NewChildAC: %p", pkg->newChildAccessibleContext);
2298 #else // JOBJECT64 is jlong (64 bit)
2299             PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
2300             PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
2301             PrintDebugString("  GlobalRef'd OldChildAC: %016I64X", pkg->oldChildAccessibleContext);
2302             PrintDebugString("  GlobalRef'd NewChildAC: %016I64X", pkg->newChildAccessibleContext);
2303 #endif
2304 
2305             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyChildChangeEvent);
2306         }
2307         ati = ati->nextATInstance;
2308     }
2309     PrintDebugString("  done with propertyChildChange event");
2310 }
2311 
2312 
2313 /**
2314  * firePropertyActiveDescendentChange
2315  *
2316  */
2317 void
2318 JavaAccessBridge::firePropertyActiveDescendentChange(JNIEnv *env, jobject callingObj,
2319                                                      jobject event, jobject source,
2320                                                      jobject oldValue, jobject newValue){
2321 
2322     PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyActiveDescendentPropertyChanged(%p, %p, %p, %p, %p, %p)",
2323                      env, callingObj, event,
2324                      source, oldValue, newValue);
2325 
2326     // sanity check
2327     if (ATs == (AccessBridgeATInstance *) 0) {
2328         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
2329         return;         // panic!
2330     }
2331 
2332     // common setup
2333     char buffer[sizeof(PackageType) + sizeof(PropertyActiveDescendentChangePackage)];
2334     PackageType *type = (PackageType *) buffer;
2335     PropertyActiveDescendentChangePackage *pkg = (PropertyActiveDescendentChangePackage *) (buffer + sizeof(PackageType));
2336     *type = cPropertyActiveDescendentChangePackage;
2337     pkg->vmID = (long) dialogWindow;
2338 
2339     // make new Global Refs and send events only to those ATs that want 'em
2340     AccessBridgeATInstance *ati = ATs;
2341     while (ati != (AccessBridgeATInstance *) 0) {
2342         if (ati->accessibilityEventMask & cPropertyActiveDescendentChangeEvent) {
2343 
2344             PrintDebugString("  sending to AT");
2345 
2346             // make new GlobalRefs for this AT
2347             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
2348             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
2349             pkg->oldActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue);
2350             pkg->newActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue);
2351 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2352             PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
2353             PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
2354             PrintDebugString("  GlobalRef'd OldActiveDescendentAC: %p", pkg->oldActiveDescendentAccessibleContext);
2355             PrintDebugString("  GlobalRef'd NewActiveDescendentAC: %p", pkg->newActiveDescendentAccessibleContext);
2356 #else // JOBJECT64 is jlong (64 bit)
2357             PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
2358             PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
2359             PrintDebugString("  GlobalRef'd OldActiveDescendentAC: %016I64X", pkg->oldActiveDescendentAccessibleContext);
2360             PrintDebugString("  GlobalRef'd NewActiveDescendentAC: %016I64X", pkg->newActiveDescendentAccessibleContext);
2361 #endif
2362 
2363             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyActiveDescendentChangeEvent);
2364         }
2365         ati = ati->nextATInstance;
2366     }
2367     PrintDebugString("  done with propertyActiveChange event");
2368 }
2369 
2370 /**
2371  * firePropertyValueChange
2372  *
2373  */
2374 void
2375 JavaAccessBridge::firePropertyTableModelChange(JNIEnv *env, jobject callingObj,
2376                                                jobject event, jobject source,
2377                                                jstring oldValue, jstring newValue){
2378 
2379     PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyTableModelChange(%p, %p, %p, %p, %p, %p)",
2380                      env, callingObj, event,
2381                      source, oldValue, newValue);
2382 
2383     // sanity check
2384     if (ATs == (AccessBridgeATInstance *) 0) {
2385         PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
2386         return;         // panic!
2387     }
2388 
2389     // common setup
2390     const wchar_t *stringBytes;
2391     char buffer[sizeof(PackageType) + sizeof(PropertyTableModelChangePackage)];
2392     PackageType *type = (PackageType *) buffer;
2393     PropertyTableModelChangePackage *pkg = (PropertyTableModelChangePackage *) (buffer + sizeof(PackageType));
2394     *type = cPropertyTableModelChangePackage;
2395     pkg->vmID = (long) dialogWindow;
2396 
2397     // make new Global Refs and send events only to those ATs that want 'em
2398     AccessBridgeATInstance *ati = ATs;
2399     while (ati != (AccessBridgeATInstance *) 0) {
2400         if (ati->accessibilityEventMask & cPropertyTableModelChangeEvent) {
2401 
2402             PrintDebugString("  sending to AT");
2403 
2404             // make new GlobalRefs for this AT
2405             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
2406             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
2407 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2408             PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
2409             PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
2410 #else // JOBJECT64 is jlong (64 bit)
2411             PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
2412             PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
2413 #endif
2414 
2415             if (oldValue != (jstring) 0) {
2416                 stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
2417                 if (stringBytes == NULL) {
2418                     if (!env->ExceptionCheck()) {
2419                         jclass cls = env->FindClass("java/lang/OutOfMemoryError");
2420                         if (cls != NULL) {
2421                             env->ThrowNew(cls, NULL);
2422                         }
2423                     }
2424                     return;
2425                 }
2426                 wcsncpy(pkg->oldValue, stringBytes, (sizeof(pkg->oldValue) / sizeof(wchar_t)));
2427                 env->ReleaseStringChars(oldValue, stringBytes);
2428             } else {
2429                 wcsncpy(pkg->oldValue, L"(null)", (sizeof(pkg->oldValue) / sizeof(wchar_t)));
2430             }
2431 
2432             if (newValue != (jstring) 0) {
2433                 stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
2434                 if (stringBytes == NULL) {
2435                     if (!env->ExceptionCheck()) {
2436                         jclass cls = env->FindClass("java/lang/OutOfMemoryError");
2437                         if (cls != NULL) {
2438                             env->ThrowNew(cls, NULL);
2439                         }
2440                     }
2441                     return;
2442                 }
2443                 wcsncpy(pkg->newValue, stringBytes, (sizeof(pkg->newValue) / sizeof(wchar_t)));
2444                 env->ReleaseStringChars(newValue, stringBytes);
2445             } else {
2446                 wcsncpy(pkg->newValue, L"(null)", (sizeof(pkg->newValue) / sizeof(wchar_t)));
2447             }
2448 
2449             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTableModelChangeEvent);
2450         }
2451         ati = ati->nextATInstance;
2452     }
2453     PrintDebugString("  done with propertyTableModelChange event");
2454 }
2455 
2456 
2457 
2458 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
2459 #define PRINT_GLOBALREFS() \
2460     PrintDebugString("  GlobalRef'd Event: %p", pkg->Event); \
2461     PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
2462 #else // JOBJECT64 is jlong (64 bit)
2463 #define PRINT_GLOBALREFS() \
2464     PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event); \
2465     PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
2466 #endif
2467 
2468 #define FIRE_EVENT(function, packageStruct, packageConstant, eventConstant)             \
2469     void JavaAccessBridge::function(JNIEnv *env, jobject callingObj,                    \
2470                                     jobject eventObj, jobject source) {                 \
2471                                                                                         \
2472         PrintDebugString("\r\nFiring event id = %d(%p, %p, %p, %p); vmID = %X",         \
2473                          eventConstant, env, callingObj, eventObj, source, dialogWindow); \
2474                                                                                         \
2475         /* sanity check */                                                              \
2476         if (ATs == (AccessBridgeATInstance *) 0) {                                      \
2477             PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");           \
2478             return;         /* panic! */                                                \
2479         }                                                                               \
2480                                                                                         \
2481         /* common setup */                                                              \
2482         char buffer[sizeof(PackageType) + sizeof(packageStruct)];                       \
2483         PackageType *type = (PackageType *) buffer;                                     \
2484         packageStruct *pkg = (packageStruct *) (buffer + sizeof(PackageType));          \
2485         *type = packageConstant;                                                        \
2486         pkg->vmID = (long) dialogWindow;                                                \
2487                                                                                         \
2488         /* make new Global Refs, send events only to those ATs that want 'em */         \
2489         AccessBridgeATInstance *ati = ATs;                                              \
2490         while (ati != (AccessBridgeATInstance *) 0) {                                   \
2491             PrintDebugString("\r\njavaEventMask = %X eventConstant=%d pkg->vmID=%X",    \
2492                              ati->javaEventMask, eventConstant, pkg->vmID );            \
2493             if (ati->javaEventMask & eventConstant) {                                   \
2494                                                                                         \
2495                 PrintDebugString("  sending to AT");                                    \
2496                 /* make new GlobalRefs for this AT */                                   \
2497                 pkg->Event = (JOBJECT64)env->NewGlobalRef(eventObj);                    \
2498                 pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);    \
2499                 PRINT_GLOBALREFS()                                                      \
2500                                                                                         \
2501                 ati->sendJavaEventPackage(buffer, sizeof(buffer), eventConstant);       \
2502             }                                                                           \
2503             ati = ati->nextATInstance;                                                  \
2504         }                                                                               \
2505         PrintDebugString("  done with firing AWT event");                               \
2506     }
2507 
2508     void JavaAccessBridge::javaShutdown(JNIEnv *env, jobject callingObj) {
2509 
2510         PrintDebugString("\r\nFiring event id = %d(%p, %p); vmID = %X",
2511                          cJavaShutdownEvent, env, callingObj, dialogWindow);
2512 
2513         /* sanity check */
2514         if (ATs == (AccessBridgeATInstance *) 0) {
2515             PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
2516             return;             /* panic! */
2517         }
2518 
2519         /* common setup */
2520         char buffer[sizeof(PackageType) + sizeof(JavaShutdownPackage)];
2521         PackageType *type = (PackageType *) buffer;
2522         JavaShutdownPackage *pkg = (JavaShutdownPackage *) (buffer + sizeof(PackageType));
2523         *type = cJavaShutdownPackage;
2524         pkg->vmID = (long) dialogWindow;
2525 
2526         /* make new Global Refs, send events only to those ATs that want 'em */
2527         AccessBridgeATInstance *ati = ATs;
2528         while (ati != (AccessBridgeATInstance *) 0) {
2529             if (ati->javaEventMask & cJavaShutdownEvent) {
2530                 PrintDebugString("  sending to AT");
2531                 ati->sendJavaEventPackage(buffer, sizeof(buffer), cJavaShutdownEvent);
2532             }
2533             ati = ati->nextATInstance;
2534         }
2535         PrintDebugString("  done with firing AWT event");
2536     }
2537 
2538     FIRE_EVENT(fireFocusGained, FocusGainedPackage, cFocusGainedPackage, cFocusGainedEvent)
2539     FIRE_EVENT(fireFocusLost, FocusLostPackage, cFocusLostPackage, cFocusLostEvent)
2540     FIRE_EVENT(fireCaretUpdate, CaretUpdatePackage, cCaretUpdatePackage, cCaretUpdateEvent)
2541     FIRE_EVENT(fireMouseClicked, MouseClickedPackage, cMouseClickedPackage, cMouseClickedEvent)
2542     FIRE_EVENT(fireMouseEntered, MouseEnteredPackage, cMouseEnteredPackage, cMouseEnteredEvent)
2543     FIRE_EVENT(fireMouseExited, MouseExitedPackage, cMouseExitedPackage, cMouseExitedEvent)
2544     FIRE_EVENT(fireMousePressed, MousePressedPackage, cMousePressedPackage, cMousePressedEvent)
2545     FIRE_EVENT(fireMouseReleased, MouseReleasedPackage, cMouseReleasedPackage, cMouseReleasedEvent)
2546     FIRE_EVENT(fireMenuCanceled, MenuCanceledPackage, cMenuCanceledPackage, cMenuCanceledEvent)
2547     FIRE_EVENT(fireMenuDeselected, MenuDeselectedPackage, cMenuDeselectedPackage, cMenuDeselectedEvent)
2548     FIRE_EVENT(fireMenuSelected, MenuSelectedPackage, cMenuSelectedPackage, cMenuSelectedEvent)
2549     FIRE_EVENT(firePopupMenuCanceled, PopupMenuCanceledPackage, cPopupMenuCanceledPackage, cPopupMenuCanceledEvent)
2550     FIRE_EVENT(firePopupMenuWillBecomeInvisible, PopupMenuWillBecomeInvisiblePackage, cPopupMenuWillBecomeInvisiblePackage, cPopupMenuWillBecomeInvisibleEvent)
2551     FIRE_EVENT(firePopupMenuWillBecomeVisible, PopupMenuWillBecomeVisiblePackage, cPopupMenuWillBecomeVisiblePackage, cPopupMenuWillBecomeVisibleEvent)
2552 
2553 
2554     // -----------------------------
2555 
2556 
2557 extern "C" {        // event stuff from AccessBridge.h, generated by JNI
2558 
2559     JNIEXPORT void JNICALL
2560     Java_com_sun_java_accessibility_internal_AccessBridge_sendDebugString(JNIEnv *env, jobject callingObj, jstring debugStr) {
2561 
2562         const wchar_t *stringBytes;
2563         stringBytes = (const wchar_t *) env->GetStringChars(debugStr, 0);
2564         if (stringBytes == NULL) {
2565             if (!env->ExceptionCheck()) {
2566                 jclass cls = env->FindClass("java/lang/OutOfMemoryError");
2567                 if (cls != NULL) {
2568                     env->ThrowNew(cls, NULL);
2569                 }
2570             }
2571             return;
2572         }
2573         wPrintJavaDebugString(L"AccessBridge.java: %ls", stringBytes);
2574         env->ReleaseStringChars(debugStr, stringBytes);
2575     }
2576 
2577     JNIEXPORT void JNICALL
2578     Java_com_sun_java_accessibility_internal_AccessBridge_propertyCaretChange(JNIEnv *env, jobject callingObj,
2579                                                                         jobject event, jobject source,
2580                                                                         jint oldValue, jint newValue) {
2581         theJavaAccessBridge->firePropertyCaretChange(env, callingObj,
2582                                                         event, source,
2583                                                         oldValue, newValue);
2584     }
2585 
2586     JNIEXPORT void JNICALL
2587     Java_com_sun_java_accessibility_internal_AccessBridge_propertyDescriptionChange(JNIEnv *env, jobject callingObj,
2588                                                                             jobject event, jobject source,
2589                                                                             jstring oldValue, jstring newValue) {
2590         theJavaAccessBridge->firePropertyDescriptionChange(env, callingObj,
2591                                                             event, source,
2592                                                             oldValue, newValue);
2593     }
2594 
2595     JNIEXPORT void JNICALL
2596     Java_com_sun_java_accessibility_internal_AccessBridge_propertyNameChange(JNIEnv *env, jobject callingObj,
2597                                                                     jobject event, jobject source,
2598                                                                     jstring oldValue, jstring newValue) {
2599         theJavaAccessBridge->firePropertyNameChange(env, callingObj,
2600                                                     event, source,
2601                                                     oldValue, newValue);
2602     }
2603 
2604     JNIEXPORT void JNICALL
2605     Java_com_sun_java_accessibility_internal_AccessBridge_propertySelectionChange(JNIEnv *env, jobject callingObj,
2606                                                                             jobject event, jobject source) {
2607         theJavaAccessBridge->firePropertySelectionChange(env, callingObj,
2608                                                             event, source);
2609     }
2610 
2611     JNIEXPORT void JNICALL
2612     Java_com_sun_java_accessibility_internal_AccessBridge_propertyStateChange(JNIEnv *env, jobject callingObj,
2613                                                                         jobject event, jobject source,
2614                                                                         jstring oldValue, jstring newValue) {
2615         theJavaAccessBridge->firePropertyStateChange(env, callingObj,
2616                                                         event, source,
2617                                                         oldValue, newValue);
2618     }
2619 
2620     JNIEXPORT void JNICALL
2621     Java_com_sun_java_accessibility_internal_AccessBridge_propertyTextChange(JNIEnv *env, jobject callingObj,
2622                                                                     jobject event,  jobject source) {
2623         theJavaAccessBridge->firePropertyTextChange(env, callingObj,
2624                                                     event, source);
2625     }
2626 
2627     JNIEXPORT void JNICALL
2628     Java_com_sun_java_accessibility_internal_AccessBridge_propertyValueChange(JNIEnv *env, jobject callingObj,
2629                                                                         jobject event, jobject source,
2630                                                                         jstring oldValue, jstring newValue) {
2631         theJavaAccessBridge->firePropertyValueChange(env, callingObj,
2632                                                         event, source,
2633                                                         oldValue, newValue);
2634     }
2635 
2636     JNIEXPORT void JNICALL
2637     Java_com_sun_java_accessibility_internal_AccessBridge_propertyVisibleDataChange(JNIEnv *env, jobject callingObj,
2638                                                                             jobject event,  jobject source) {
2639         theJavaAccessBridge->firePropertyVisibleDataChange(env, callingObj,
2640                                                             event, source);
2641     }
2642 
2643     JNIEXPORT void JNICALL
2644     Java_com_sun_java_accessibility_internal_AccessBridge_propertyChildChange(JNIEnv *env, jobject callingObj,
2645                                                                         jobject event, jobject source,
2646                                                                         jobject oldValue, jobject newValue) {
2647         theJavaAccessBridge->firePropertyChildChange(env, callingObj,
2648                                                         event, source,
2649                                                         oldValue, newValue);
2650     }
2651 
2652     JNIEXPORT void JNICALL
2653     Java_com_sun_java_accessibility_internal_AccessBridge_propertyActiveDescendentChange(JNIEnv *env, jobject callingObj,
2654                                                                                 jobject event,  jobject source,
2655                                                                                 jobject oldValue,
2656                                                                                 jobject newValue) {
2657         theJavaAccessBridge->firePropertyActiveDescendentChange(env, callingObj,
2658                                                                 event, source,
2659                                                                 oldValue, newValue);
2660     }
2661 
2662     JNIEXPORT void JNICALL
2663     Java_com_sun_java_accessibility_internal_AccessBridge_propertyTableModelChange(JNIEnv *env, jobject callingObj,
2664                                                                             jobject event,  jobject source,
2665                                                                             jstring oldValue, jstring newValue) {
2666 
2667         theJavaAccessBridge->firePropertyTableModelChange(env, callingObj,
2668                                                             event, source,
2669                                                             oldValue, newValue);
2670     }
2671 
2672 #define HANDLE_STANDARD_EVENT_FROM_JAVA(function, method) \
2673     JNIEXPORT void JNICALL \
2674     function(JNIEnv *env, jobject callingObj, jobject event, jobject source) { \
2675         theJavaAccessBridge->method(env, callingObj, event, source); \
2676     }
2677 
2678 
2679     JNIEXPORT void JNICALL
2680     Java_com_sun_java_accessibility_internal_AccessBridge_javaShutdown(JNIEnv *env, jobject callingObj) {
2681         theJavaAccessBridge->javaShutdown(env, callingObj);
2682     }
2683 
2684     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_focusGained, fireFocusGained)
2685     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_focusLost, fireFocusLost)
2686     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_caretUpdate, fireCaretUpdate)
2687     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_mouseClicked, fireMouseClicked)
2688     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_mouseEntered, fireMouseEntered)
2689     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_mouseExited, fireMouseExited)
2690     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_mousePressed, fireMousePressed)
2691     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_mouseReleased, fireMouseReleased)
2692     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_menuCanceled, fireMenuCanceled)
2693     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_menuDeselected, fireMenuDeselected)
2694     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_menuSelected, fireMenuSelected)
2695     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_popupMenuCanceled, firePopupMenuCanceled)
2696     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_popupMenuWillBecomeInvisible, firePopupMenuWillBecomeInvisible)
2697     HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_popupMenuWillBecomeVisible, firePopupMenuWillBecomeVisible)
2698 
2699     /*
2700      * Map a HWND to a Java component
2701      *
2702      * Class:     com_sun_java_accessibility_internal_AccessBridge
2703      * Method:    jawtGetComponentFromNativeWindowHandle
2704      * Signature: (I)Ljava/awt/Component;
2705      */
2706     JNIEXPORT jobject JNICALL
2707     Java_com_sun_java_accessibility_internal_AccessBridge_jawtGetComponentFromNativeWindowHandle
2708         (JNIEnv *env, jobject callingObj, jint windowHandle) {
2709 
2710     JAWT awt;
2711     jboolean result;
2712     jobject component = (jobject)0;
2713 
2714     // Get the AWT
2715     awt.version = JAWT_VERSION_1_4;
2716     result = JAWT_GetAWT(env, &awt);
2717     if (result == JNI_FALSE) {
2718         return (jobject)0;
2719     }
2720 
2721     // Get the component
2722     return awt.GetComponent(env, (void *)windowHandle);
2723     }
2724 
2725 
2726     /*
2727      * Map a Java component to a HWND
2728      *
2729      * Class:     com_sun_java_accessibility_internal_AccessBridge
2730      * Method:    jawtGetNativeWindowHandleFromComponent
2731      * Signature: (Ljava/awt/Component;)I
2732      */
2733     JNIEXPORT jint JNICALL
2734     Java_com_sun_java_accessibility_internal_AccessBridge_jawtGetNativeWindowHandleFromComponent
2735         (JNIEnv *env, jobject callingObj, jobject component) {
2736 
2737         JAWT awt;
2738         JAWT_DrawingSurface* ds;
2739         JAWT_DrawingSurfaceInfo* dsi;
2740         JAWT_Win32DrawingSurfaceInfo* dsi_win;
2741         jboolean result;
2742         // jint lock;
2743         jint windowHandle = -1;
2744 
2745         // Get the AWT
2746         awt.version = JAWT_VERSION_1_4;
2747         result = JAWT_GetAWT(env, &awt);
2748         if (result == JNI_FALSE) {
2749             return -1;
2750         }
2751 
2752         // Get the drawing surface
2753         ds = awt.GetDrawingSurface(env, component);
2754         if (ds == NULL) {
2755             return -1;
2756         }
2757 
2758         // Get the drawing surface info
2759         dsi = ds->GetDrawingSurfaceInfo(ds);
2760 
2761         // Get the platform-specific drawing info
2762         dsi_win = (JAWT_Win32DrawingSurfaceInfo *)dsi->platformInfo;
2763 
2764         // Get the window handle
2765         windowHandle = (jint)dsi_win->hwnd;
2766 
2767         // Free the drawing surface info
2768         ds->FreeDrawingSurfaceInfo(dsi);
2769 
2770         // Free the drawing surface
2771         awt.FreeDrawingSurface(ds);
2772 
2773         return windowHandle;
2774     }
2775 
2776 }