/**
  * Finds the program that is associated with an extension. The extension may or may not begin with
  * a '.'. Note that a <code>Display</code> must already exist to guarantee that this method
  * returns an appropriate result.
  *
  * @param extension the program extension
  * @return the program or <code>null</code>
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_NULL_ARGUMENT when extension is null
  *     </ul>
  */
 public static Program findProgram(String extension) {
   NSAutoreleasePool pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
   try {
     if (extension == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
     if (extension.length() == 0) return null;
     Program program = null;
     char[] chars;
     if (extension.charAt(0) != '.') {
       chars = new char[extension.length()];
       extension.getChars(0, chars.length, chars, 0);
     } else {
       chars = new char[extension.length() - 1];
       extension.getChars(1, extension.length(), chars, 0);
     }
     NSString ext = NSString.stringWithCharacters(chars, chars.length);
     if (ext != null) {
       byte[] fsRef = new byte[80];
       if (OS.LSGetApplicationForInfo(
               OS.kLSUnknownType, OS.kLSUnknownCreator, ext.id, OS.kLSRolesAll, fsRef, null)
           == OS.noErr) {
         long /*int*/ url = OS.CFURLCreateFromFSRef(OS.kCFAllocatorDefault(), fsRef);
         if (url != 0) {
           NSString bundlePath = new NSURL(url).path();
           NSBundle bundle = NSBundle.bundleWithPath(bundlePath);
           if (bundle != null) program = getProgram(bundle);
           OS.CFRelease(url);
         }
       }
     }
     return program;
   } finally {
     pool.release();
   }
 }
Example #2
0
 /**
  * Sets the OpenGL context associated with this GLCanvas to be the current GL context.
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setCurrent() {
   checkWidget();
   if (GLX.glXGetCurrentContext() == context) return;
   int /*long*/ window = OS.GTK_WIDGET_WINDOW(handle);
   int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay(window);
   GLX.glXMakeCurrent(xDisplay, xWindow, context);
 }
 void onDispose(long /*int*/ embedHandle) {
   if (SubclassProc == null) return;
   long /*int*/ hwndChild = OS.GetWindow(browser.handle, OS.GW_CHILD);
   OS.SetWindowLongPtr(hwndChild, OS.GWL_WNDPROC, MozillaProc);
   childWindows = null;
   browser = null;
 }
  private int QueryContinueDrag(int fEscapePressed, int grfKeyState) {
    if (topControl != null && topControl.isDisposed()) return COM.DRAGDROP_S_CANCEL;
    if (fEscapePressed != 0) {
      if (hwndDrag != 0) OS.ImageList_DragLeave(hwndDrag);
      return COM.DRAGDROP_S_CANCEL;
    }
    /*
     * Bug in Windows.  On some machines that do not have XBUTTONs,
     * the MK_XBUTTON1 and OS.MK_XBUTTON2 bits are sometimes set,
     * causing mouse capture to become stuck.  The fix is to test
     * for the extra buttons only when they exist.
     */
    int mask = OS.MK_LBUTTON | OS.MK_MBUTTON | OS.MK_RBUTTON;
    //	if (display.xMouse) mask |= OS.MK_XBUTTON1 | OS.MK_XBUTTON2;
    if ((grfKeyState & mask) == 0) {
      if (hwndDrag != 0) OS.ImageList_DragLeave(hwndDrag);
      return COM.DRAGDROP_S_DROP;
    }

    if (hwndDrag != 0) {
      POINT pt = new POINT();
      OS.GetCursorPos(pt);
      RECT rect = new RECT();
      OS.GetWindowRect(hwndDrag, rect);
      OS.ImageList_DragMove(pt.x - rect.left, pt.y - rect.top);
    }
    return COM.S_OK;
  }
 void addWindowSubclass() {
   long /*int*/ hwndChild = OS.GetWindow(browser.handle, OS.GW_CHILD);
   if (SubclassProc == null) {
     SubclassProc = new Callback(MozillaDelegate.class, "windowProc", 4); // $NON-NLS-1$
     MozillaProc = OS.GetWindowLongPtr(hwndChild, OS.GWL_WNDPROC);
   }
   OS.SetWindowLongPtr(hwndChild, OS.GWL_WNDPROC, SubclassProc.getAddress());
 }
 /**
  * Answers all available programs in the operating system. Note that a <code>Display</code> must
  * already exist to guarantee that this method returns an appropriate result.
  *
  * @return an array of programs
  */
 public static Program[] getPrograms() {
   NSAutoreleasePool pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
   try {
     List<Program> vector = new ArrayList<>();
     NSWorkspace workspace = NSWorkspace.sharedWorkspace();
     NSArray array =
         new NSArray(
             OS.NSSearchPathForDirectoriesInDomains(
                 OS.NSAllApplicationsDirectory, OS.NSAllDomainsMask, true));
     int count = (int) /*64*/ array.count();
     for (int i = 0; i < count; i++) {
       NSString path = new NSString(array.objectAtIndex(i));
       NSFileManager fileManager = NSFileManager.defaultManager();
       NSDirectoryEnumerator enumerator = fileManager.enumeratorAtPath(path);
       if (enumerator != null) {
         id id;
         while ((id = enumerator.nextObject()) != null) {
           enumerator.skipDescendents();
           NSString fullPath = path.stringByAppendingPathComponent(new NSString(id.id));
           if (workspace.isFilePackageAtPath(fullPath)) {
             NSBundle bundle = NSBundle.bundleWithPath(fullPath);
             if (bundle != null) {
               Program program = getProgram(bundle);
               if (program != null) vector.add(program);
             }
           }
         }
       }
     }
     return vector.toArray(new Program[vector.size()]);
   } finally {
     pool.release();
   }
 }
  /*
   * EnumFormatEtc([in] dwDirection, [out] ppenumFormatetc)
   * Ownership of ppenumFormatetc transfers from callee to caller so reference count on ppenumFormatetc
   * must be incremented before returning.  Caller is responsible for releasing ppenumFormatetc.
   */
  private int EnumFormatEtc(int dwDirection, long /*int*/ ppenumFormatetc) {
    // only allow getting of data - SetData is not currently supported
    if (dwDirection == COM.DATADIR_SET) return COM.E_NOTIMPL;

    // what types have been registered?
    TransferData[] allowedDataTypes = new TransferData[0];
    for (int i = 0; i < transferAgents.length; i++) {
      Transfer transferAgent = transferAgents[i];
      if (transferAgent != null) {
        TransferData[] formats = transferAgent.getSupportedTypes();
        TransferData[] newAllowedDataTypes =
            new TransferData[allowedDataTypes.length + formats.length];
        System.arraycopy(allowedDataTypes, 0, newAllowedDataTypes, 0, allowedDataTypes.length);
        System.arraycopy(formats, 0, newAllowedDataTypes, allowedDataTypes.length, formats.length);
        allowedDataTypes = newAllowedDataTypes;
      }
    }

    OleEnumFORMATETC enumFORMATETC = new OleEnumFORMATETC();
    enumFORMATETC.AddRef();

    FORMATETC[] formats = new FORMATETC[allowedDataTypes.length];
    for (int i = 0; i < formats.length; i++) {
      formats[i] = allowedDataTypes[i].formatetc;
    }
    enumFORMATETC.setFormats(formats);

    OS.MoveMemory(ppenumFormatetc, new long /*int*/[] {enumFORMATETC.getAddress()}, OS.PTR_SIZEOF);
    return COM.S_OK;
  }
 static long /*int*/ windowProc(
     long /*int*/ hwnd, long /*int*/ msg, long /*int*/ wParam, long /*int*/ lParam) {
   switch ((int) /*64*/ msg) {
     case OS.WM_UPDATEUISTATE:
       /*
        * In XULRunner 17, calling the default windowProc for WM_UPDATEUISTATE message
        * terminates the program. Workaround is to prevent the call to default windowProc.
        */
       return 0;
     case OS.WM_ERASEBKGND:
       RECT rect = new RECT();
       OS.GetClientRect(hwnd, rect);
       OS.FillRect(wParam, rect, OS.GetSysColorBrush(OS.COLOR_WINDOW));
       break;
   }
   return OS.CallWindowProc(MozillaProc, hwnd, (int) /*64*/ msg, wParam, lParam);
 }
  /**
   * This implementation of <code>dragLeave</code> provides a default drag under effect for the
   * feedback specified in <code>event.feedback</code>.
   *
   * <p>For additional information see <code>DropTargetAdapter.dragLeave</code>.
   *
   * <p>Subclasses that override this method should call <code>super.dragLeave(event)</code> to get
   * the default drag under effect implementation.
   *
   * @param event the information associated with the drag leave event
   * @see DropTargetAdapter
   * @see DropTargetEvent
   */
  public void dragLeave(DropTargetEvent event) {
    Table table = (Table) control;
    long /*int*/ handle = table.handle;
    OS.gtk_tree_view_set_drag_dest_row(handle, 0, OS.GTK_TREE_VIEW_DROP_BEFORE);

    scrollBeginTime = 0;
    scrollIndex = -1;
  }
 static String getCacheParentPath() {
   /* Use the character encoding for the default locale */
   TCHAR buffer = new TCHAR(0, OS.MAX_PATH);
   if (OS.SHGetFolderPath(0, OS.CSIDL_LOCAL_APPDATA, 0, OS.SHGFP_TYPE_CURRENT, buffer)
       == OS.S_OK) {
     return buffer.toString(0, buffer.strlen()) + Mozilla.SEPARATOR_OS + "eclipse"; // $NON-NLS-1$
   }
   return getProfilePath();
 }
 private int SetData(long /*int*/ pFormatetc, long /*int*/ pmedium, int fRelease) {
   if (pFormatetc == 0 || pmedium == 0) return COM.E_INVALIDARG;
   FORMATETC formatetc = new FORMATETC();
   COM.MoveMemory(formatetc, pFormatetc, FORMATETC.sizeof);
   if (formatetc.cfFormat == CFSTR_PERFORMEDDROPEFFECT && formatetc.tymed == COM.TYMED_HGLOBAL) {
     STGMEDIUM stgmedium = new STGMEDIUM();
     COM.MoveMemory(stgmedium, pmedium, STGMEDIUM.sizeof);
     // TODO - this should be GlobalLock()
     long /*int*/[] ptrEffect = new long /*int*/[1];
     OS.MoveMemory(ptrEffect, stgmedium.unionField, OS.PTR_SIZEOF);
     int[] effect = new int[1];
     OS.MoveMemory(effect, ptrEffect[0], 4);
     dataEffect = osToOp(effect[0]);
   }
   if (fRelease == 1) {
     COM.ReleaseStgMedium(pmedium);
   }
   return COM.S_OK;
 }
