text: /*
   * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
   * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
   */
  
  /*
   * @(#)JavaAccessBridge.cpp	1.31 05/03/21
   */
  
  /* 
   * A DLL which is loaded by Java applications to handle communication
   * between Java VMs purposes of Accessbility.
   */
  
  #ifdef _DEBUG
  #define DEBUGGING_ON
  #endif
  
  #include "AccessBridgeDebug.h"
  #include "JavaAccessBridge.h"
  #include "AccessBridge.h"			// programatically generated by JNI
  #include "accessBridgeResource.h"
  #include "accessBridgeCallbacks.h"
  #include "AccessBridgeMessages.h"
  
  
  #include <windows.h>
  #include <stdio.h>
  
  // #ifdef JAWT_SUPPORT
  #include <jawt.h>
  #include <win32/jawt_md.h>
  // #endif /* JAWT_SUPPORT */
  
  JavaAccessBridge *theJavaAccessBridge;
  HWND theDialogWindow;
  
  // re-entrance lock for receiving memory messages
  CRITICAL_SECTION receiveMemoryIPCLock;
  
  
  // unique broadcast msg. IDs gotten dymanically
  extern UINT theFromJavaHelloMsgID;
  extern UINT theFromWindowsHelloMsgID;
  
  
  // ---------------------------------------------------------------------------
  
  extern "C" {
      /**	
       * DllMain - where Windows executables will load/unload us
       *
       */
      BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) {
  
          switch (fdwReason) {
          case DLL_PROCESS_ATTACH:
              InitializeCriticalSection(&receiveMemoryIPCLock);
              theJavaAccessBridge = new JavaAccessBridge(hinstDll);
              break;
  
          case DLL_PROCESS_DETACH:	// A Windows executable unloaded us
              if (theJavaAccessBridge != (JavaAccessBridge *) 0) {
                  delete theJavaAccessBridge;
                  DeleteCriticalSection(&receiveMemoryIPCLock);
              }
              break; 
          }
          return TRUE;
      }
  
      /**
       * Open a native window (and init the wrappers we'll be using)
       *
       */
      JNIEXPORT void JNICALL 
      Java_com_sun_java_accessibility_AccessBridge_run(JNIEnv *env, jobject obj) {
          PrintDebugString("\r\nJavaAccessBridge.DLL run() called"); 
          theJavaAccessBridge->javaRun(env, obj);
      }
  
      /**
       * Append debug info to dialog
       *
       */
      void AppendToCallInfo(char *s) {
          char buffer[4096];
  
          GetDlgItemText(theDialogWindow, cCallInfo, buffer, sizeof(buffer));
          if (strlen(buffer) < (sizeof(buffer) - strlen(s))) {
              strncat(buffer, s, sizeof(buffer));
              SetDlgItemText(theDialogWindow, cCallInfo, buffer);
          } else {
              SetDlgItemText(theDialogWindow, cCallInfo, s);
          }
      }
  
  
      /**
       * Our window proc
       *
       */
      BOOL APIENTRY AccessBridgeDialogProc (HWND hDlg, UINT message, UINT wParam, LONG lParam) {
          int command;
          COPYDATASTRUCT *sentToUs;
          char *package;
          DEBUG(char buffer[256]);
  
          switch (message) {
          case WM_INITDIALOG:
              DEBUG(SetDlgItemText(theDialogWindow, cStatusText, "Initializing"));
              break;
  		
          case WM_COMMAND: 
              command = LOWORD (wParam);
              break;
  
              // call from Java with data for us to deliver
          case WM_COPYDATA:
              if (theDialogWindow == (HWND) wParam) {
                  DEBUG(SetDlgItemText(theDialogWindow, cStatusText, "Got WM_COPYDATA from ourselves"));
              } else {
                  DEBUG(sprintf(buffer, "Got WM_COPYDATA from HWND %x", wParam)); 
                  DEBUG(SetDlgItemText(theDialogWindow, cStatusText, buffer));
                  sentToUs = (COPYDATASTRUCT *) lParam;
                  package = (char *) sentToUs->lpData;
                  theJavaAccessBridge->processPackage(package, sentToUs->cbData);
              }
              break;
  
              // call from Java with data for us retrieve from memory mapped file and deliver
          case AB_MESSAGE_WAITING:
              // wParam == sourceHwnd
              // lParam == buffer size in shared memory
              if (theDialogWindow == (HWND) wParam) {
                  DEBUG(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_MESSAGE_WAITING from ourselves"));
              } else {
                  DEBUG(sprintf(buffer, "Got AB_MESSAGE_WAITING from HWND %x", wParam)); 
                  DEBUG(SetDlgItemText(theDialogWindow, cStatusText, buffer));
                  LRESULT returnVal = theJavaAccessBridge->receiveMemoryPackage((HWND) wParam, lParam);
              }
              break;
  
              // a JavaAccessBridge DLL is going away
          case AB_DLL_GOING_AWAY:
              // wParam == sourceHwnd
              DEBUG(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_DLL_GOING_AWAY message"));
              theJavaAccessBridge->WindowsATDestroyed((HWND) wParam);
              break;
  
          default:
              // the Windows AT is saying "hi"!
              // wParam == sourceHwnc; lParam unused
              if (message == theFromWindowsHelloMsgID) {
                  // A new Windows AT just said "hi";
                  // say "hi" back so it can mate up with us
                  // otherwise don't do anything (e.g. don't set up data structures yet)
                  theJavaAccessBridge->postHelloToWindowsDLLMsg((HWND) wParam);
              }
          }
          return FALSE;   
      }
  
  }
  
  
  // -----------------------------
  
  
  /**
   * Initialize the JavaAccessBridge
   *
   */
  JavaAccessBridge::JavaAccessBridge(HINSTANCE hInstance) {
      windowsInstance = hInstance;
      ATs = (AccessBridgeATInstance *) 0;
      initBroadcastMessageIDs();		// get the unique to us broadcast msg. IDs
  }
  
  extern DWORD JavaBridgeThreadId;
  
  /**
   * Destroy the JavaAccessBridge
   *
   */
  JavaAccessBridge::~JavaAccessBridge() {
      // inform all other AccessBridges that we're going away
  
      PrintDebugString("\r\nin JavaAccessBridge::~JavaAccessBridge()"); 
  
      // Send a shutdown message for those applications like StarOffice that do
      // send a shutdown message themselves.
      javaShutdown(NULL, 0);    
  
      AccessBridgeATInstance *current = ATs;
      while (current != (AccessBridgeATInstance *) 0) {
          PrintDebugString("  telling %X we're going away", current->winAccessBridgeWindow); 
          SendMessage(current->winAccessBridgeWindow,
                      AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0);
          current = current->nextATInstance;
      }
  
      PrintDebugString("  finished telling ATs about our demise");
  
  	if(JavaBridgeThreadId)
  		{
  		PostThreadMessage(JavaBridgeThreadId,WM_USER+1,0,0);
  		Sleep(100);
  		}
  
      delete ATs;
  
      PrintDebugString("  finished deleting ATs"); 
      PrintDebugString("GOODBYE CRUEL WORLD..."); 
  }
  
  
  void
  JavaAccessBridge::javaRun(JNIEnv *env, jobject obj) {
      MSG msg;
  	
      PrintDebugString("JavaAccessBridge::javaRun(%X, %X) called", env, obj);
  
      if (env->GetJavaVM(&javaVM) != 0) {
          return;	// huh!?!?!
      }
      PrintDebugString("  -> javaVM = %X", javaVM);
  
      if (javaVM->AttachCurrentThread((void **) &windowsThreadJNIEnv, NULL) != 0) {
          return;	// huh!?!?!
      }
      PrintDebugString("  -> windowsThreadJNIEnv = %X", windowsThreadJNIEnv);
  
      javaThreadABObject = env->NewGlobalRef(obj);
      windowsThreadABObject = windowsThreadJNIEnv->NewGlobalRef(obj);
  
      // initialize the Java thread AccessBridge entry points
      javaThreadEntryPoints = new AccessBridgeJavaEntryPoints(env, javaThreadABObject);
      if (javaThreadEntryPoints->BuildJavaEntryPoints() == FALSE) {
          return;		// couldn't build our entry points; let's get out of here!
      }
      PrintDebugString("  all Java thread entry points successfully found.");
  
      // initialize the Windows thread AccessBridge entry points
      windowsThreadEntryPoints = new AccessBridgeJavaEntryPoints(windowsThreadJNIEnv,
                                                                 windowsThreadABObject);
      if (windowsThreadEntryPoints->BuildJavaEntryPoints() == FALSE) {
          return;		// couldn't build our entry points; let's get out of here!
      }
      PrintDebugString("  all Windows thread entry points successfully found.");
  
  
      // open our window
      if (initWindow() == TRUE) {
          PrintDebugString("  Window created.  HWND = %X", dialogWindow);
  
          // post a broadcast msg.; let other AccessBridge DLLs know we exist
          postHelloToWindowsDLLMsg(HWND_BROADCAST);
  
          // do that message loop thing
          while (GetMessage(&msg, NULL, 0, 0)) {
              TranslateMessage(&msg);
              DispatchMessage(&msg);
          }
      } else {
          PrintDebugString("  FAILED TO CREATE WINDOW!!!");
      }
  
      javaVM->DetachCurrentThread();
  }
  
  /**
   * Bring up our window; make a connection to the rest of the world
   *
   */
  BOOL
  JavaAccessBridge::initWindow() {
      theDialogWindow = CreateDialog(windowsInstance,
                                     "ACCESSBRIDGESTATUSWINDOW", NULL,
                                     (DLGPROC) AccessBridgeDialogProc);
  
      // If window could not be created, return "failure".
      if (!theDialogWindow)
          return FALSE;
  
      dialogWindow = theDialogWindow;
  
      // Make the window visible, update its client area, & return "success".
      // DEBUG(ShowWindow (theDialogWindow, SW_SHOWNORMAL));
      // DEBUG(UpdateWindow (theDialogWindow)); 
  	
      return TRUE;      
  }
  
  
  
  // -----------------------
  
  
  /**
   * postHelloToWindowsDLLMsg
   *			- PostMessage(theFromJavaHelloMsgID) to let one or
   *			  all WindowDLLs we're here and have a vmID
   *
   *			  destHwnd is either a single hwnd or HWND_BROADCAST
   *				(former if a reply, latter if we're just born)
   *			  wParam is our HWND
   *			  lParam is our vmID
   *
   */
  void
  JavaAccessBridge::postHelloToWindowsDLLMsg(HWND destHwnd) {
      PrintDebugString("\r\nin JavaAccessBridge::postHelloToWindowsDLLMsg");
      PrintDebugString("  calling PostMessage(%X,m %X, %X, %X)", 
                       destHwnd, theFromJavaHelloMsgID, dialogWindow, javaVM);
  
      //	PostMessage(destHwnd, theFromJavaHelloMsgID, (WPARAM) dialogWindow, (LPARAM) javaVM);
      PostMessage(destHwnd, theFromJavaHelloMsgID, (WPARAM) dialogWindow, (LPARAM) dialogWindow);
  }
  
  
  // -----------------------
  
  /**
   * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging 
   *				  with the Java AccessBridge DLL
   *
   */
  void
  JavaAccessBridge::sendPackage(char *buffer, int bufsize, HWND destHwnd) {
      COPYDATASTRUCT toCopy;
      toCopy.dwData = 0;		// 32-bits we could use for something...
      toCopy.cbData = bufsize;
      toCopy.lpData = buffer;
  
      SendMessage(destHwnd, WM_COPYDATA, (WPARAM) dialogWindow, (LPARAM) &toCopy);
  }
  
  
  /**
   * sendJavaEventPackage - walk through ATs, sending event messages to 'em 
   *
   */
  void
  JavaAccessBridge::sendJavaEventPackage(char *buffer, int bufsize, long type) {
  
      PrintDebugString("JavaAccessBridge::sendJavaEventPackage(), type = %X", type);
  
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
      }
  
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          ati->sendJavaEventPackage(buffer, bufsize, type);
          ati = ati->nextATInstance;
      }
  }
  
  /**
   * sendAccessibilityEventPackage - walk through ATs, sending event messages to 'em 
   *
   */
  void
  JavaAccessBridge::sendAccessibilityEventPackage(char *buffer, int bufsize, long type) {
  
      PrintDebugString("JavaAccessBridge::sendAccessibilityEventPackage(), type = %X", type);
  
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
      }
  
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          ati->sendAccessibilityEventPackage(buffer, bufsize, type);
          ati = ati->nextATInstance;
      }
  }
  
  
  
  
  /**
   * receiveMemoryPackage - uses Memory-Mapped files to do IPC messaging 
   *						  with the Java AccessBridge DLL, receiving the
   *						  message from Java AccessBridge DLL by reading the
   *						  contents of the shared memory mapped file that
   *						  is used for Java-initiated messages
   *
   */
  BOOL
  JavaAccessBridge::receiveMemoryPackage(HWND srcWindow, long bufsize) {
      char *IPCview;
  
      PrintDebugString("\r\nJavaAccessBridge::receiveMemoryPackage(%X, %d)", srcWindow, bufsize);
  
      // look-up the appropriate IPCview based on the srcHWND of the Windows AccessBridge DLL
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR! - ATs == 0 (shouldn't happen in receiveMemoryPackage()!");
          return FALSE;
      }
      AccessBridgeATInstance *ati = ATs->findABATInstanceFromATHWND(srcWindow);
      if (ati != (AccessBridgeATInstance *) 0) {
          IPCview = (char *) ati->memoryMappedView;
  
          // wait for the lock if someone else has it (re-entrancy)
          EnterCriticalSection(&receiveMemoryIPCLock);
          {
              // set byte at end of buffer to indicate to caller that we have reached this point
              IPCview[bufsize] = 1;
  
              // process the package
              processPackage(IPCview, bufsize);
          }
          // release re-entrance lock
          LeaveCriticalSection(&receiveMemoryIPCLock);
  
          return TRUE;
  
      } else {
          DEBUG(AppendToCallInfo("ERROR receiving memory package: couldn't find srcWindow"));
          return FALSE;
      }
  }
  
  /**
   * processPackage - processes the output of SendMessage(WM_COPYDATA) 
   *					to do IPC messaging with the Windows AccessBridge DLL
   *
   */
  LRESULT
  JavaAccessBridge::processPackage(char *buffer, int bufsize) {
      PrintDebugString("\r\nProcessing package sent from Windows, bufsize = %d:", bufsize);
  
      PackageType *type = (PackageType *) buffer;
      LRESULT returnVal = 0;
      PrintDebugString("  PackageType = %X:", *type);
  
      switch (*type) {
  
  
      case cMemoryMappedFileCreatedPackage:
          // Windows is telling us it created a memory mapped file for us to use
          // in repsonding to various information querying packages (see below)
          PrintDebugString("   type == cMemoryMappedFileCreatedPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage))) {
              MemoryMappedFileCreatedPackage *pkg =
                  (MemoryMappedFileCreatedPackage *) (buffer + sizeof(PackageType));
              returnVal = MemoryMappedFileCreated(pkg->bridgeWindow, pkg->filename);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage));
          }
          break;
  
          // ------------ information querying packages ------------------
  
      case cReleaseJavaObjectPackage:
          PrintDebugString("   type == cReleaseJavaObjectPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage))) {
              ReleaseJavaObjectPackage *pkg = 
                  (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType));
              releaseJavaObject(pkg->object);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage));
          }
          break;
  
      case cGetAccessBridgeVersionPackage:
          PrintDebugString("   type == cGetAccessBridgeVersionPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage))) {
              GetAccessBridgeVersionPackage *pkg = 
                  (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getVersionInfo(&(pkg->rVersionInfo));
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage));
          }
          break;
  
      case cIsJavaWindowPackage:
          PrintDebugString("   type == cIsJavaWindowPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(IsJavaWindowPackage))) {
              IsJavaWindowPackage *pkg = 
                  (IsJavaWindowPackage *) (buffer + sizeof(PackageType));
              pkg->rResult =
                  windowsThreadEntryPoints->isJavaWindow(pkg->window);
              PrintDebugString("     -> returning result = %d", pkg->rResult);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(IsJavaWindowPackage));
          }
          break;
  
      case cIsSameObjectPackage:
          PrintDebugString("   type == cIsSameObjectPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(IsSameObjectPackage))) {
              IsSameObjectPackage *pkg = 
                  (IsSameObjectPackage *) (buffer + sizeof(PackageType));
              pkg->rResult =
                  windowsThreadEntryPoints->isSameObject(pkg->obj1, pkg->obj2);
              PrintDebugString("     -> returning result = %d", pkg->rResult);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(IsSameObjectPackage));
          }
          break;
  
  
      case cGetAccessibleContextFromHWNDPackage:
          PrintDebugString("   type == cGetAccessibleContextFromHWNDPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage))) {
              GetAccessibleContextFromHWNDPackage *pkg = 
                  (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext =
                  windowsThreadEntryPoints->getAccessibleContextFromHWND(pkg->window);
              pkg->rVMID = (int) dialogWindow;
              PrintDebugString("     -> returning AC = %X, vmID = %X", pkg->rAccessibleContext, pkg->rVMID);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage));
          }
          break;
  
  
      case cGetHWNDFromAccessibleContextPackage:
          PrintDebugString("   type == cGetHWNDFromAccessibleContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage))) {
              GetHWNDFromAccessibleContextPackage *pkg = 
                  (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType));
              pkg->rHWND =
                  windowsThreadEntryPoints->getHWNDFromAccessibleContext(pkg->accessibleContext);
              PrintDebugString("     -> returning HWND = %d", pkg->rHWND);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage));
          }
          break;
  
  
          /* ===== utility methods ===== */
  
      case cSetTextContentsPackage:
          PrintDebugString("   type == cSetTextContentsPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(SetTextContentsPackage))) {
              SetTextContentsPackage *pkg = 
                  (SetTextContentsPackage *) (buffer + sizeof(PackageType));
              pkg->rResult =
                  windowsThreadEntryPoints->setTextContents(pkg->accessibleContext, pkg->text);
              PrintDebugString("     -> returning result = %d", pkg->rResult);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(SetTextContentsPackage));
          }
          break;
  
      case cGetParentWithRolePackage:
          PrintDebugString("   type == cGetParentWithRolePackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRolePackage))) {
              GetParentWithRolePackage *pkg = 
                  (GetParentWithRolePackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext =
                  windowsThreadEntryPoints->getParentWithRole(pkg->accessibleContext, pkg->role);
              PrintDebugString("     -> returning rAccessibleContext = %x", pkg->rAccessibleContext);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetParentWithRolePackage));
          }
          break;
  
      case cGetTopLevelObjectPackage:
          PrintDebugString("   type == cGetTopLevelObjectPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetTopLevelObjectPackage))) {
              GetTopLevelObjectPackage *pkg = 
                  (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext =
                  windowsThreadEntryPoints->getTopLevelObject(pkg->accessibleContext);
              PrintDebugString("     -> returning rAccessibleContext = %x", pkg->rAccessibleContext);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetTopLevelObjectPackage));
          }
          break;
  
      case cGetParentWithRoleElseRootPackage:
          PrintDebugString("   type == cGetParentWithRoleElseRootPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage))) {
              GetParentWithRoleElseRootPackage *pkg = 
                  (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext =
                  windowsThreadEntryPoints->getParentWithRoleElseRoot(pkg->accessibleContext, pkg->role);
              PrintDebugString("     -> returning rAccessibleContext = %x", pkg->rAccessibleContext);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage));
          }
          break;
  
      case cGetObjectDepthPackage:
          PrintDebugString("   type == cGetObjectDepthPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetObjectDepthPackage))) {
              GetObjectDepthPackage *pkg = 
                  (GetObjectDepthPackage *) (buffer + sizeof(PackageType));
              pkg->rResult =
                  windowsThreadEntryPoints->getObjectDepth(pkg->accessibleContext);
              PrintDebugString("     -> returning rResult = %d", pkg->rResult);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetObjectDepthPackage));
          }
          break;
  
      case cGetActiveDescendentPackage:
          PrintDebugString("   type == cGetActiveDescendentPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetActiveDescendentPackage))) {
              GetActiveDescendentPackage *pkg = 
                  (GetActiveDescendentPackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext =
                  windowsThreadEntryPoints->getActiveDescendent(pkg->accessibleContext);
              PrintDebugString("     -> returning rAccessibleContext = %x", pkg->rAccessibleContext);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetActiveDescendentPackage));
          }
          break;
  
      case cGetAccessibleContextAtPackage:
          PrintDebugString("   type == cGetAccessibleContextAtPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage))) {
              GetAccessibleContextAtPackage *pkg = 
                  (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext = 
                  windowsThreadEntryPoints->getAccessibleContextAt(pkg->x, pkg->y, 
                                                                   pkg->AccessibleContext);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage));
          }
          break;
  
      case cGetAccessibleContextWithFocusPackage:
          PrintDebugString("   type == cGetAccessibleContextWithFocusPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage))) {
              GetAccessibleContextWithFocusPackage *pkg = 
                  (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext = 
                  windowsThreadEntryPoints->getAccessibleContextWithFocus();
              pkg->rVMID =  (int) dialogWindow;
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage));
          }
          break;
  
      case cGetAccessibleContextInfoPackage:
          PrintDebugString("   type == cGetAccessibleContextInfoPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage))) {
              GetAccessibleContextInfoPackage *pkg = 
                  (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleContextInfo(
                                                                 pkg->AccessibleContext, &(pkg->rAccessibleContextInfo));
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage));
          }
          break;
  
      case cGetAccessibleChildFromContextPackage:
          PrintDebugString("   type == cGetAccessibleChildFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage))) {
              GetAccessibleChildFromContextPackage *pkg = 
                  (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext = windowsThreadEntryPoints->getAccessibleChildFromContext(
                                                                                                pkg->AccessibleContext, pkg->childIndex);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage));
          }
          break;
  
      case cGetAccessibleParentFromContextPackage:
          PrintDebugString("   type == cGetAccessibleParentFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage))) {
              GetAccessibleParentFromContextPackage *pkg = 
                  (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext = windowsThreadEntryPoints->getAccessibleParentFromContext(
                                                                                                 pkg->AccessibleContext);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage));
          }
          break;
  
          // ------------ begin AccessibleTable packages ------------------
  
      case cGetAccessibleTableInfoPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableInfoPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage))) {
              GetAccessibleTableInfoPackage *pkg = 
                  (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTableInfo(pkg->accessibleContext, 
                                                               &(pkg->rTableInfo));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage));
          }
          break;
  
      case cGetAccessibleTableCellInfoPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableCellInfoPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage))) {
              GetAccessibleTableCellInfoPackage *pkg = 
                  (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTableCellInfo(pkg->accessibleTable, pkg->row, 
                                                                   pkg->column, &(pkg->rTableCellInfo));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage));
          }
          break;
  
      case cGetAccessibleTableRowHeaderPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableRowHeaderPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage))) {
              GetAccessibleTableRowHeaderPackage *pkg = 
                  (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTableRowHeader(pkg->accessibleContext, 
                                                                    &(pkg->rTableInfo));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage));
          }
          break;
  
      case cGetAccessibleTableColumnHeaderPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableColumnHeaderPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage))) {
              GetAccessibleTableColumnHeaderPackage *pkg = 
                  (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTableColumnHeader(pkg->accessibleContext, 
                                                                       &(pkg->rTableInfo));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage));
          }
          break;
  
  		
      case cGetAccessibleTableRowDescriptionPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableRowDescriptionPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage))) {
              GetAccessibleTableRowDescriptionPackage *pkg = 
                  (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext = windowsThreadEntryPoints->getAccessibleTableRowDescription(
                                                                                                   pkg->accessibleContext, pkg->row);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage));
          }
          break;
  
      case cGetAccessibleTableColumnDescriptionPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableColumnDescriptionPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage))) {
              GetAccessibleTableColumnDescriptionPackage *pkg = 
                  (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext = windowsThreadEntryPoints->getAccessibleTableColumnDescription(
                                                                                                      pkg->accessibleContext, pkg->column);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage));
          }
          break;
  
      case cGetAccessibleTableColumnSelectionCountPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableColumnSelectionCountPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage))) {
              GetAccessibleTableColumnSelectionCountPackage *pkg = 
                  (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType));
              pkg->rCount = windowsThreadEntryPoints->getAccessibleTableColumnSelectionCount(
                                                                                             pkg->accessibleTable);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage));
          }
          break;
  
      case cGetAccessibleTableRowSelectionCountPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableRowSelectionCountPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage))) {
              GetAccessibleTableRowSelectionCountPackage *pkg = 
                  (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType));
  
              pkg->rCount = windowsThreadEntryPoints->getAccessibleTableRowSelectionCount(
                                                                                          pkg->accessibleTable);
  
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage));
          }
          break;
  
      case cIsAccessibleTableRowSelectedPackage:
          PrintDebugString("   ##### type == cIsAccessibleTableRowSelectedPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage))) {
              IsAccessibleTableRowSelectedPackage *pkg = 
                  (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType));
              pkg->rResult = windowsThreadEntryPoints->isAccessibleTableRowSelected(
                                                                                    pkg->accessibleTable, pkg->row);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage));
          }
          break;
  
      case cIsAccessibleTableColumnSelectedPackage:
          PrintDebugString("   ##### type == cIsAccessibleTableColumnSelectedPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage))) {
              IsAccessibleTableColumnSelectedPackage *pkg = 
                  (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType));
              pkg->rResult = windowsThreadEntryPoints->isAccessibleTableColumnSelected(
                                                                                       pkg->accessibleTable, pkg->column);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage));
          }
          break;
  
      case cGetAccessibleTableColumnSelectionsPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableColumnSelectionsPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage))) {
              GetAccessibleTableColumnSelectionsPackage *pkg = 
                  (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType));
              PrintDebugString("     ##### cGetAccessibleTableColumnSelectionsPackage count=%d", pkg->count);
              windowsThreadEntryPoints->getAccessibleTableColumnSelections(
                                                                           pkg->accessibleTable, pkg->count, pkg->rSelections);
  			
              for (int i = 0; i < pkg->count; i++) {
                  PrintDebugString("     ##### cGetAccessibleTableColumnSelectionsPackage(%d)=%d", i, pkg->rSelections[i]);
              }
  			
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage));
          }
          break;
  
  
      case cGetAccessibleTableRowSelectionsPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableRowSelectionsPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage))) {
              GetAccessibleTableRowSelectionsPackage *pkg = 
                  (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTableRowSelections(
                                                                        pkg->accessibleTable, pkg->count, pkg->rSelections);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage));
          }
          break;
  
      case cGetAccessibleTableRowPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableRowPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage))) {
              GetAccessibleTableRowPackage *pkg = 
                  (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType));
              pkg->rRow = windowsThreadEntryPoints->getAccessibleTableRow(
                                                                          pkg->accessibleTable, pkg->index);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage));
          }
          break;
  
      case cGetAccessibleTableColumnPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableColumnPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage))) {
              GetAccessibleTableColumnPackage *pkg = 
                  (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType));
              pkg->rColumn = windowsThreadEntryPoints->getAccessibleTableColumn(
                                                                                pkg->accessibleTable, pkg->index);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage));
          }
          break;
  
      case cGetAccessibleTableIndexPackage:
          PrintDebugString("   ##### type == cGetAccessibleTableIndexPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage))) {
              GetAccessibleTableIndexPackage *pkg = 
                  (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType));
              pkg->rIndex = windowsThreadEntryPoints->getAccessibleTableIndex(
                                                                              pkg->accessibleTable, pkg->row, pkg->column);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage));
          }
          break;
  
          // ------------ end AccessibleTable packages ------------------
  
  
          // ------------ begin AccessibleRelationSet packages ------------------
  
      case cGetAccessibleRelationSetPackage:
          PrintDebugString("   ##### type == cGetAccessibleRelationSetPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage))) {
              GetAccessibleRelationSetPackage *pkg = 
                  (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleRelationSet(
                                                                 pkg->accessibleContext, &(pkg->rAccessibleRelationSetInfo));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage));
          }
          break;
  
          // ------------ end AccessibleRelationSet packages ------------------
  
          // ------------ begin AccessibleHypertext packages ------------------
  
      case cGetAccessibleHypertextPackage:
          PrintDebugString("   ##### type == cGetAccessibleHypertextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage))) {
              GetAccessibleHypertextPackage *pkg = 
                  (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleHypertext(
                                                               pkg->accessibleContext, &(pkg->rAccessibleHypertextInfo));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage));
          }
          break;
  
      case cActivateAccessibleHyperlinkPackage:
          PrintDebugString("   ##### type == cActivateAccessibleHyperlinkPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage))) {
              ActivateAccessibleHyperlinkPackage *pkg = 
                  (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
              pkg->rResult = windowsThreadEntryPoints->activateAccessibleHyperlink(
                                                                                   pkg->accessibleContext, pkg->accessibleHyperlink);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage));
          }
          break;
  
      case cGetAccessibleHyperlinkCountPackage:
          PrintDebugString("   ##### type == cGetAccessibleHyperlinkCountPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage))) {
              GetAccessibleHyperlinkCountPackage *pkg = 
                  (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType));
              pkg->rLinkCount = windowsThreadEntryPoints->getAccessibleHyperlinkCount(
                                                                                      pkg->accessibleContext);
              PrintDebugString("   ##### processing succeeded: pkg->rLinkCount = %d", pkg->rLinkCount);
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage));
          }
          break;
                  
      case cGetAccessibleHypertextExtPackage:
          PrintDebugString("   ##### type == cGetAccessibleHypertextExtPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage))) {
              GetAccessibleHypertextExtPackage *pkg = 
                  (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType));
              pkg->rSuccess = windowsThreadEntryPoints->getAccessibleHypertextExt(
                                                                                  pkg->accessibleContext, pkg->startIndex, &(pkg->rAccessibleHypertextInfo));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage));
          }
          break;
  
      case cGetAccessibleHypertextLinkIndexPackage:
          PrintDebugString("   ##### type == cGetAccessibleHypertextLinkIndexPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage))) {
              GetAccessibleHypertextLinkIndexPackage *pkg = 
                  (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType));
              pkg->rLinkIndex = windowsThreadEntryPoints->getAccessibleHypertextLinkIndex(
                                                                                          pkg->hypertext, pkg->charIndex);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage));
          }
          break;
  
      case cGetAccessibleHyperlinkPackage:
          PrintDebugString("   ##### type == cGetAccessibleHyperlinkPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage))) {
              GetAccessibleHyperlinkPackage *pkg = 
                  (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleHyperlink(pkg->hypertext, pkg->linkIndex, 
                                                               &(pkg->rAccessibleHyperlinkInfo));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage));
          }
          break;
  
          // ------------ end AccessibleHypertext packages
  
          // ------------ begin Accessible KeyBindings, Icons and Actions 
  
      case cGetAccessibleKeyBindingsPackage:
          PrintDebugString("   ##### type == cGetAccessibleKeyBindingsPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage))) {
              GetAccessibleKeyBindingsPackage *pkg = 
                  (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleKeyBindings (
                                                                  pkg->accessibleContext, &(pkg->rAccessibleKeyBindings));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage));
          }
          break;
  
      case cGetAccessibleIconsPackage:
          PrintDebugString("   ##### type == cGetAccessibleIconsPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleIconsPackage))) {
              GetAccessibleIconsPackage *pkg = 
                  (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleIcons (
                                                            pkg->accessibleContext, &(pkg->rAccessibleIcons));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleIconsPackage));
          }
          break;
  
  
      case cGetAccessibleActionsPackage:
          PrintDebugString("   ##### type == cGetAccessibleActionsPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleActionsPackage))) {
              GetAccessibleActionsPackage *pkg = 
                  (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleActions (
                                                              pkg->accessibleContext, &(pkg->rAccessibleActions));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleActionsPackage));
          }
          break;
  
      case cDoAccessibleActionsPackage:
          PrintDebugString("   ##### type == cDoAccessibleActionsPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(DoAccessibleActionsPackage))) {
              DoAccessibleActionsPackage *pkg = 
                  (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType));
              pkg->rResult =
                  windowsThreadEntryPoints->doAccessibleActions(pkg->accessibleContext, &(pkg->actionsToDo),
                                                                &(pkg->failure));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(DoAccessibleActionsPackage));
          }
          break;
  
          // ------------ begin addtional methods for Teton 
          
      case cGetVirtualAccessibleNamePackage:
          PrintDebugString("   ##### type == GetVirtualAccessibleNamePackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage))) {
              GetVirtualAccessibleNamePackage *pkg = 
                  (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getVirtualAccessibleName (pkg->accessibleContext, 
                                                               pkg->rName,
                                                               pkg->len);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage));
          }
          break;
          
      case cRequestFocusPackage:
          PrintDebugString("   ##### type == RequestFocusPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(RequestFocusPackage))) {
              RequestFocusPackage *pkg = 
                  (RequestFocusPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->requestFocus (
                                                      pkg->accessibleContext);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(RequestFocusPackage));
          }
          break;
          
      case cSelectTextRangePackage:
          PrintDebugString("   ##### type == SelectTextRangePackage");
          if (bufsize == (sizeof(PackageType) + sizeof(SelectTextRangePackage))) {
              SelectTextRangePackage *pkg = 
                  (SelectTextRangePackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->selectTextRange (
                                                         pkg->accessibleContext, pkg->startIndex, pkg->endIndex);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(SelectTextRangePackage));
          }
          break;
          
      case cGetTextAttributesInRangePackage:
          PrintDebugString("   ##### type == GetTextAttributesInRangePackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage))) {
              GetTextAttributesInRangePackage *pkg = 
                  (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getTextAttributesInRange (
                                                                  pkg->accessibleContext, pkg->startIndex, pkg->endIndex,
                                                                  (AccessibleTextAttributesInfo *)&(pkg->attributes), 
                                                                  &(pkg->rLength));
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage));
          }
          break;
          
          
      case cGetVisibleChildrenCountPackage:
          PrintDebugString("   ##### type == GetVisibleChildrenCountPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage))) {
              GetVisibleChildrenCountPackage *pkg = 
                  (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType));
              pkg->rChildrenCount = windowsThreadEntryPoints->getVisibleChildrenCount (pkg->accessibleContext);
                                                            
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage));
          }
          break;
          
      case cGetVisibleChildrenPackage:
          PrintDebugString("   ##### type == GetVisibleChildrenPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenPackage))) {
              GetVisibleChildrenPackage *pkg = 
                  (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType));
              pkg->rSuccess = windowsThreadEntryPoints->getVisibleChildren (pkg->accessibleContext, 
                                                                            pkg->startIndex,
                                                                            &(pkg->rVisibleChildrenInfo));
                                                            
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenPackage));
          }
          break;
          
      case cSetCaretPositionPackage:
          PrintDebugString("   ##### type == SetCaretPositionPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(SetCaretPositionPackage))) {
              SetCaretPositionPackage *pkg = 
                  (SetCaretPositionPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->setCaretPosition (
                                                          pkg->accessibleContext, pkg->position);
              PrintDebugString("   ##### processing succeeded");
          } else {
              PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(SetCaretPositionPackage));
          }
          break;	
          
          // ------------ end additional methods for Teton
          
          // ------------ end Accessible KeyBindings, Icons and Actions 
  
          // ------------ Accessible Text packages ------------------
  
      case cGetAccessibleTextInfoPackage:
          PrintDebugString("   type == cGetAccessibleTextInfoPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage))) {
              GetAccessibleTextInfoPackage *pkg = 
                  (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTextInfo(pkg->AccessibleContext, 
                                                              &(pkg->rTextInfo), pkg->x, pkg->y);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage));
          }
          break;
  		
      case cGetAccessibleTextItemsPackage:
          PrintDebugString("   type == cGetAccessibleTextItemsPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage))) {
              GetAccessibleTextItemsPackage *pkg = 
                  (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTextItems(pkg->AccessibleContext, 
                                                               &(pkg->rTextItemsInfo), pkg->index);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage));
          }
          break;
  		
      case cGetAccessibleTextSelectionInfoPackage:
          PrintDebugString("   type == cGetAccessibleTextSelectionInfoPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage))) {
              GetAccessibleTextSelectionInfoPackage *pkg = 
                  (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTextSelectionInfo(
                                                                       pkg->AccessibleContext, &(pkg->rTextSelectionItemsInfo));
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage));
          }
          break;
  		
      case cGetAccessibleTextAttributeInfoPackage:
          PrintDebugString("   type == cGetAccessibleTextAttributeInfoPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage))) {
              GetAccessibleTextAttributeInfoPackage *pkg = 
                  (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTextAttributes(
                                                                    pkg->AccessibleContext, pkg->index, (AccessibleTextAttributesInfo *) &(pkg->rAttributeInfo));
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage));
          }
          break;
  		
      case cGetAccessibleTextRectInfoPackage:
          PrintDebugString("   type == cGetAccessibleTextRectInfoPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage))) {
              GetAccessibleTextRectInfoPackage *pkg = 
                  (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTextRect(pkg->AccessibleContext,
                                                              &(pkg->rTextRectInfo), pkg->index);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage));
          }
          break;
  
      case cGetCaretLocationPackage:
          PrintDebugString("   type == cGetCaretLocationPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetCaretLocationPackage))) {
              GetCaretLocationPackage *pkg = 
                  (GetCaretLocationPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getCaretLocation(pkg->AccessibleContext,
                                                              &(pkg->rTextRectInfo), pkg->index);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetCaretLocationPackage));
          }
          break;
  
      case cGetAccessibleTextLineBoundsPackage:
          PrintDebugString("   type == cGetAccessibleTextLineBoundsPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage))) {
              GetAccessibleTextLineBoundsPackage *pkg = 
                  (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTextLineBounds(pkg->AccessibleContext,
                                                                    pkg->index, &(pkg->rLineStart), &(pkg->rLineEnd));
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage));
          }
          break;
  
      case cGetAccessibleTextRangePackage:
          PrintDebugString("   type == cGetAccessibleTextRangePackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage))) {
              GetAccessibleTextRangePackage *pkg = 
                  (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getAccessibleTextRange(pkg->AccessibleContext,
                                                               pkg->start, pkg->end, (wchar_t *) &(pkg->rText), (sizeof(pkg->rText) / sizeof(wchar_t)));
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage));
          }
          break;
  
  
          // ------------ Accessible Value packages ------------------
          
      case cGetCurrentAccessibleValueFromContextPackage:
          PrintDebugString("   type == cGetCurrentAccessibleValueFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage))) {
              GetCurrentAccessibleValueFromContextPackage *pkg = 
                  (GetCurrentAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getCurrentAccessibleValueFromContext(pkg->AccessibleContext,
                                                                             (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage));
          }
          break;
  
      case cGetMaximumAccessibleValueFromContextPackage:
          PrintDebugString("   type == cGetMaximumAccessibleValueFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage))) {
              GetMaximumAccessibleValueFromContextPackage *pkg = 
                  (GetMaximumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getMaximumAccessibleValueFromContext(pkg->AccessibleContext,
                                                                             (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage));
          }
          break;
  
      case cGetMinimumAccessibleValueFromContextPackage:
          PrintDebugString("   type == cGetMinimumAccessibleValueFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage))) {
              GetMinimumAccessibleValueFromContextPackage *pkg = 
                  (GetMinimumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->getMinimumAccessibleValueFromContext(pkg->AccessibleContext,
                                                                             (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage));
          }
          break;
  
          // ------------ Accessible Selection packages ------------------
  
      case cAddAccessibleSelectionFromContextPackage:
          PrintDebugString("   type == cAddAccessibleSelectionFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage))) {
              AddAccessibleSelectionFromContextPackage *pkg = 
                  (AddAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->addAccessibleSelectionFromContext(pkg->AccessibleContext,
                                                                          pkg->index);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage));
          }
          break;
  
      case cClearAccessibleSelectionFromContextPackage:
          PrintDebugString("   type == cClearAccessibleSelectionFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage))) {
              ClearAccessibleSelectionFromContextPackage *pkg = 
                  (ClearAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->clearAccessibleSelectionFromContext(pkg->AccessibleContext);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage));
          }
          break;
  
      case cGetAccessibleSelectionFromContextPackage:
          PrintDebugString("   type == cGetAccessibleSelectionFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage))) {
              GetAccessibleSelectionFromContextPackage *pkg = 
                  (GetAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
              pkg->rAccessibleContext = windowsThreadEntryPoints->getAccessibleSelectionFromContext(
                                                                                                    pkg->AccessibleContext, pkg->index);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage));
          }
          break;
  
      case cGetAccessibleSelectionCountFromContextPackage:
          PrintDebugString("   type == cGetAccessibleSelectionCountFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage))) {
              GetAccessibleSelectionCountFromContextPackage *pkg = 
                  (GetAccessibleSelectionCountFromContextPackage *) (buffer + sizeof(PackageType));
              pkg->rCount = windowsThreadEntryPoints->getAccessibleSelectionCountFromContext(
                                                                                             pkg->AccessibleContext);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage));
          }
          break;
  
      case cIsAccessibleChildSelectedFromContextPackage:
          PrintDebugString("   type == cIsAccessibleChildSelectedFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage))) {
              IsAccessibleChildSelectedFromContextPackage *pkg = 
                  (IsAccessibleChildSelectedFromContextPackage *) (buffer + sizeof(PackageType));
              pkg->rResult = windowsThreadEntryPoints->isAccessibleChildSelectedFromContext(
                                                                                            pkg->AccessibleContext, pkg->index);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage));
          }
          break;
  
      case cRemoveAccessibleSelectionFromContextPackage:
          PrintDebugString("   type == cRemoveAccessibleSelectionFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage))) {
              RemoveAccessibleSelectionFromContextPackage *pkg = 
                  (RemoveAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->removeAccessibleSelectionFromContext(pkg->AccessibleContext,
                                                                             pkg->index);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage));
          }
          break;
  
      case cSelectAllAccessibleSelectionFromContextPackage:
          PrintDebugString("   type == cSelectAllAccessibleSelectionFromContextPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage))) {
              SelectAllAccessibleSelectionFromContextPackage *pkg = 
                  (SelectAllAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
              windowsThreadEntryPoints->selectAllAccessibleSelectionFromContext(pkg->AccessibleContext);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage));
          }
          break;
  
  		
          // ------------ event notification management packages ------------------
  
      case cAddJavaEventNotificationPackage:
          PrintDebugString("   type = cAddJavaEventNotificationPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage))) {
              AddJavaEventNotificationPackage *pkg = 
                  (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
              addJavaEventNotification(pkg->type, pkg->DLLwindow);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage));
          }
          break;
  
      case cRemoveJavaEventNotificationPackage:
          PrintDebugString("   type = cRemoveJavaEventNotificationPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage))) {
              RemoveJavaEventNotificationPackage *pkg = 
                  (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
              removeJavaEventNotification(pkg->type, pkg->DLLwindow);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage));
          }
          break;
  
      case cAddAccessibilityEventNotificationPackage:
          PrintDebugString("   type = cAddAccessibilityEventNotificationPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage))) {
              AddAccessibilityEventNotificationPackage *pkg = 
                  (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
              addAccessibilityEventNotification(pkg->type, pkg->DLLwindow);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage));
          }
          break;
  
      case cRemoveAccessibilityEventNotificationPackage:
          PrintDebugString("   type = cRemoveAccessibilityEventNotificationPackage");
          if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage))) {
              RemoveAccessibilityEventNotificationPackage *pkg = 
                  (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
              removeAccessibilityEventNotification(pkg->type, pkg->DLLwindow);
          } else {
              PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
                               bufsize, sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage));
          }
          break;
  
      default:
          PrintDebugString("   processing FAILED!! -> don't know how to handle type = %X", *type);
          returnVal = -1;
          break;
      }
  
      PrintDebugString("   package processing completed");
      return returnVal;
  }
  
  
  // -----------------------------
  
  
  /**
   * MemoryMappedFileCreated
   *			- WindowsDLL letting us know it's created a memory-mapped file
   *			  for IPC.  We need to open it and write a magic string into
   *			  it to let the WindowsDLL know all is OK.  Also we need to
   *			  set up our own data structures to communicate with the
   *			  WindowsDLL
   *
   */
  LRESULT
  JavaAccessBridge::MemoryMappedFileCreated(HWND ATBridgeDLLWindow, char *filename) {
      PrintDebugString("  in MemoryMappedFileCreated(%X, %s)!", ATBridgeDLLWindow, filename);
      AccessBridgeATInstance *newAT = 
          new AccessBridgeATInstance(dialogWindow, ATBridgeDLLWindow, filename, ATs);
      PrintDebugString("    just created a new ATInstance = %X, old = %X", newAT, ATs);
      ATs = newAT;
  
      LRESULT returnVal = ATs->initiateIPC();
      if (returnVal == 0) {
          PrintDebugString("  Successfully initiated IPC with AT!!!");
      } else {
          PrintDebugString("  ERROR: Failed to initiate IPC with AT!!!");
      }
  
      return returnVal;
  }
  
  
  /**
   * WindowsATDestroyed - lets the JavaABDLL know a Windows AT disappeared
   *
   */
  void
  JavaAccessBridge::WindowsATDestroyed(HWND ATBridgeDLLWindow) {
      PrintDebugString("\r\nin JavaAccessBridge::WindowsATDestroyed(%X)", ATBridgeDLLWindow);
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! -> ATs == 0! (shouldn't happen here)");
          return;
      }
  
      AccessBridgeATInstance *currentAT = ATs;
      AccessBridgeATInstance *previousAT = ATs;
      if (ATs->winAccessBridgeWindow == ATBridgeDLLWindow) {
          ATs = ATs->nextATInstance;
          // remove event notification for this AT
          removeJavaEventNotification(currentAT->javaEventMask, ATBridgeDLLWindow);
          removeAccessibilityEventNotification(currentAT->accessibilityEventMask, ATBridgeDLLWindow);
          delete currentAT;
          PrintDebugString("  data structures successfully removed");
      } else {
          while (currentAT != (AccessBridgeATInstance *) NULL) {
              if (currentAT->winAccessBridgeWindow == ATBridgeDLLWindow) {
                  previousAT->nextATInstance = currentAT->nextATInstance;
                  delete currentAT;
                  PrintDebugString("  data structures successfully removed");
                  return;
              } else {
                  previousAT = currentAT;
                  currentAT = currentAT->nextATInstance;
              }
          }
          PrintDebugString("  ERROR!! couldn't find matching data structures!");
      }
  }
  
  
  // -----------------------------
  
  
  /**
   * releaseJavaObject - lets the JavaVM know it can release the Java Object
   *
   * Note: once you have made this call, the JavaVM will garbage collect
   * the jobject you pass in.  If you later use that jobject in another
   * call, you will cause all maner of havoc!
   *
   */
  void
  JavaAccessBridge::releaseJavaObject(jobject object) {
      if (windowsThreadJNIEnv != (JNIEnv *) 0) {
          windowsThreadJNIEnv->DeleteGlobalRef(object);
          PrintDebugString("  global reference deleted.", object);
      } else {
          PrintDebugString("  Error! windowsThreadJNIEnv == 0");
      }
  }
  
  // -----------------------------
  
  /**
   * addJavaEventNotification - this AT now wants this type of events
   *
   */
  void
  JavaAccessBridge::addJavaEventNotification(jlong type, HWND DLLwindow) {
      // walk through list of ATs, find this one and add this type
      // and, if we weren't listening for these before, ask Java for 'em
      PrintDebugString("  adding Java event type %X to HWND %X", type, DLLwindow);
      AccessBridgeATInstance *ati = ATs;
      long globalEventMask = 0;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->winAccessBridgeWindow == DLLwindow) {
              ati->javaEventMask |= type;
              PrintDebugString("  found HWND, javaEventMask now is %X", ati->javaEventMask);
          } else {
              globalEventMask |= ati->javaEventMask;
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  union of all Java AT event masks: %X", globalEventMask);
      if (!(globalEventMask & type)) {
          // no other ATs wanted this event; 
          // start getting them from Java
          PrintDebugString("  no other AT wanted this Java event (so not registered); adding to AccessBridge.java");
          windowsThreadEntryPoints->addJavaEventNotification(type);
      }
  }
  
  /**
   * removeJavaEventNotification - this AT no longer wants this type of events
   *
   */
  void
  JavaAccessBridge::removeJavaEventNotification(jlong type, HWND DLLwindow) {
      // walk through list of ATs, find this one and remove this type
      // and, if no other AT wants 'em either, tell Java we no longer want 'em
      PrintDebugString("  removing Java event type %X from HWND %X", type, DLLwindow);
      AccessBridgeATInstance *ati = ATs;
      long globalEventMask = 0;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->winAccessBridgeWindow == DLLwindow) {
              ati->javaEventMask &= (0xFFFFFFFF - type);
              PrintDebugString("  found HWND, javaEventMask now is %X", ati->javaEventMask);
          } else {
              globalEventMask |= ati->javaEventMask;
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  union of all Java AT event masks: %X", globalEventMask);
      if (!(globalEventMask & type)) {
          // no other ATs wanted this event; 
          // stop getting them from Java
          PrintDebugString("  no other AT wanted this Java event (so can remove); removing from AccessBridge.java");
          windowsThreadEntryPoints->removeJavaEventNotification(type);
      }
  }
  
  
  /**
   * addAccesibilityEventNotification - this AT now wants this type of events
   *
   */
  void
  JavaAccessBridge::addAccessibilityEventNotification(jlong type, HWND DLLwindow) {
      // walk through list of ATs, find this one and add this type
      // and, if we weren't listening for these before, ask Java for 'em
      PrintDebugString("  adding Accesibility event type %X to HWND %X", type, DLLwindow);
      AccessBridgeATInstance *ati = ATs;
      long globalEventMask = 0;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->winAccessBridgeWindow == DLLwindow) {
              ati->accessibilityEventMask |= type;
              PrintDebugString("  found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask);
          } else {
              globalEventMask |= ati->accessibilityEventMask;
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  union of all Accessibility AT event masks: %X", globalEventMask);
      if (!(globalEventMask & type)) {
          // no other ATs wanted this event; 
          // start getting them from Java
          PrintDebugString("  no other AT wanted this Accesibility event (so not registered); adding to AccessBridge.java");
          windowsThreadEntryPoints->addAccessibilityEventNotification(type);
      }
  }
  
  /**
   * removeAccesibilityEventNotification - this AT no longer wants this type of events
   *
   */
  void
  JavaAccessBridge::removeAccessibilityEventNotification(jlong type, HWND DLLwindow) {
      // walk through list of ATs, find this one and remove this type
      // and, if no other AT wants 'em either, tell Java we no longer want 'em
      PrintDebugString("  removing Accesibility event type %X from HWND %X", type, DLLwindow);
      AccessBridgeATInstance *ati = ATs;
      long globalEventMask = 0;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->winAccessBridgeWindow == DLLwindow) {
              ati->accessibilityEventMask &= (0xFFFFFFFF - type);
              PrintDebugString("  found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask);
          } else {
              globalEventMask |= ati->accessibilityEventMask;
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  union of all Accessibility AT event masks: %X", globalEventMask);
      if (!(globalEventMask & type)) {
          // no other ATs wanted this event; 
          // stop getting them from Java
          PrintDebugString("  no other AT wanted this Accessibility event (so can remove); removing from AccessBridge.java");
          windowsThreadEntryPoints->removeAccessibilityEventNotification(type);
      }
  }
  
  
  
  
  /**
   * firePropertyCaretChange
   *
   */
  void
  JavaAccessBridge::firePropertyCaretChange(JNIEnv *env, jobject callingObj, 
                                            jobject event, jobject source,
                                            jint oldValue, jint newValue) {
  
      PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyCaretChanged(%X, %X, %X, %X, %d, %d)", 
                       env, callingObj, event, 
                       source, oldValue, newValue);
  
      // sanity check
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
          return;		// panic!
      }
  
      // common setup
      char buffer[sizeof(PackageType) + sizeof(PropertyCaretChangePackage)];
      PackageType *type = (PackageType *) buffer;
      PropertyCaretChangePackage *pkg = (PropertyCaretChangePackage *) (buffer + sizeof(PackageType));
      *type = cPropertyCaretChangePackage;
      pkg->vmID = (long) dialogWindow;
  
      // make new Global Refs and send events only to those ATs that want 'em
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) {
  
              PrintDebugString("  sending to AT");
  
              // make new GlobalRefs for this AT
              pkg->Event = env->NewGlobalRef(event);
              pkg->AccessibleContextSource = env->NewGlobalRef(source);
  
              pkg->oldPosition = oldValue;
              pkg->newPosition = newValue;
  
              ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyCaretChangeEvent);
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  done with propertyCaretChange event");
  }
  
  /**
   * firePropertyDescriptionChange
   *
   */
  void
  JavaAccessBridge::firePropertyDescriptionChange(JNIEnv *env, jobject callingObj, 
                                                  jobject event, jobject source,
                                                  jstring oldValue, jstring newValue){
  
      PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyDescriptionChanged(%X, %X, %X, %X, %X, %X)", 
                       env, callingObj, event, 
                       source, oldValue, newValue);
  
      // sanity check
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
          return;		// panic!
      }
  
      // common setup
      const wchar_t *stringBytes;
      char buffer[sizeof(PackageType) + sizeof(PropertyDescriptionChangePackage)];
      PackageType *type = (PackageType *) buffer;
      PropertyDescriptionChangePackage *pkg = (PropertyDescriptionChangePackage *) (buffer + sizeof(PackageType));
      *type = cPropertyDescriptionChangePackage;
      pkg->vmID = (long) dialogWindow;
  
      // make new Global Refs and send events only to those ATs that want 'em
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) {
  
              PrintDebugString("  sending to AT");
  
              // make new GlobalRefs for this AT
              pkg->Event = env->NewGlobalRef(event);
              pkg->AccessibleContextSource = env->NewGlobalRef(source);
  
              if (oldValue != (jstring) 0) {
                  stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
                  wcsncpy(pkg->oldDescription, stringBytes, (sizeof(pkg->oldDescription) / sizeof(wchar_t)));
                  env->ReleaseStringChars(oldValue, stringBytes);
              } else {
                  wcsncpy(pkg->oldDescription, L"(null)", (sizeof(pkg->oldDescription) / sizeof(wchar_t)));
              }
  
              if (newValue != (jstring) 0) {
                  stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
                  wcsncpy(pkg->newDescription, stringBytes, (sizeof(pkg->newDescription) / sizeof(wchar_t)));
                  env->ReleaseStringChars(newValue, stringBytes);
              } else {
                  wcsncpy(pkg->newDescription, L"(null)", (sizeof(pkg->newDescription) / sizeof(wchar_t)));
              }
  
              ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyDescriptionChangeEvent);
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  done with propertyDescriptionChange event");
  }
  
  /**
   * firePropertyNameChange
   *
   */
  void
  JavaAccessBridge::firePropertyNameChange(JNIEnv *env, jobject callingObj, 
                                           jobject event, jobject source,
                                           jstring oldValue, jstring newValue){
  
      PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyNameChanged(%X, %X, %X, %X, %X, %X)", 
                       env, callingObj, event, 
                       source, oldValue, newValue);
  
      // sanity check
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
          return;		// panic!
      }
  
      // common setup
      const wchar_t *stringBytes;
      char buffer[sizeof(PackageType) + sizeof(PropertyNameChangePackage)];
      PackageType *type = (PackageType *) buffer;
      PropertyNameChangePackage *pkg = (PropertyNameChangePackage *) (buffer + sizeof(PackageType));
      *type = cPropertyNameChangePackage;
      pkg->vmID = (long) dialogWindow;
  
      // make new Global Refs and send events only to those ATs that want 'em
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->accessibilityEventMask & cPropertyNameChangeEvent) {
  
              PrintDebugString("  sending to AT");
  
              // make new GlobalRefs for this AT
              pkg->Event = env->NewGlobalRef(event);
              pkg->AccessibleContextSource = env->NewGlobalRef(source);
  
              if (oldValue != (jstring) 0) {
                  stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
                  wcsncpy(pkg->oldName, stringBytes, (sizeof(pkg->oldName) / sizeof(wchar_t)));
                  env->ReleaseStringChars(oldValue, stringBytes);
              } else {
                  wcsncpy(pkg->oldName, L"(null)", (sizeof(pkg->oldName) / sizeof(wchar_t)));
              }
  
              if (newValue != (jstring) 0) {
                  stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
                  wcsncpy(pkg->newName, stringBytes, (sizeof(pkg->newName) / sizeof(wchar_t)));
                  env->ReleaseStringChars(newValue, stringBytes);
              } else {
                  wcsncpy(pkg->newName, L"(null)", (sizeof(pkg->newName) / sizeof(wchar_t)));
              }
  
              ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyNameChangeEvent);
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  done with propertyNameChange event");
  }
  
  
  /**
   * firePropertySelectionChange
   *
   */
  void
  JavaAccessBridge::firePropertySelectionChange(JNIEnv *env, jobject callingObj, 
                                                jobject event, jobject source) {
  
      PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertySelectionChanged(%X, %X, %X, %X)", 
                       env, callingObj, event, source);
  
      // sanity check
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
          return;		// panic!
      }
  
      // common setup
      char buffer[sizeof(PackageType) + sizeof(PropertySelectionChangePackage)];
      PackageType *type = (PackageType *) buffer;
      PropertySelectionChangePackage *pkg = (PropertySelectionChangePackage *) (buffer + sizeof(PackageType));
      *type = cPropertySelectionChangePackage;
      pkg->vmID = (long) dialogWindow;
  
      // make new Global Refs and send events only to those ATs that want 'em
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->accessibilityEventMask & cPropertySelectionChangeEvent) {
  
              PrintDebugString("  sending to AT");
  
              // make new GlobalRefs for this AT
              pkg->Event = env->NewGlobalRef(event);
              pkg->AccessibleContextSource = env->NewGlobalRef(source);
  
              ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertySelectionChangeEvent);
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  done with propertySelectionChange event");
  }
  
  
  /**
   * firePropertyStateChange
   *
   */
  void
  JavaAccessBridge::firePropertyStateChange(JNIEnv *env, jobject callingObj, 
                                            jobject event, jobject source,
                                            jstring oldValue, jstring newValue){
  
      PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyStateChanged(%X, %X, %X, %X, %X, %X)", 
                       env, callingObj, event, 
                       source, oldValue, newValue);
  
      // sanity check
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
          return;		// panic!
      }
  
      // common setup
      const wchar_t *stringBytes;
      char buffer[sizeof(PackageType) + sizeof(PropertyStateChangePackage)];
      PackageType *type = (PackageType *) buffer;
      PropertyStateChangePackage *pkg = (PropertyStateChangePackage *) (buffer + sizeof(PackageType));
      *type = cPropertyStateChangePackage;
      pkg->vmID = (long) dialogWindow;
  
      // make new Global Refs and send events only to those ATs that want 'em
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->accessibilityEventMask & cPropertyStateChangeEvent) {
  
              PrintDebugString("  sending to AT");
  
              // make new GlobalRefs for this AT
              pkg->Event = env->NewGlobalRef(event);
              pkg->AccessibleContextSource = env->NewGlobalRef(source);
  
              if (oldValue != (jstring) 0) {
                  stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
                  wcsncpy(pkg->oldState, stringBytes, (sizeof(pkg->oldState) / sizeof(wchar_t)));
                  env->ReleaseStringChars(oldValue, stringBytes);
              } else {
                  wcsncpy(pkg->oldState, L"(null)", (sizeof(pkg->oldState) / sizeof(wchar_t)));
              }
  
              if (newValue != (jstring) 0) {
                  stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
                  wcsncpy(pkg->newState, stringBytes, (sizeof(pkg->newState) / sizeof(wchar_t)));
                  env->ReleaseStringChars(newValue, stringBytes);
              } else {
                  wcsncpy(pkg->newState, L"(null)", (sizeof(pkg->newState) / sizeof(wchar_t)));
              }
  
              ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyStateChangeEvent);
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  done with propertyStateChange event");
  }
  
  
  /**
   * firePropertyTextChange
   *
   */
  void
  JavaAccessBridge::firePropertyTextChange(JNIEnv *env, jobject callingObj, 
                                           jobject event, jobject source) {
  
      PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTextChanged(%X, %X, %X, %X)", 
                       env, callingObj, event, source);
  
      // sanity check
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
          return;		// panic!
      }
  
      // common setup
      char buffer[sizeof(PackageType) + sizeof(PropertyTextChangePackage)];
      PackageType *type = (PackageType *) buffer;
      PropertyTextChangePackage *pkg = (PropertyTextChangePackage *) (buffer + sizeof(PackageType));
      *type = cPropertyTextChangePackage;
      pkg->vmID = (long) dialogWindow;
  
      // make new Global Refs and send events only to those ATs that want 'em
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->accessibilityEventMask & cPropertyTextChangeEvent) {
  
              PrintDebugString("  sending to AT");
  
              // make new GlobalRefs for this AT
              pkg->Event = env->NewGlobalRef(event);
              pkg->AccessibleContextSource = env->NewGlobalRef(source);
  
              ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTextChangeEvent);
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  done with propertyTextChange event");
  }
  
  
  /**
   * firePropertyValueChange
   *
   */
  void
  JavaAccessBridge::firePropertyValueChange(JNIEnv *env, jobject callingObj, 
                                            jobject event, jobject source,
                                            jstring oldValue, jstring newValue){
  
      PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyValueChanged(%X, %X, %X, %X, %X, %X)", 
                       env, callingObj, event, 
                       source, oldValue, newValue);
  
      // sanity check
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
          return;		// panic!
      }
  
      // common setup
      const wchar_t *stringBytes;
      char buffer[sizeof(PackageType) + sizeof(PropertyValueChangePackage)];
      PackageType *type = (PackageType *) buffer;
      PropertyValueChangePackage *pkg = (PropertyValueChangePackage *) (buffer + sizeof(PackageType));
      *type = cPropertyValueChangePackage;
      pkg->vmID = (long) dialogWindow;
  
      // make new Global Refs and send events only to those ATs that want 'em
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->accessibilityEventMask & cPropertyValueChangeEvent) {
  
              PrintDebugString("  sending to AT");
  
              // make new GlobalRefs for this AT
              pkg->Event = env->NewGlobalRef(event);
              pkg->AccessibleContextSource = env->NewGlobalRef(source);
  
              if (oldValue != (jstring) 0) {
                  stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
                  wcsncpy(pkg->oldValue, stringBytes, (sizeof(pkg->oldValue) / sizeof(wchar_t)));
                  env->ReleaseStringChars(oldValue, stringBytes);
              } else {
                  wcsncpy(pkg->oldValue, L"(null)", (sizeof(pkg->oldValue) / sizeof(wchar_t)));
              }
  
              if (newValue != (jstring) 0) {
                  stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
                  wcsncpy(pkg->newValue, stringBytes, (sizeof(pkg->newValue) / sizeof(wchar_t)));
                  env->ReleaseStringChars(newValue, stringBytes);
              } else {
                  wcsncpy(pkg->newValue, L"(null)", (sizeof(pkg->newValue) / sizeof(wchar_t)));
              }
  
              ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyValueChangeEvent);
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  done with propertyValueChange event");
  }
  
  /**
   * firePropertyVisibleDataChange
   *
   */
  void
  JavaAccessBridge::firePropertyVisibleDataChange(JNIEnv *env, jobject callingObj, 
                                                  jobject event, jobject source) {
  
      PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChanged(%X, %X, %X, %X)", 
                       env, callingObj, event, source);
  
      // sanity check
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
          return;		// panic!
      }
  
      // common setup
      char buffer[sizeof(PackageType) + sizeof(PropertyVisibleDataChangePackage)];
      PackageType *type = (PackageType *) buffer;
      PropertyVisibleDataChangePackage *pkg = (PropertyVisibleDataChangePackage *) (buffer + sizeof(PackageType));
      *type = cPropertyVisibleDataChangePackage;
      pkg->vmID = (long) dialogWindow;
  
      // make new Global Refs and send events only to those ATs that want 'em
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->accessibilityEventMask & cPropertyVisibleDataChangeEvent) {
  
              PrintDebugString("  sending to AT");
  
              // make new GlobalRefs for this AT
              pkg->Event = env->NewGlobalRef(event);
              pkg->AccessibleContextSource = env->NewGlobalRef(source);
  
              ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyVisibleDataChangeEvent);
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  done with propertyVisibleDataChange event");
  }
  
  
  /**
   * firePropertyChildChange
   *
   */
  void
  JavaAccessBridge::firePropertyChildChange(JNIEnv *env, jobject callingObj, 
                                            jobject event, jobject source,
                                            jobject oldValue, jobject newValue){
  
      PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyChildPropertyChanged(%X, %X, %X, %X, %X, %X)", 
                       env, callingObj, event, 
                       source, oldValue, newValue);
  
      // sanity check
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
          return;		// panic!
      }
  
      // common setup
      char buffer[sizeof(PackageType) + sizeof(PropertyChildChangePackage)];
      PackageType *type = (PackageType *) buffer;
      PropertyChildChangePackage *pkg = (PropertyChildChangePackage *) (buffer + sizeof(PackageType));
      *type = cPropertyChildChangePackage;
      pkg->vmID = (long) dialogWindow;
  
      // make new Global Refs and send events only to those ATs that want 'em
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->accessibilityEventMask & cPropertyChildChangeEvent) {
  
              PrintDebugString("  sending to AT");
  
              // make new GlobalRefs for this AT
              pkg->Event = env->NewGlobalRef(event);
              pkg->AccessibleContextSource = env->NewGlobalRef(source);
              pkg->oldChildAccessibleContext = env->NewGlobalRef(oldValue);
              pkg->newChildAccessibleContext = env->NewGlobalRef(newValue);
  
              ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyChildChangeEvent);
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  done with propertyChildChange event");
  }
  
  
  /**
   * firePropertyActiveDescendentChange
   *
   */
  void
  JavaAccessBridge::firePropertyActiveDescendentChange(JNIEnv *env, jobject callingObj, 
                                                       jobject event, jobject source,
                                                       jobject oldValue, jobject newValue){
  
      PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentPropertyChanged(%X, %X, %X, %X, %X, %X)", 
                       env, callingObj, event, 
                       source, oldValue, newValue);
  
      // sanity check
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
          return;		// panic!
      }
  
      // common setup
      char buffer[sizeof(PackageType) + sizeof(PropertyActiveDescendentChangePackage)];
      PackageType *type = (PackageType *) buffer;
      PropertyActiveDescendentChangePackage *pkg = (PropertyActiveDescendentChangePackage *) (buffer + sizeof(PackageType));
      *type = cPropertyActiveDescendentChangePackage;
      pkg->vmID = (long) dialogWindow;
  
      // make new Global Refs and send events only to those ATs that want 'em
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->accessibilityEventMask & cPropertyActiveDescendentChangeEvent) {
  
              PrintDebugString("  sending to AT");
  
              // make new GlobalRefs for this AT
              pkg->Event = env->NewGlobalRef(event);
              pkg->AccessibleContextSource = env->NewGlobalRef(source);
              pkg->oldActiveDescendentAccessibleContext = env->NewGlobalRef(oldValue);
              pkg->newActiveDescendentAccessibleContext = env->NewGlobalRef(newValue);
  
              ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyActiveDescendentChangeEvent);
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  done with propertyActiveChange event");
  }
  
  /**
   * firePropertyValueChange
   *
   */
  void
  JavaAccessBridge::firePropertyTableModelChange(JNIEnv *env, jobject callingObj, 
  			                       jobject event, jobject source,
                                                 jstring oldValue, jstring newValue){
  
      PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(%X, %X, %X, %X, %X, %X)", 
                       env, callingObj, event, 
                       source, oldValue, newValue);
  
      // sanity check
      if (ATs == (AccessBridgeATInstance *) 0) {
          PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
          return;		// panic!
      }
  
      // common setup
      const wchar_t *stringBytes;
      char buffer[sizeof(PackageType) + sizeof(PropertyTableModelChangePackage)];
      PackageType *type = (PackageType *) buffer;
      PropertyTableModelChangePackage *pkg = (PropertyTableModelChangePackage *) (buffer + sizeof(PackageType));
      *type = cPropertyTableModelChangePackage;
      pkg->vmID = (long) dialogWindow;
  
      // make new Global Refs and send events only to those ATs that want 'em
      AccessBridgeATInstance *ati = ATs;
      while (ati != (AccessBridgeATInstance *) 0) {
          if (ati->accessibilityEventMask & cPropertyTableModelChangeEvent) {
  
              PrintDebugString("  sending to AT");
  
              // make new GlobalRefs for this AT
              pkg->Event = env->NewGlobalRef(event);
              pkg->AccessibleContextSource = env->NewGlobalRef(source);
  
              if (oldValue != (jstring) 0) {
                  stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
                  wcsncpy(pkg->oldValue, stringBytes, (sizeof(pkg->oldValue) / sizeof(wchar_t)));
                  env->ReleaseStringChars(oldValue, stringBytes);
              } else {
                  wcsncpy(pkg->oldValue, L"(null)", (sizeof(pkg->oldValue) / sizeof(wchar_t)));
              }
  
              if (newValue != (jstring) 0) {
                  stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
                  wcsncpy(pkg->newValue, stringBytes, (sizeof(pkg->newValue) / sizeof(wchar_t)));
                  env->ReleaseStringChars(newValue, stringBytes);
              } else {
                  wcsncpy(pkg->newValue, L"(null)", (sizeof(pkg->newValue) / sizeof(wchar_t)));
              }
  
              ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTableModelChangeEvent);
          }
          ati = ati->nextATInstance;
      }
      PrintDebugString("  done with propertyTableModelChange event");
  }
  
  
  
  #define FIRE_EVENT(function, packageStruct, packageConstant, eventConstant)			        \
  	void JavaAccessBridge::function(JNIEnv *env, jobject callingObj,				\
  					jobject eventObj, jobject source) {	                        \
                                                                                                          \
  		PrintDebugString("\r\nFiring event id = %d(%X, %X, %X, %X); vmID = %X",		        \
  					  eventConstant, env, callingObj, eventObj, source, javaVM);	\
  													\
  			/* sanity check */								\
  		if (ATs == (AccessBridgeATInstance *) 0) {						\
  			PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");		\
  			return;		/* panic! */							\
  		}											\
  													\
  			/* common setup */								\
  		char buffer[sizeof(PackageType) + sizeof(packageStruct)];				\
  		PackageType *type = (PackageType *) buffer;						\
  		packageStruct *pkg = (packageStruct *) (buffer + sizeof(PackageType));		        \
  		*type = packageConstant;								\
  		pkg->vmID = (long) dialogWindow;							\
  													\
  			/* make new Global Refs, send events only to those ATs that want 'em */         \
  		AccessBridgeATInstance *ati = ATs;							\
  		while (ati != (AccessBridgeATInstance *) 0) {						\
  			if (ati->javaEventMask & eventConstant) {					\
                                                                                                          \
                                  PrintDebugString("  sending to AT");                                    \
  				/* make new GlobalRefs for this AT */					\
  				pkg->Event = env->NewGlobalRef(eventObj);				\
  				pkg->AccessibleContextSource = env->NewGlobalRef(source);		\
  													\
  				ati->sendJavaEventPackage(buffer, sizeof(buffer), eventConstant);	\
  			}										\
  			ati = ati->nextATInstance;							\
  		}											\
                  PrintDebugString("  done with firing AWT event");                                       \
  	}
  
      void JavaAccessBridge::javaShutdown(JNIEnv *env, jobject callingObj) {
      
          PrintDebugString("\r\nFiring event id = %d(%X, %X); vmID = %X",	
                           cJavaShutdownEvent, env, callingObj, javaVM);
          
          /* sanity check */
          if (ATs == (AccessBridgeATInstance *) 0) {
              PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
              return;		/* panic! */
          }
          
          /* common setup */
          char buffer[sizeof(PackageType) + sizeof(JavaShutdownPackage)];
          PackageType *type = (PackageType *) buffer;
          JavaShutdownPackage *pkg = (JavaShutdownPackage *) (buffer + sizeof(PackageType));
          *type = cJavaShutdownPackage;
          pkg->vmID = (long) dialogWindow;
          
          /* make new Global Refs, send events only to those ATs that want 'em */
          AccessBridgeATInstance *ati = ATs;
          while (ati != (AccessBridgeATInstance *) 0) {
              if (ati->javaEventMask & cJavaShutdownEvent) {
                  PrintDebugString("  sending to AT"); 
                  ati->sendJavaEventPackage(buffer, sizeof(buffer), cJavaShutdownEvent);
              }
              ati = ati->nextATInstance;
          }
          PrintDebugString("  done with firing AWT event"); 
      }
  
      FIRE_EVENT(fireFocusGained, FocusGainedPackage, cFocusGainedPackage, cFocusGainedEvent)
      FIRE_EVENT(fireFocusLost, FocusLostPackage, cFocusLostPackage, cFocusLostEvent)
      FIRE_EVENT(fireCaretUpdate, CaretUpdatePackage, cCaretUpdatePackage, cCaretUpdateEvent)
      FIRE_EVENT(fireMouseClicked, MouseClickedPackage, cMouseClickedPackage, cMouseClickedEvent)
      FIRE_EVENT(fireMouseEntered, MouseEnteredPackage, cMouseEnteredPackage, cMouseEnteredEvent)
      FIRE_EVENT(fireMouseExited, MouseExitedPackage, cMouseExitedPackage, cMouseExitedEvent)
      FIRE_EVENT(fireMousePressed, MousePressedPackage, cMousePressedPackage, cMousePressedEvent)
      FIRE_EVENT(fireMouseReleased, MouseReleasedPackage, cMouseReleasedPackage, cMouseReleasedEvent)
      FIRE_EVENT(fireMenuCanceled, MenuCanceledPackage, cMenuCanceledPackage, cMenuCanceledEvent)
      FIRE_EVENT(fireMenuDeselected, MenuDeselectedPackage, cMenuDeselectedPackage, cMenuDeselectedEvent)
      FIRE_EVENT(fireMenuSelected, MenuSelectedPackage, cMenuSelectedPackage, cMenuSelectedEvent)
      FIRE_EVENT(firePopupMenuCanceled, PopupMenuCanceledPackage, cPopupMenuCanceledPackage, cPopupMenuCanceledEvent)
      FIRE_EVENT(firePopupMenuWillBecomeInvisible, PopupMenuWillBecomeInvisiblePackage, cPopupMenuWillBecomeInvisiblePackage, cPopupMenuWillBecomeInvisibleEvent)
      FIRE_EVENT(firePopupMenuWillBecomeVisible, PopupMenuWillBecomeVisiblePackage, cPopupMenuWillBecomeVisiblePackage, cPopupMenuWillBecomeVisibleEvent)
  
  
      // -----------------------------
  
  
      extern "C" {	// event stuff from AccessBridge.h, generated by JNI
  
    	JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_sendDebugString(JNIEnv *env, jobject callingObj,
                                                                       jstring debugStr) {
  
  	    const wchar_t *stringBytes;
              stringBytes = (const wchar_t *) env->GetStringChars(debugStr, 0);
              wPrintJavaDebugString(L"AccessBridge.java: %ls", stringBytes);
              env->ReleaseStringChars(debugStr, stringBytes);
          }
  
  
  	/*
  	 * Returns whether JAWT.DLL is installed
  	 *
  	 * Class:     com_sun_java_accessibility_AccessBridge
  	 * Method:    isJAWTInstalled
  	 * Signature: ()I
  	 */
  	JNIEXPORT jint JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_isJAWTInstalled
          (JNIEnv *env, jobject callingObj) 
  	{
  
              // There is no way to get the JAWT version so
              // just verify that the DLL is loaded.
              HINSTANCE jawtInstance = LoadLibrary("JAWT.DLL");
              if (jawtInstance == 0) {
                  return 0;
              } else {
                  return 1;
              }
  	}
  
  
  	/**
  	 * Handle Java propertyChange event
  	 *
  	 */
          /*
            JNIEXPORT void JNICALL 
            Java_com_sun_java_accessibility_AccessBridge_propertyChange(JNIEnv *env, jobject callingObj, 
            jobject propertyChangeEvent, 
            jobject source, jstring propertyName,
            jstring oldValue, jstring newValue) {
            theJavaAccessBridge->firePropertyChange(env, callingObj,
            propertyChangeEvent,
            source, propertyName,
            oldValue, newValue);
            }
          */
  
  	JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_propertyCaretChange(JNIEnv *env, jobject callingObj,
                                                                           jobject event, jobject source, 
                                                                           jint oldValue, jint newValue) {
              theJavaAccessBridge->firePropertyCaretChange(env, callingObj,
                                                           event, source,
                                                           oldValue, newValue);
  	}
  
  	JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_propertyDescriptionChange(JNIEnv *env, jobject callingObj, 
                                                                                 jobject event, jobject source,
                                                                                 jstring oldValue, jstring newValue) {
              theJavaAccessBridge->firePropertyDescriptionChange(env, callingObj,
                                                                 event, source,
                                                                 oldValue, newValue);
  	}
  
          JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_propertyNameChange(JNIEnv *env, jobject callingObj, 
                                                                          jobject event, jobject source,
                                                                          jstring oldValue, jstring newValue) {
              theJavaAccessBridge->firePropertyNameChange(env, callingObj,
                                                          event, source,
                                                          oldValue, newValue);
  	}
  
          JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_propertySelectionChange(JNIEnv *env, jobject callingObj, 
                                                                               jobject event, jobject source) {
              theJavaAccessBridge->firePropertySelectionChange(env, callingObj,
                                                               event, source);
  	}
  
          JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_propertyStateChange(JNIEnv *env, jobject callingObj, 
                                                                           jobject event, jobject source,
                                                                           jstring oldValue, jstring newValue) {
              theJavaAccessBridge->firePropertyStateChange(env, callingObj,
                                                           event, source,
                                                           oldValue, newValue);
  	}
  
          JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_propertyTextChange(JNIEnv *env, jobject callingObj, 
                                                                          jobject event,  jobject source) {
              theJavaAccessBridge->firePropertyTextChange(env, callingObj,
                                                          event, source);
  	}
  
          JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_propertyValueChange(JNIEnv *env, jobject callingObj, 
                                                                           jobject event, jobject source,
                                                                           jstring oldValue, jstring newValue) {
              theJavaAccessBridge->firePropertyValueChange(env, callingObj,
                                                           event, source,
                                                           oldValue, newValue);
  	}
  
          JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChange(JNIEnv *env, jobject callingObj, 
                                                                                 jobject event,  jobject source) {
              theJavaAccessBridge->firePropertyVisibleDataChange(env, callingObj,
                                                                 event, source);
  	}
  
          JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_propertyChildChange(JNIEnv *env, jobject callingObj, 
                                                                           jobject event, jobject source,
                                                                           jobject oldValue, jobject newValue) {
              theJavaAccessBridge->firePropertyChildChange(env, callingObj,
                                                           event, source,
                                                           oldValue, newValue);
  	}
  
          JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentChange(JNIEnv *env, jobject callingObj, 
                                                                                      jobject event,  jobject source,
                                                                                      jobject oldValue,
                                                                                      jobject newValue) {
              theJavaAccessBridge->firePropertyActiveDescendentChange(env, callingObj,
                                                                      event, source,
                                                                      oldValue, newValue);
  	}
  
          JNIEXPORT void JNICALL 
  	Java_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(JNIEnv *env, jobject callingObj, 
                                                                                jobject event,  jobject source,
                                                                                jstring oldValue, jstring newValue) {
  											
              theJavaAccessBridge->firePropertyTableModelChange(env, callingObj,  
                                                                event, source,
                                                                oldValue, newValue);
  	}
  
  #define HANDLE_STANDARD_EVENT_FROM_JAVA(function, method)			\
  		JNIEXPORT void JNICALL						\
  		function(JNIEnv *env, jobject callingObj,			\
  				 jobject event, jobject source) {		\
  			theJavaAccessBridge->method(env, callingObj, event, source);	\
  		}
  
  
          JNIEXPORT void JNICALL
  	Java_com_sun_java_accessibility_AccessBridge_javaShutdown(JNIEnv *env, jobject callingObj) {
              theJavaAccessBridge->javaShutdown(env, callingObj);
  	}
  
  	HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_focusGained, fireFocusGained)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_focusLost, fireFocusLost)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_caretUpdate, fireCaretUpdate)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseClicked, fireMouseClicked)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseEntered, fireMouseEntered)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseExited, fireMouseExited)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mousePressed, fireMousePressed)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseReleased, fireMouseReleased)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuCanceled, fireMenuCanceled)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuDeselected, fireMenuDeselected)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuSelected, fireMenuSelected)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuCanceled, firePopupMenuCanceled)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuWillBecomeInvisible, firePopupMenuWillBecomeInvisible)
              HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuWillBecomeVisible, firePopupMenuWillBecomeVisible)
  
              }
  