Example #12
0
 /**
  * This implementation of <code>nativeToJava</code> converts a platform specific representation of
  * an image to java <code>ImageData</code>.
  *
  * @param transferData the platform specific representation of the data to be converted
  * @return a java <code>ImageData</code> of the image if the conversion was successful; otherwise
  *     null
  * @see Transfer#javaToNative
  */
 public Object nativeToJava(TransferData transferData) {
   ImageData imgData = null;
   if (transferData.length > 0) {
     long /*int*/ loader = OS.gdk_pixbuf_loader_new();
     try {
       OS.gdk_pixbuf_loader_write(loader, transferData.pValue, transferData.length, null);
       OS.gdk_pixbuf_loader_close(loader, null);
       long /*int*/ pixbuf = OS.gdk_pixbuf_loader_get_pixbuf(loader);
       if (pixbuf != 0) {
         Image img = Image.gtk_new_from_pixbuf(Display.getCurrent(), SWT.BITMAP, pixbuf);
         imgData = img.getImageData();
         img.dispose();
       }
     } finally {
       OS.g_object_unref(loader);
     }
   }
   return imgData;
 }
 static char[] mbcsToWcs(String codePage, byte[] buffer) {
   char[] chars = new char[buffer.length];
   int charCount =
       OS.MultiByteToWideChar(
           OS.CP_ACP, OS.MB_PRECOMPOSED, buffer, buffer.length, chars, chars.length);
   if (charCount == chars.length) return chars;
   char[] result = new char[charCount];
   System.arraycopy(chars, 0, result, 0, charCount);
   return result;
 }
  /* QueryInterface([in] riid, [out] ppvObject)
   * Ownership of ppvObject transfers from callee to caller so reference count on ppvObject
   * must be incremented before returning.  Caller is responsible for releasing ppvObject.
   */
  private int QueryInterface(long /*int*/ riid, long /*int*/ ppvObject) {
    if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG;
    GUID guid = new GUID();
    COM.MoveMemory(guid, riid, GUID.sizeof);

    if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIDropSource)) {
      OS.MoveMemory(ppvObject, new long /*int*/[] {iDropSource.getAddress()}, OS.PTR_SIZEOF);
      AddRef();
      return COM.S_OK;
    }

    if (COM.IsEqualGUID(guid, COM.IIDIDataObject)) {
      OS.MoveMemory(ppvObject, new long /*int*/[] {iDataObject.getAddress()}, OS.PTR_SIZEOF);
      AddRef();
      return COM.S_OK;
    }

    OS.MoveMemory(ppvObject, new long /*int*/[] {0}, OS.PTR_SIZEOF);
    return COM.E_NOINTERFACE;
  }
Example #15
0
 static NSURL getURL(String fileName) {
   NSString unescapedStr;
   String lowercaseName = fileName.toLowerCase();
   if (lowercaseName.startsWith(PREFIX_HTTP)
       || lowercaseName.startsWith(PREFIX_HTTPS)
       || lowercaseName.startsWith(PREFIX_FILE)) {
     unescapedStr = NSString.stringWith("%#"); // $NON-NLS-1$
   } else {
     unescapedStr = NSString.stringWith("%"); // $NON-NLS-1$
   }
   NSString fullPath = NSString.stringWith(fileName);
   if (NSFileManager.defaultManager().fileExistsAtPath(fullPath)) {
     fullPath = NSURL.fileURLWithPath(fullPath).absoluteString();
   }
   long /*int*/ ptr =
       OS.CFURLCreateStringByAddingPercentEscapes(
           0, fullPath.id, unescapedStr.id, 0, OS.kCFStringEncodingUTF8);
   NSString escapedString = new NSString(ptr);
   NSURL url = NSURL.URLWithString(escapedString);
   OS.CFRelease(ptr);
   return url;
 }
Example #16
0
 static boolean isExecutable(String fileName) {
   long /*int*/ ptr = OS.malloc(1);
   NSString path = NSString.stringWith(fileName);
   boolean result = false;
   NSFileManager manager = NSFileManager.defaultManager();
   if (manager.fileExistsAtPath(path, ptr)) {
     byte[] isDirectory = new byte[1];
     OS.memmove(isDirectory, ptr, 1);
     if (isDirectory[0] == 0 && manager.isExecutableFileAtPath(path)) {
       NSWorkspace ws = NSWorkspace.sharedWorkspace();
       NSString type = ws.typeOfFile(path, 0);
       result =
           type != null
               && (ws.type(type, NSString.stringWith("public.unix-executable"))
                   || //$NON-NLS-1$
                   OS.UTTypeEqual(
                       type.id, NSString.stringWith("public.shell-script").id)); // $NON-NLS-1$
     }
   }
   OS.free(ptr);
   return result;
 }
Example #17
0
  /**
   * This implementation of <code>javaToNative</code> converts an ImageData object represented by
   * java <code>ImageData</code> to a platform specific representation.
   *
   * @param object a java <code>ImageData</code> containing the ImageData to be converted
   * @param transferData an empty <code>TransferData</code> object that will be filled in on return
   *     with the platform specific format of the data
   * @see Transfer#nativeToJava
   */
  public void javaToNative(Object object, TransferData transferData) {
    if (!checkImage(object) || !isSupportedType(transferData)) {
      DND.error(DND.ERROR_INVALID_DATA);
    }
    if (OS.GTK_VERSION < OS.VERSION(2, 4, 0)) return;

    ImageData imgData = (ImageData) object;
    if (imgData == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
    Image image = new Image(Display.getCurrent(), imgData);
    long /*int*/ pixbuf = ImageList.createPixbuf(image);
    if (pixbuf != 0) {
      String typeStr = "";
      if (transferData.type == JPEG_ID) typeStr = "jpeg";
      else if (transferData.type == PNG_ID) typeStr = "png";
      else if (transferData.type == BMP_ID) typeStr = "bmp";
      else if (transferData.type == EPS_ID) typeStr = "eps";
      else if (transferData.type == PCX_ID) typeStr = "pcx";
      else if (transferData.type == PPM_ID) typeStr = "ppm";
      else if (transferData.type == RGB_ID) typeStr = "rgb";
      else if (transferData.type == TGA_ID) typeStr = "tga";
      else if (transferData.type == XBM_ID) typeStr = "xbm";
      else if (transferData.type == XPM_ID) typeStr = "xpm";
      else if (transferData.type == XV_ID) typeStr = "xv";
      byte[] type = Converter.wcsToMbcs(null, typeStr, true);
      long /*int*/[] buffer = new long /*int*/[1];
      long /*int*/[] len = new long /*int*/[1];
      if (type == null) return;
      OS.gdk_pixbuf_save_to_bufferv(pixbuf, buffer, len, type, null, null, null);
      OS.g_object_unref(pixbuf);
      transferData.pValue = buffer[0];
      transferData.length = (int) (len[0] + 3) / 4 * 4;
      transferData.result = 1;
      transferData.format = 32;
    }
    image.dispose();
  }
 static String getProfilePath() {
   String baseDir;
   /* Use the character encoding for the default locale */
   TCHAR buffer = new TCHAR(0, OS.MAX_PATH);
   if (OS.SHGetFolderPath(0, OS.CSIDL_APPDATA, 0, OS.SHGFP_TYPE_CURRENT, buffer) == OS.S_OK) {
     baseDir = buffer.toString(0, buffer.strlen());
   } else {
     baseDir = System.getProperty("user.home"); // $NON-NLS-1$
   }
   return baseDir
       + Mozilla.SEPARATOR_OS
       + "Mozilla"
       + Mozilla.SEPARATOR_OS
       + "eclipse"; //$NON-NLS-1$ //$NON-NLS-2$
 }
Example #19
0
 /**
  * Returns a GLData object describing the created context.
  *
  * @return GLData description of the OpenGL context attributes
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public GLData getGLData() {
   checkWidget();
   int /*long*/ window = OS.GTK_WIDGET_WINDOW(handle);
   int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay(window);
   GLData data = new GLData();
   int[] value = new int[1];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_DOUBLEBUFFER, value);
   data.doubleBuffer = value[0] != 0;
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_STEREO, value);
   data.stereo = value[0] != 0;
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_RED_SIZE, value);
   data.redSize = value[0];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_GREEN_SIZE, value);
   data.greenSize = value[0];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_BLUE_SIZE, value);
   data.blueSize = value[0];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_ALPHA_SIZE, value);
   data.alphaSize = value[0];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_DEPTH_SIZE, value);
   data.depthSize = value[0];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_STENCIL_SIZE, value);
   data.stencilSize = value[0];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_ACCUM_RED_SIZE, value);
   data.accumRedSize = value[0];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_ACCUM_GREEN_SIZE, value);
   data.accumGreenSize = value[0];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_ACCUM_BLUE_SIZE, value);
   data.accumBlueSize = value[0];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_ACCUM_ALPHA_SIZE, value);
   data.accumAlphaSize = value[0];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_SAMPLE_BUFFERS, value);
   data.sampleBuffers = value[0];
   GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_SAMPLES, value);
   data.samples = value[0];
   return data;
 }
 public void show(int effect, int x, int y) {
   effect = checkEffect(effect);
   int handle = table.handle;
   Point coordinates = new Point(x, y);
   coordinates = table.toControl(coordinates);
   LVHITTESTINFO pinfo = new LVHITTESTINFO();
   pinfo.x = coordinates.x;
   pinfo.y = coordinates.y;
   OS.SendMessage(handle, OS.LVM_HITTEST, 0, pinfo);
   if ((effect & DND.FEEDBACK_SCROLL) == 0) {
     scrollBeginTime = 0;
     scrollIndex = -1;
   } else {
     if (pinfo.iItem != -1 && scrollIndex == pinfo.iItem && scrollBeginTime != 0) {
       if (System.currentTimeMillis() >= scrollBeginTime) {
         int top = Math.max(0, OS.SendMessage(handle, OS.LVM_GETTOPINDEX, 0, 0));
         int count = OS.SendMessage(handle, OS.LVM_GETITEMCOUNT, 0, 0);
         int index =
             (scrollIndex - 1 < top)
                 ? Math.max(0, scrollIndex - 1)
                 : Math.min(count - 1, scrollIndex + 1);
         OS.SendMessage(handle, OS.LVM_ENSUREVISIBLE, index, 0);
         scrollBeginTime = 0;
         scrollIndex = -1;
       }
     } else {
       scrollBeginTime = System.currentTimeMillis() + SCROLL_HYSTERESIS;
       scrollIndex = pinfo.iItem;
     }
   }
   LVITEM lvItem = new LVITEM();
   lvItem.stateMask = OS.LVIS_DROPHILITED;
   OS.SendMessage(handle, OS.LVM_SETITEMSTATE, -1, lvItem);
   if (pinfo.iItem != -1 && (effect & DND.FEEDBACK_SELECT) != 0) {
     lvItem.state = OS.LVIS_DROPHILITED;
     OS.SendMessage(handle, OS.LVM_SETITEMSTATE, pinfo.iItem, lvItem);
   }
   // Insert mark only supported on Windows XP with manifest
   //	if (OS.COMCTL32_MAJOR >= 6) {
   //		if ((effect & DND.FEEDBACK_INSERT_BEFORE) != 0 || (effect & DND.FEEDBACK_INSERT_AFTER) != 0)
   // {
   //			LVINSERTMARK lvinsertmark = new LVINSERTMARK();
   //			lvinsertmark.cbSize = LVINSERTMARK.sizeof;
   //			lvinsertmark.dwFlags = (effect & DND.FEEDBACK_INSERT_BEFORE) != 0 ? 0 : OS.LVIM_AFTER;
   //			lvinsertmark.iItem = pinfo.iItem == -1 ? 0 : pinfo.iItem;
   //			int hItem = pinfo.iItem;
   //			OS.SendMessage (handle, OS.LVM_SETINSERTMARK, 0, lvinsertmark);
   //		} else {
   //			OS.SendMessage (handle, OS.LVM_SETINSERTMARK, 0, 0);
   //		}
   //	}
   return;
 }
 static byte[] wcsToMbcs(String codePage, String string, boolean terminate) {
   int byteCount;
   char[] chars = new char[string.length()];
   string.getChars(0, chars.length, chars, 0);
   byte[] bytes = new byte[byteCount = chars.length * 2 + (terminate ? 1 : 0)];
   byteCount =
       OS.WideCharToMultiByte(OS.CP_ACP, 0, chars, chars.length, bytes, byteCount, null, null);
   if (terminate) {
     byteCount++;
   } else {
     if (bytes.length != byteCount) {
       byte[] result = new byte[byteCount];
       System.arraycopy(bytes, 0, result, 0, byteCount);
       bytes = result;
     }
   }
   return bytes;
 }
  static Variant writeSafeArray(String string) {
    // Create a one dimensional safearray containing two VT_UI1 values
    // where VT_UI1 is an unsigned char

    // Define cDims, fFeatures and cbElements
    short cDims = 1;
    short FADF_FIXEDSIZE = 0x10;
    short FADF_HAVEVARTYPE = 0x80;
    short fFeatures = (short) (FADF_FIXEDSIZE | FADF_HAVEVARTYPE);
    int cbElements = 1;
    // Create a pointer and copy the data into it
    int count = string.length();
    char[] chars = new char[count + 1];
    string.getChars(0, count, chars, 0);
    int cchMultiByte = OS.WideCharToMultiByte(CodePage, 0, chars, -1, null, 0, null, null);
    if (cchMultiByte == 0) return null;
    long /*int*/ pvData = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, cchMultiByte);
    OS.WideCharToMultiByte(CodePage, 0, chars, -1, pvData, cchMultiByte, null, null);
    int cElements1 = cchMultiByte;
    int lLbound1 = 0;
    // Create a safearray in memory
    long /*int*/ pSafeArray = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, SAFEARRAY.sizeof);
    SAFEARRAY safeArray = new SAFEARRAY();
    safeArray.cDims = cDims;
    safeArray.fFeatures = fFeatures;
    safeArray.cbElements = cbElements;
    safeArray.pvData = pvData;
    SAFEARRAYBOUND safeArrayBound = new SAFEARRAYBOUND();
    safeArray.rgsabound = safeArrayBound;
    safeArrayBound.cElements = cElements1;
    safeArrayBound.lLbound = lLbound1;
    OS.MoveMemory(pSafeArray, safeArray, SAFEARRAY.sizeof);
    // Create a variant in memory to hold the safearray
    long /*int*/ pVariant = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, Variant.sizeof);
    short vt = (short) (OLE.VT_ARRAY | OLE.VT_UI1);
    OS.MoveMemory(pVariant, new short[] {vt}, 2);
    OS.MoveMemory(pVariant + 8, new long /*int*/[] {pSafeArray}, OS.PTR_SIZEOF);
    // Create a by ref variant
    Variant variantByRef = new Variant(pVariant, (short) (OLE.VT_BYREF | OLE.VT_VARIANT));
    return variantByRef;
  }
  private int GetData(long /*int*/ pFormatetc, long /*int*/ pmedium) {
    /* Called by a data consumer to obtain data from a source data object.
       The GetData method renders the data described in the specified FORMATETC
       structure and transfers it through the specified STGMEDIUM structure.
       The caller then assumes responsibility for releasing the STGMEDIUM structure.
    */
    if (pFormatetc == 0 || pmedium == 0) return COM.E_INVALIDARG;

    if (QueryGetData(pFormatetc) != COM.S_OK) return COM.DV_E_FORMATETC;

    TransferData transferData = new TransferData();
    transferData.formatetc = new FORMATETC();
    COM.MoveMemory(transferData.formatetc, pFormatetc, FORMATETC.sizeof);
    transferData.type = transferData.formatetc.cfFormat;
    transferData.stgmedium = new STGMEDIUM();
    transferData.result = COM.E_FAIL;

    DNDEvent event = new DNDEvent();
    event.widget = this;
    event.time = OS.GetMessageTime();
    event.dataType = transferData;
    notifyListeners(DND.DragSetData, event);

    if (!event.doit) return COM.E_FAIL;

    // get matching transfer agent to perform conversion
    Transfer transfer = null;
    for (int i = 0; i < transferAgents.length; i++) {
      Transfer transferAgent = transferAgents[i];
      if (transferAgent != null && transferAgent.isSupportedType(transferData)) {
        transfer = transferAgent;
        break;
      }
    }

    if (transfer == null) return COM.DV_E_FORMATETC;
    transfer.javaToNative(event.data, transferData);
    if (transferData.result != COM.S_OK) return transferData.result;
    COM.MoveMemory(pmedium, transferData.stgmedium, STGMEDIUM.sizeof);
    return transferData.result;
  }
 static String readSafeArray(Variant variantByRef) {
   // Read a safearray that contains data of
   // type VT_UI1 (unsigned shorts) which contains
   // a text stream.
   long /*int*/ pPostData = variantByRef.getByRef();
   short[] vt_type = new short[1];
   OS.MoveMemory(vt_type, pPostData, 2);
   String result = null;
   if (vt_type[0] == (short) (OLE.VT_BYREF | OLE.VT_VARIANT)) {
     int[] pVariant = new int[1];
     OS.MoveMemory(pVariant, pPostData + 8, 4);
     vt_type = new short[1];
     OS.MoveMemory(vt_type, pVariant[0], 2);
     if (vt_type[0] == (short) (OLE.VT_ARRAY | OLE.VT_UI1)) {
       long /*int*/[] pSafearray = new long /*int*/[1];
       OS.MoveMemory(pSafearray, pVariant[0] + 8, OS.PTR_SIZEOF);
       SAFEARRAY safeArray = new SAFEARRAY();
       OS.MoveMemory(safeArray, pSafearray[0], SAFEARRAY.sizeof);
       for (int i = 0; i < safeArray.cDims; i++) {
         int cchWideChar =
             OS.MultiByteToWideChar(CodePage, OS.MB_PRECOMPOSED, safeArray.pvData, -1, null, 0);
         if (cchWideChar == 0) return null;
         char[] lpWideCharStr = new char[cchWideChar - 1];
         OS.MultiByteToWideChar(
             CodePage,
             OS.MB_PRECOMPOSED,
             safeArray.pvData,
             -1,
             lpWideCharStr,
             lpWideCharStr.length);
         result = new String(lpWideCharStr);
       }
     }
   }
   return result;
 }
  Image getDragSourceImage(DragSourceEvent event) {
    if (dragSourceImage != null) dragSourceImage.dispose();
    dragSourceImage = null;

    Table table = (Table) control;
    if (OS.GTK_VERSION < OS.VERSION(2, 2, 0)) return null;
    // TEMPORARY CODE
    if (table.isListening(SWT.EraseItem) || table.isListening(SWT.PaintItem)) return null;
    /*
     * Bug in GTK.  gtk_tree_selection_get_selected_rows() segmentation faults
     * in versions smaller than 2.2.4 if the model is NULL.  The fix is
     * to give a valid pointer instead.
     */
    long /*int*/ handle = table.handle;
    long /*int*/ selection = OS.gtk_tree_view_get_selection(handle);
    long /*int*/[] model = OS.GTK_VERSION < OS.VERSION(2, 2, 4) ? new long /*int*/[1] : null;
    long /*int*/ list = OS.gtk_tree_selection_get_selected_rows(selection, model);
    if (list == 0) return null;
    int count = Math.min(10, OS.g_list_length(list));

    Display display = table.getDisplay();
    if (count == 1) {
      long /*int*/ path = OS.g_list_nth_data(list, 0);
      long /*int*/ pixmap = OS.gtk_tree_view_create_row_drag_icon(handle, path);
      dragSourceImage = Image.gtk_new(display, SWT.ICON, pixmap, 0);
    } else {
      int width = 0, height = 0;
      int[] w = new int[1], h = new int[1];
      int[] yy = new int[count], hh = new int[count];
      long /*int*/[] pixmaps = new long /*int*/[count];
      GdkRectangle rect = new GdkRectangle();
      for (int i = 0; i < count; i++) {
        long /*int*/ path = OS.g_list_nth_data(list, i);
        OS.gtk_tree_view_get_cell_area(handle, path, 0, rect);
        pixmaps[i] = OS.gtk_tree_view_create_row_drag_icon(handle, path);
        OS.gdk_drawable_get_size(pixmaps[i], w, h);
        width = Math.max(width, w[0]);
        height = rect.y + h[0] - yy[0];
        yy[i] = rect.y;
        hh[i] = h[0];
      }
      long /*int*/ source = OS.gdk_pixmap_new(OS.GDK_ROOT_PARENT(), width, height, -1);
      long /*int*/ gcSource = OS.gdk_gc_new(source);
      long /*int*/ mask = OS.gdk_pixmap_new(OS.GDK_ROOT_PARENT(), width, height, 1);
      long /*int*/ gcMask = OS.gdk_gc_new(mask);
      GdkColor color = new GdkColor();
      color.pixel = 0;
      OS.gdk_gc_set_foreground(gcMask, color);
      OS.gdk_draw_rectangle(mask, gcMask, 1, 0, 0, width, height);
      color.pixel = 1;
      OS.gdk_gc_set_foreground(gcMask, color);
      for (int i = 0; i < count; i++) {
        OS.gdk_draw_drawable(source, gcSource, pixmaps[i], 0, 0, 0, yy[i] - yy[0], -1, -1);
        OS.gdk_draw_rectangle(mask, gcMask, 1, 0, yy[i] - yy[0], width, hh[i]);
        OS.g_object_unref(pixmaps[i]);
      }
      OS.g_object_unref(gcSource);
      OS.g_object_unref(gcMask);
      dragSourceImage = Image.gtk_new(display, SWT.ICON, source, mask);
    }
    OS.g_list_free(list);

    return dragSourceImage;
  }
 /**
  * This implementation of <code>dragOver</code> provides a default drag under effect for the
  * feedback specified in <code>event.feedback</code>. The class description lists the FEEDBACK
  * constants that are applicable to the class.
  *
  * <p>For additional information see <code>DropTargetAdapter.dragOver</code>.
  *
  * <p>Subclasses that override this method should call <code>super.dragOver(event)</code> to get
  * the default drag under effect implementation.
  *
  * @param event the information associated with the drag over event
  * @see DropTargetAdapter
  * @see DropTargetEvent
  * @see DND#FEEDBACK_SELECT
  * @see DND#FEEDBACK_SCROLL
  */
 public void dragOver(DropTargetEvent event) {
   Table table = (Table) control;
   long /*int*/ handle = table.handle;
   int effect = checkEffect(event.feedback);
   Point coordinates = new Point(event.x, event.y);
   coordinates = table.toControl(coordinates);
   long /*int*/[] path = new long /*int*/[1];
   OS.gtk_tree_view_get_path_at_pos(handle, coordinates.x, coordinates.y, path, null, null, null);
   int index = -1;
   if (path[0] != 0) {
     long /*int*/ indices = OS.gtk_tree_path_get_indices(path[0]);
     if (indices != 0) {
       int[] temp = new int[1];
       OS.memmove(temp, indices, 4);
       index = temp[0];
     }
   }
   if ((effect & DND.FEEDBACK_SCROLL) == 0) {
     scrollBeginTime = 0;
     scrollIndex = -1;
   } else {
     if (index != -1 && scrollIndex == index && scrollBeginTime != 0) {
       if (System.currentTimeMillis() >= scrollBeginTime) {
         if (coordinates.y < table.getItemHeight()) {
           OS.gtk_tree_path_prev(path[0]);
         } else {
           OS.gtk_tree_path_next(path[0]);
         }
         if (path[0] != 0) {
           OS.gtk_tree_view_scroll_to_cell(handle, path[0], 0, false, 0, 0);
           OS.gtk_tree_path_free(path[0]);
           path[0] = 0;
           OS.gtk_tree_view_get_path_at_pos(
               handle, coordinates.x, coordinates.y, path, null, null, null);
         }
         scrollBeginTime = 0;
         scrollIndex = -1;
       }
     } else {
       scrollBeginTime = System.currentTimeMillis() + SCROLL_HYSTERESIS;
       scrollIndex = index;
     }
   }
   if (path[0] != 0) {
     int position = 0;
     if ((effect & DND.FEEDBACK_SELECT) != 0) position = OS.GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
     // if ((effect & DND.FEEDBACK_INSERT_BEFORE) != 0) position = OS.GTK_TREE_VIEW_DROP_BEFORE;
     // if ((effect & DND.FEEDBACK_INSERT_AFTER) != 0) position = OS.GTK_TREE_VIEW_DROP_AFTER;
     if (position != 0) {
       OS.gtk_tree_view_set_drag_dest_row(handle, path[0], OS.GTK_TREE_VIEW_DROP_INTO_OR_BEFORE);
     } else {
       OS.gtk_tree_view_set_drag_dest_row(handle, 0, OS.GTK_TREE_VIEW_DROP_BEFORE);
     }
   } else {
     OS.gtk_tree_view_set_drag_dest_row(handle, 0, OS.GTK_TREE_VIEW_DROP_BEFORE);
   }
   if (path[0] != 0) OS.gtk_tree_path_free(path[0]);
 }
 void removeWindowSubclass() {
   long /*int*/ hwndChild = OS.GetWindow(browser.handle, OS.GW_CHILD);
   if (SubclassProc != null) {
     OS.SetWindowLongPtr(hwndChild, OS.GWL_WNDPROC, MozillaProc);
   }
 }
  private void drag(Event dragEvent) {
    DNDEvent event = new DNDEvent();
    event.widget = this;
    event.x = dragEvent.x;
    event.y = dragEvent.y;
    event.time = OS.GetMessageTime();
    event.doit = true;
    notifyListeners(DND.DragStart, event);
    if (!event.doit || transferAgents == null || transferAgents.length == 0) return;

    int[] pdwEffect = new int[1];
    int operations = opToOs(getStyle());
    Display display = control.getDisplay();
    String key = "org.eclipse.swt.internal.win32.runMessagesInIdle"; // $NON-NLS-1$
    Object oldValue = display.getData(key);
    display.setData(key, Boolean.TRUE);
    ImageList imagelist = null;
    Image image = event.image;
    hwndDrag = 0;
    topControl = null;
    if (image != null) {
      imagelist = new ImageList(SWT.NONE);
      imagelist.add(image);
      topControl = control.getShell();
      /*
       * Bug in Windows. The image is inverted if the shell is RIGHT_TO_LEFT.
       * The fix is to create a transparent window that covers the shell client
       * area and use it during the drag to prevent the image from being inverted.
       * On XP if the shell is RTL, the image is not displayed.
       */
      int offsetX = event.offsetX;
      hwndDrag = topControl.handle;
      if ((topControl.getStyle() & SWT.RIGHT_TO_LEFT) != 0) {
        offsetX = image.getBounds().width - offsetX;
        RECT rect = new RECT();
        OS.GetClientRect(topControl.handle, rect);
        hwndDrag =
            OS.CreateWindowEx(
                OS.WS_EX_TRANSPARENT | OS.WS_EX_NOINHERITLAYOUT,
                WindowClass,
                null,
                OS.WS_CHILD | OS.WS_CLIPSIBLINGS,
                0,
                0,
                rect.right - rect.left,
                rect.bottom - rect.top,
                topControl.handle,
                0,
                OS.GetModuleHandle(null),
                null);
        OS.ShowWindow(hwndDrag, OS.SW_SHOW);
      }
      OS.ImageList_BeginDrag(imagelist.getHandle(), 0, offsetX, event.offsetY);
      /*
       * Feature in Windows. When ImageList_DragEnter() is called,
       * it takes a snapshot of the screen  If a drag is started
       * when another window is in front, then the snapshot will
       * contain part of the other window, causing pixel corruption.
       * The fix is to force all paints to be delivered before
       * calling ImageList_DragEnter().
       */
      if (OS.IsWinCE) {
        OS.UpdateWindow(topControl.handle);
      } else {
        int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN;
        OS.RedrawWindow(topControl.handle, null, 0, flags);
      }
      POINT pt = new POINT();
      pt.x = dragEvent.x;
      pt.y = dragEvent.y;
      OS.MapWindowPoints(control.handle, 0, pt, 1);
      RECT rect = new RECT();
      OS.GetWindowRect(hwndDrag, rect);
      OS.ImageList_DragEnter(hwndDrag, pt.x - rect.left, pt.y - rect.top);
    }
    int result = COM.DRAGDROP_S_CANCEL;
    try {
      result =
          COM.DoDragDrop(iDataObject.getAddress(), iDropSource.getAddress(), operations, pdwEffect);
    } finally {
      // ensure that we don't leave transparent window around
      if (hwndDrag != 0) {
        OS.ImageList_DragLeave(hwndDrag);
        OS.ImageList_EndDrag();
        imagelist.dispose();
        if (hwndDrag != topControl.handle) OS.DestroyWindow(hwndDrag);
        hwndDrag = 0;
        topControl = null;
      }
      display.setData(key, oldValue);
    }
    int operation = osToOp(pdwEffect[0]);
    if (dataEffect == DND.DROP_MOVE) {
      operation =
          (operation == DND.DROP_NONE || operation == DND.DROP_COPY)
              ? DND.DROP_TARGET_MOVE
              : DND.DROP_MOVE;
    } else {
      if (dataEffect != DND.DROP_NONE) {
        operation = dataEffect;
      }
    }
    event = new DNDEvent();
    event.widget = this;
    event.time = OS.GetMessageTime();
    event.doit = (result == COM.DRAGDROP_S_DROP);
    event.detail = operation;
    notifyListeners(DND.DragEnd, event);
    dataEffect = DND.DROP_NONE;
  }
Example #29
0
  /**
   * Create a GLCanvas widget using the attributes described in the GLData object provided.
   *
   * @param parent a composite widget
   * @param style the bitwise OR'ing of widget styles
   * @param data the requested attributes of the GLCanvas
   * @exception IllegalArgumentException
   *     <ul>
   *       <li>ERROR_NULL_ARGUMENT when the data is null
   *       <li>ERROR_UNSUPPORTED_DEPTH when the requested attributes cannot be provided
   *     </ul>
   *     </ul>
   */
  public GLCanvas(Composite parent, int style, GLData data) {
    super(parent, style);
    if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
    int glxAttrib[] = new int[MAX_ATTRIBUTES];
    int pos = 0;
    glxAttrib[pos++] = GLX.GLX_RGBA;
    if (data.doubleBuffer) glxAttrib[pos++] = GLX.GLX_DOUBLEBUFFER;
    if (data.stereo) glxAttrib[pos++] = GLX.GLX_STEREO;
    if (data.redSize > 0) {
      glxAttrib[pos++] = GLX.GLX_RED_SIZE;
      glxAttrib[pos++] = data.redSize;
    }
    if (data.greenSize > 0) {
      glxAttrib[pos++] = GLX.GLX_GREEN_SIZE;
      glxAttrib[pos++] = data.greenSize;
    }
    if (data.blueSize > 0) {
      glxAttrib[pos++] = GLX.GLX_BLUE_SIZE;
      glxAttrib[pos++] = data.blueSize;
    }
    if (data.alphaSize > 0) {
      glxAttrib[pos++] = GLX.GLX_ALPHA_SIZE;
      glxAttrib[pos++] = data.alphaSize;
    }
    if (data.depthSize > 0) {
      glxAttrib[pos++] = GLX.GLX_DEPTH_SIZE;
      glxAttrib[pos++] = data.depthSize;
    }
    if (data.stencilSize > 0) {
      glxAttrib[pos++] = GLX.GLX_STENCIL_SIZE;
      glxAttrib[pos++] = data.stencilSize;
    }
    if (data.accumRedSize > 0) {
      glxAttrib[pos++] = GLX.GLX_ACCUM_RED_SIZE;
      glxAttrib[pos++] = data.accumRedSize;
    }
    if (data.accumGreenSize > 0) {
      glxAttrib[pos++] = GLX.GLX_ACCUM_GREEN_SIZE;
      glxAttrib[pos++] = data.accumGreenSize;
    }
    if (data.accumBlueSize > 0) {
      glxAttrib[pos++] = GLX.GLX_ACCUM_BLUE_SIZE;
      glxAttrib[pos++] = data.accumBlueSize;
    }
    if (data.accumAlphaSize > 0) {
      glxAttrib[pos++] = GLX.GLX_ACCUM_ALPHA_SIZE;
      glxAttrib[pos++] = data.accumAlphaSize;
    }
    if (data.sampleBuffers > 0) {
      glxAttrib[pos++] = GLX.GLX_SAMPLE_BUFFERS;
      glxAttrib[pos++] = data.sampleBuffers;
    }
    if (data.samples > 0) {
      glxAttrib[pos++] = GLX.GLX_SAMPLES;
      glxAttrib[pos++] = data.samples;
    }
    glxAttrib[pos++] = 0;
    OS.gtk_widget_realize(handle);
    int /*long*/ window = OS.GTK_WIDGET_WINDOW(handle);
    int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay(window);
    int /*long*/ infoPtr = GLX.glXChooseVisual(xDisplay, OS.XDefaultScreen(xDisplay), glxAttrib);
    if (infoPtr == 0) {
      dispose();
      SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
    }
    vinfo = new XVisualInfo();
    GLX.memmove(vinfo, infoPtr, XVisualInfo.sizeof);
    OS.XFree(infoPtr);
    int /*long*/ screen = OS.gdk_screen_get_default();
    int /*long*/ gdkvisual = OS.gdk_x11_screen_lookup_visual(screen, vinfo.visualid);
    // FIXME- share lists
    // context = GLX.glXCreateContext (xDisplay, info, share == null ? 0 : share.context, true);
    context = GLX.glXCreateContext(xDisplay, vinfo, 0, true);
    if (context == 0) SWT.error(SWT.ERROR_NO_HANDLES);
    GdkWindowAttr attrs = new GdkWindowAttr();
    attrs.width = 1;
    attrs.height = 1;
    attrs.event_mask =
        OS.GDK_KEY_PRESS_MASK
            | OS.GDK_KEY_RELEASE_MASK
            | OS.GDK_FOCUS_CHANGE_MASK
            | OS.GDK_POINTER_MOTION_MASK
            | OS.GDK_BUTTON_PRESS_MASK
            | OS.GDK_BUTTON_RELEASE_MASK
            | OS.GDK_ENTER_NOTIFY_MASK
            | OS.GDK_LEAVE_NOTIFY_MASK
            | OS.GDK_EXPOSURE_MASK
            | OS.GDK_VISIBILITY_NOTIFY_MASK
            | OS.GDK_POINTER_MOTION_HINT_MASK;
    attrs.window_type = OS.GDK_WINDOW_CHILD;
    attrs.visual = gdkvisual;
    glWindow = OS.gdk_window_new(window, attrs, OS.GDK_WA_VISUAL);
    OS.gdk_window_set_user_data(glWindow, handle);
    if ((style & SWT.NO_BACKGROUND) != 0) OS.gdk_window_set_back_pixmap(window, 0, false);
    xWindow = OS.gdk_x11_drawable_get_xid(glWindow);
    OS.gdk_window_show(glWindow);

    Listener listener =
        new Listener() {
          public void handleEvent(Event event) {
            switch (event.type) {
              case SWT.Paint:
                /**
                 * Bug in MESA. MESA does some nasty sort of polling to try and ensure that their
                 * buffer sizes match the current X state. This state can be updated using
                 * glViewport(). FIXME: There has to be a better way of doing this.
                 */
                int[] viewport = new int[4];
                GLX.glGetIntegerv(GLX.GL_VIEWPORT, viewport);
                GLX.glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
                break;
              case SWT.Resize:
                Rectangle clientArea = getClientArea();
                OS.gdk_window_move(glWindow, clientArea.x, clientArea.y);
                OS.gdk_window_resize(glWindow, clientArea.width, clientArea.height);
                break;
              case SWT.Dispose:
                int /*long*/ window = OS.GTK_WIDGET_WINDOW(handle);
                int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay(window);
                if (context != 0) {
                  if (GLX.glXGetCurrentContext() == context) {
                    GLX.glXMakeCurrent(xDisplay, 0, 0);
                  }
                  GLX.glXDestroyContext(xDisplay, context);
                  context = 0;
                }
                if (glWindow != 0) {
                  OS.gdk_window_destroy(glWindow);
                  glWindow = 0;
                }
                break;
            }
          }
        };
    addListener(SWT.Resize, listener);
    addListener(SWT.Paint, listener);
    addListener(SWT.Dispose, listener);
  }
public class Snippet186 {

  static int CodePage = OS.GetACP();

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setLayout(new GridLayout(2, false));

    final Text text = new Text(shell, SWT.BORDER);
    text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
    Button go = new Button(shell, SWT.PUSH);
    go.setText("Go");
    OleFrame oleFrame = new OleFrame(shell, SWT.NONE);
    oleFrame.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
    OleControlSite controlSite;
    OleAutomation automation;
    try {
      controlSite = new OleControlSite(oleFrame, SWT.NONE, "Shell.Explorer");
      automation = new OleAutomation(controlSite);
      controlSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
    } catch (SWTException ex) {
      System.out.println("Unable to open activeX control");
      display.dispose();
      return;
    }

    final OleAutomation auto = automation;
    go.addListener(
        SWT.Selection,
        new Listener() {
          public void handleEvent(Event e) {
            String url = text.getText();
            int[] rgdispid = auto.getIDsOfNames(new String[] {"Navigate", "URL"});
            int dispIdMember = rgdispid[0];
            Variant[] rgvarg = new Variant[1];
            rgvarg[0] = new Variant(url);
            int[] rgdispidNamedArgs = new int[1];
            rgdispidNamedArgs[0] = rgdispid[1];
            auto.invoke(dispIdMember, rgvarg, rgdispidNamedArgs);
          }
        });

    // Read PostData whenever we navigate to a site that uses it
    int BeforeNavigate2 = 0xfa;
    controlSite.addEventListener(
        BeforeNavigate2,
        new OleListener() {
          public void handleEvent(OleEvent event) {
            Variant url = event.arguments[1];
            Variant postData = event.arguments[4];
            if (postData != null) {
              System.out.println(
                  "PostData = " + readSafeArray(postData) + ", URL = " + url.getString());
            }
          }
        });

    // Navigate to this web site which uses post data to fill in the text field
    // and put the string "hello world" into the text box
    text.setText("file://" + Snippet186.class.getResource("Snippet186.html").getFile());
    int[] rgdispid = automation.getIDsOfNames(new String[] {"Navigate", "URL", "PostData"});
    int dispIdMember = rgdispid[0];
    Variant[] rgvarg = new Variant[2];
    rgvarg[0] = new Variant(text.getText());
    rgvarg[1] = writeSafeArray("hello world");
    int[] rgdispidNamedArgs = new int[2];
    rgdispidNamedArgs[0] = rgdispid[1];
    rgdispidNamedArgs[1] = rgdispid[2];
    automation.invoke(dispIdMember, rgvarg, rgdispidNamedArgs);

    shell.open();
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch()) display.sleep();
    }
    display.dispose();
  }

  // The following structs are accessed in the readSafeArray and writeSafeArray
  // functions:
  //
  // VARIANT:
  // 		short vt
  // 		short wReserved1
  // 		short wReserved2
  // 		short wReserved3
  // 		int parray
  //
  // SAFEARRAY:
  //      short cDims      // Count of dimensions in this array
  //      short fFeatures  // Flags used by the SafeArray
  //      int cbElements   // Size of an element of the array
  //      int cLocks       // Number of times the array has been locked without corresponding unlock
  //      int pvData       // Pointer to the data
  //      SAFEARRAYBOUND[] rgsabound // One bound for each dimension
  //
  // SAFEARRAYBOUND:
  //      int cElements    // the number of elements in the dimension
  //      int lLbound      // the lower bound of the dimension

  static String readSafeArray(Variant variantByRef) {
    // Read a safearray that contains data of
    // type VT_UI1 (unsigned shorts) which contains
    // a text stream.
    long /*int*/ pPostData = variantByRef.getByRef();
    short[] vt_type = new short[1];
    OS.MoveMemory(vt_type, pPostData, 2);
    String result = null;
    if (vt_type[0] == (short) (OLE.VT_BYREF | OLE.VT_VARIANT)) {
      int[] pVariant = new int[1];
      OS.MoveMemory(pVariant, pPostData + 8, 4);
      vt_type = new short[1];
      OS.MoveMemory(vt_type, pVariant[0], 2);
      if (vt_type[0] == (short) (OLE.VT_ARRAY | OLE.VT_UI1)) {
        long /*int*/[] pSafearray = new long /*int*/[1];
        OS.MoveMemory(pSafearray, pVariant[0] + 8, OS.PTR_SIZEOF);
        SAFEARRAY safeArray = new SAFEARRAY();
        OS.MoveMemory(safeArray, pSafearray[0], SAFEARRAY.sizeof);
        for (int i = 0; i < safeArray.cDims; i++) {
          int cchWideChar =
              OS.MultiByteToWideChar(CodePage, OS.MB_PRECOMPOSED, safeArray.pvData, -1, null, 0);
          if (cchWideChar == 0) return null;
          char[] lpWideCharStr = new char[cchWideChar - 1];
          OS.MultiByteToWideChar(
              CodePage,
              OS.MB_PRECOMPOSED,
              safeArray.pvData,
              -1,
              lpWideCharStr,
              lpWideCharStr.length);
          result = new String(lpWideCharStr);
        }
      }
    }
    return result;
  }

  static Variant writeSafeArray(String string) {
    // Create a one dimensional safearray containing two VT_UI1 values
    // where VT_UI1 is an unsigned char

    // Define cDims, fFeatures and cbElements
    short cDims = 1;
    short FADF_FIXEDSIZE = 0x10;
    short FADF_HAVEVARTYPE = 0x80;
    short fFeatures = (short) (FADF_FIXEDSIZE | FADF_HAVEVARTYPE);
    int cbElements = 1;
    // Create a pointer and copy the data into it
    int count = string.length();
    char[] chars = new char[count + 1];
    string.getChars(0, count, chars, 0);
    int cchMultiByte = OS.WideCharToMultiByte(CodePage, 0, chars, -1, null, 0, null, null);
    if (cchMultiByte == 0) return null;
    long /*int*/ pvData = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, cchMultiByte);
    OS.WideCharToMultiByte(CodePage, 0, chars, -1, pvData, cchMultiByte, null, null);
    int cElements1 = cchMultiByte;
    int lLbound1 = 0;
    // Create a safearray in memory
    long /*int*/ pSafeArray = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, SAFEARRAY.sizeof);
    SAFEARRAY safeArray = new SAFEARRAY();
    safeArray.cDims = cDims;
    safeArray.fFeatures = fFeatures;
    safeArray.cbElements = cbElements;
    safeArray.pvData = pvData;
    SAFEARRAYBOUND safeArrayBound = new SAFEARRAYBOUND();
    safeArray.rgsabound = safeArrayBound;
    safeArrayBound.cElements = cElements1;
    safeArrayBound.lLbound = lLbound1;
    OS.MoveMemory(pSafeArray, safeArray, SAFEARRAY.sizeof);
    // Create a variant in memory to hold the safearray
    long /*int*/ pVariant = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, Variant.sizeof);
    short vt = (short) (OLE.VT_ARRAY | OLE.VT_UI1);
    OS.MoveMemory(pVariant, new short[] {vt}, 2);
    OS.MoveMemory(pVariant + 8, new long /*int*/[] {pSafeArray}, OS.PTR_SIZEOF);
    // Create a by ref variant
    Variant variantByRef = new Variant(pVariant, (short) (OLE.VT_BYREF | OLE.VT_VARIANT));
    return variantByRef;
  }
}