diff options
author | Veronika Irvine | 2004-11-22 22:48:59 +0000 |
---|---|---|
committer | Veronika Irvine | 2004-11-22 22:48:59 +0000 |
commit | 4e54d10a77c1b5bd8e4db501d1cc42dac8d3fe78 (patch) | |
tree | 098575b057fa5cedb875def136f270862b57f7a0 | |
parent | 55c694fe14536618a500c8ce6028a23959f8beea (diff) | |
download | eclipse.platform.swt-eclipse_3_1_v3113.tar.gz eclipse.platform.swt-eclipse_3_1_v3113.tar.xz eclipse.platform.swt-eclipse_3_1_v3113.zip |
add support for X selection clipboardv3113aeclipse_3_1_v3113
2 files changed, 382 insertions, 341 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/Clipboard.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/Clipboard.java index 9c6e22d3d9..9cc5b2478a 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/Clipboard.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/Clipboard.java @@ -12,9 +12,9 @@ package org.eclipse.swt.dnd; import org.eclipse.swt.*; -import org.eclipse.swt.widgets.*; import org.eclipse.swt.internal.*; import org.eclipse.swt.internal.motif.*; +import org.eclipse.swt.widgets.*; /** * The <code>Clipboard</code> provides a mechanism for transferring data from one @@ -25,35 +25,6 @@ import org.eclipse.swt.internal.motif.*; public class Clipboard { Display display; - int shellHandle; - int clipboardAtom, primaryAtom, targetsAtom; - - static int[][] convertData = new int[10][3]; - static Clipboard activeClipboard = null; - static Clipboard activePrimaryClipboard = null; - static Object[] ClipboardData; - static Transfer[] ClipboardDataTypes; - static Object[] PrimaryClipboardData; - static Transfer[] PrimaryClipboardDataTypes; - - static boolean done = false; - static Object selectionValue; - static Transfer selectionTransfer; - - static byte [] CLIPBOARD = Converter.wcsToMbcs (null, "CLIPBOARD", true); - static byte [] PRIMARY = Converter.wcsToMbcs (null, "PRIMARY", true); - static byte [] TARGETS = Converter.wcsToMbcs (null, "TARGETS", true); - static Callback XtConvertSelectionCallback; - static Callback XtLoseSelectionCallback; - static Callback XtSelectionDoneCallback; - static Callback XtSelectionCallbackCallback; - - static { - XtConvertSelectionCallback = new Callback(Clipboard.class, "XtConvertSelection", 7); //$NON-NLS-1$ - XtLoseSelectionCallback = new Callback(Clipboard.class, "XtLoseSelection", 2); //$NON-NLS-1$ - XtSelectionDoneCallback = new Callback(Clipboard.class, "XtSelectionDone", 3); //$NON-NLS-1$ - XtSelectionCallbackCallback = new Callback(Clipboard.class, "XtSelectionCallback", 7); //$NON-NLS-1$ - } /** * Constructs a new instance of this class. Creating an instance of a Clipboard @@ -70,28 +41,19 @@ public class Clipboard { * @see Clipboard#dispose * @see Clipboard#checkSubclass */ -public Clipboard(Display display) { - checkSubclass (); - if (display == null) { - display = Display.getCurrent(); + public Clipboard(Display display) { + checkSubclass (); if (display == null) { - display = Display.getDefault(); + display = Display.getCurrent(); + if (display == null) { + display = Display.getDefault(); + } } + if (display.getThread() != Thread.currentThread()) { + DND.error(SWT.ERROR_THREAD_INVALID_ACCESS); + } + this.display = display; } - if (display.getThread() != Thread.currentThread()) { - DND.error(SWT.ERROR_THREAD_INVALID_ACCESS); - } - this.display = display; - - int widgetClass = OS.topLevelShellWidgetClass (); - shellHandle = OS.XtAppCreateShell (null, null, widgetClass, display.xDisplay, null, 0); - OS.XtSetMappedWhenManaged (shellHandle, false); - OS.XtRealizeWidget (shellHandle); - int xDisplay = OS.XtDisplay(shellHandle); - clipboardAtom = OS.XmInternAtom(xDisplay, CLIPBOARD, false); - primaryAtom = OS.XmInternAtom(xDisplay, PRIMARY, false); - targetsAtom = OS.XmInternAtom(xDisplay, TARGETS, false); -} /** * Checks that this class can be subclassed. @@ -203,14 +165,8 @@ public void clearContents() { */ public void clearContents(int clipboards) { checkWidget(); - int xDisplay = OS.XtDisplay(shellHandle); - if (xDisplay == 0) return; - if ((clipboards & DND.CLIPBOARD) != 0 && activeClipboard == this) { - OS.XtDisownSelection(shellHandle, clipboardAtom, OS.CurrentTime); - } - if ((clipboards & DND.SELECTION_CLIPBOARD) != 0 && activePrimaryClipboard == this) { - OS.XtDisownSelection(shellHandle, primaryAtom, OS.CurrentTime); - } + ClipboardProxy proxy = ClipboardProxy._getInstance(display); + proxy.clear(this, clipboards); } /** @@ -228,19 +184,6 @@ public void clearContents(int clipboards) { public void dispose () { if (isDisposed()) return; if (display.getThread() != Thread.currentThread()) DND.error(SWT.ERROR_THREAD_INVALID_ACCESS); - if (shellHandle != 0) { - int xDisplay = OS.XtDisplay(shellHandle); - if (xDisplay != 0) { - if (activeClipboard != null) { - OS.XtDisownSelection(shellHandle, clipboardAtom, OS.CurrentTime); - } - if (activePrimaryClipboard != null) { - OS.XtDisownSelection(shellHandle, primaryAtom, OS.CurrentTime); - } - } - OS.XtDestroyWidget (shellHandle); - shellHandle = 0; - } display = null; } @@ -326,42 +269,17 @@ public Object getContents(Transfer transfer) { public Object getContents(Transfer transfer, int clipboards) { checkWidget(); if (transfer == null) DND.error(SWT.ERROR_NULL_ARGUMENT); - int xDisplay = OS.XtDisplay (shellHandle); - if (xDisplay == 0) return null; + ClipboardProxy proxy = ClipboardProxy._getInstance(display); Object result = null; if ((clipboards & DND.CLIPBOARD) != 0) { - result = getContents(xDisplay, transfer, clipboardAtom); + result = proxy.getContents(transfer, DND.CLIPBOARD); } if (result != null) return result; if ((clipboards & DND.SELECTION_CLIPBOARD) != 0) { - result = getContents(xDisplay, transfer, primaryAtom); + result = proxy.getContents(transfer, DND.SELECTION_CLIPBOARD); } return result; } - -Object getContents(int xDisplay, Transfer transfer, int selection) { - int[] types = getAvailableTypes(xDisplay, selection); - int index = -1; - TransferData transferData = new TransferData(); - for (int i = 0; i < types.length; i++) { - transferData.type = types[i]; - if (transfer.isSupportedType(transferData)) { - index = i; - break; - } - } - if (index == -1) return null; - done = false; - selectionValue = null; selectionTransfer = transfer; - OS.XtGetSelectionValue(shellHandle, selection, types[index], XtSelectionCallbackCallback.getAddress(), 0, OS.CurrentTime); - if (!done) { - int xtContext = OS.XtDisplayToApplicationContext(xDisplay); - int selectionTimeout = OS.XtAppGetSelectionTimeout(xtContext); - _wait(selectionTimeout); - - } - return (!done) ? null : selectionValue; -} /** * Returns <code>true</code> if the clipboard has been disposed, @@ -424,14 +342,13 @@ public TransferData[] getAvailableTypes() { */ public TransferData[] getAvailableTypes(int clipboards) { checkWidget(); - int xDisplay = OS.XtDisplay (shellHandle); - if (xDisplay == 0) return null; + ClipboardProxy proxy = ClipboardProxy._getInstance(display); int[] types = null; if ((clipboards & DND.CLIPBOARD) != 0) { - types = getAvailableTypes(xDisplay, clipboardAtom); + types = proxy.getAvailableTypes(DND.CLIPBOARD); } if ((clipboards & DND.SELECTION_CLIPBOARD) != 0) { - int[] primaryTypes = getAvailableTypes(xDisplay, primaryAtom); + int[] primaryTypes = proxy.getAvailableTypes(DND.SELECTION_CLIPBOARD); if (types == null) { types = primaryTypes; } else { @@ -468,12 +385,12 @@ public TransferData[] getAvailableTypes(int clipboards) { */ public String[] getAvailableTypeNames() { checkWidget(); - int xDisplay = OS.XtDisplay (shellHandle); - if (xDisplay == 0) return new String[0]; - int[] types = getAvailableTypes(xDisplay, clipboardAtom); - int[] primaryTypes = getAvailableTypes(xDisplay, primaryAtom); + ClipboardProxy proxy = ClipboardProxy._getInstance(display); + int[] types = proxy.getAvailableTypes(DND.CLIPBOARD); + int[] primaryTypes = proxy.getAvailableTypes(DND.SELECTION_CLIPBOARD); String[] names = new String[types.length + primaryTypes.length]; int index = 0; + int xDisplay = display.xDisplay; for (int i = 0; i < types.length; i++) { int ptr = OS.XmGetAtomName(xDisplay, types[i]); int length = OS.strlen(ptr); @@ -497,19 +414,6 @@ public String[] getAvailableTypeNames() { return names; } -int[] getAvailableTypes(int xDisplay, int selection) { - done = false; - selectionValue = null; selectionTransfer = null; - OS.XtGetSelectionValue(shellHandle, selection, targetsAtom, XtSelectionCallbackCallback.getAddress(), 0, OS.CurrentTime); - if (!done) { - int xtContext = OS.XtDisplayToApplicationContext(xDisplay); - int selectionTimeout = OS.XtAppGetSelectionTimeout(xtContext); - _wait(selectionTimeout); - - } - return (!done || selectionValue == null) ? new int[0] : (int[])selectionValue; -} - /** * Place data of the specified type on the system clipboard. More than one type * of data can be placed on the system clipboard at the same time. Setting the @@ -630,214 +534,7 @@ public void setContents(Object[] data, Transfer[] dataTypes, int clipboards) { DND.error(SWT.ERROR_INVALID_ARGUMENT); } } - if ((clipboards & DND.CLIPBOARD) != 0) { - ClipboardData = data; - ClipboardDataTypes = dataTypes; - _setContents(data, dataTypes, clipboardAtom); - activeClipboard = this; - } - if ((clipboards & DND.SELECTION_CLIPBOARD) != 0) { - PrimaryClipboardData = data; - PrimaryClipboardDataTypes = dataTypes; - _setContents(data, dataTypes, primaryAtom); - activePrimaryClipboard = this; - } -} -void _setContents(Object[] data, Transfer[] dataTypes, int selection) { - int XtConvertSelectionProc = XtConvertSelectionCallback.getAddress(); - int XtLoseSelectionProc = XtLoseSelectionCallback.getAddress(); - int XtSelectionDoneProc = XtSelectionDoneCallback.getAddress(); - if (!OS.XtOwnSelection(shellHandle, selection, OS.CurrentTime, XtConvertSelectionProc, XtLoseSelectionProc, XtSelectionDoneProc)) { - DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD); - } -} - -static void storePtr(int ptr, int selection, int target) { - int index = -1; - for (int i = 0; i < convertData.length; i++) { - if (convertData[i][0] == 0){ - index = i; - break; - } - } - if (index == -1) { - int[][] newConvertData = new int[convertData.length][3]; - System.arraycopy(convertData, 0, newConvertData, 0, convertData.length); - index = convertData.length; - convertData = newConvertData; - } - convertData[index][0] = selection; - convertData[index][1] = target; - convertData[index][2] = ptr; -} - -void _wait(int timeout) { - int xDisplay = OS.XtDisplay(shellHandle); - if (xDisplay == 0) return; - long start = System.currentTimeMillis(); - int xEvent = OS.XtMalloc (XEvent.sizeof); - Callback checkEventCallback = new Callback(this, "checkEvent", 3); - int checkEventProc = checkEventCallback.getAddress(); - display.timerExec(timeout, new Runnable() { - public void run() { - // timer required to force display.sleep() to wake up - // in the case where no events are received - } - }); - while (!done && System.currentTimeMillis() - start < timeout && !isDisposed()) { - if (OS.XCheckIfEvent (xDisplay, xEvent, checkEventProc, 0) != 0) { - OS.XtDispatchEvent(xEvent); - } else { - display.sleep(); - } - } - OS.XtFree (xEvent); - checkEventCallback.dispose(); -} -int checkEvent(int display, int event, int arg) { - XEvent xEvent = new XEvent(); - OS.memmove (xEvent, event, XEvent.sizeof); - switch (xEvent.type) { - case OS.SelectionClear: - case OS.SelectionNotify: - case OS.SelectionRequest: - case OS.PropertyNotify: - return 1; - } - return 0; -} -static int XtConvertSelection(int widget, int selection, int target, int type, int value, int length, int format) { - int xDisplay = OS.XtDisplay (widget); - if (xDisplay == 0) return 0; - int selectionAtom = 0; - if (selection != 0) { - int[] dest = new int[1]; - OS.memmove(dest, selection, 4); - selectionAtom = dest[0]; - } - if (selectionAtom == 0) return 0; - int clipboardAtom = OS.XInternAtom (xDisplay, CLIPBOARD, false); - int primaryAtom = OS.XInternAtom (xDisplay, PRIMARY, false); - int targetsAtom = OS.XInternAtom (xDisplay, TARGETS, false); - Transfer[] types = null; - if (selectionAtom == clipboardAtom) types = ClipboardDataTypes; - if (selectionAtom == primaryAtom) types = PrimaryClipboardDataTypes; - if (types == null) return 0; - - int targetAtom = 0; - if (target != 0) { - int[] dest = new int[1]; - OS.memmove(dest, target, 4); - targetAtom = dest[0]; - } - if (targetAtom == targetsAtom) { - int[] transferTypes = new int[] {targetAtom}; - for (int i = 0; i < types.length; i++) { - TransferData[] subTypes = types[i].getSupportedTypes(); - int[] newtransferTypes = new int[transferTypes.length + subTypes.length]; - System.arraycopy(transferTypes, 0, newtransferTypes, 0, transferTypes.length); - int index = transferTypes.length; - transferTypes = newtransferTypes; - for (int j = 0; j < subTypes.length; j++) { - transferTypes[index++] = subTypes[j].type; - } - } - int ptr = OS.XtMalloc(transferTypes.length*4); - storePtr(ptr, selectionAtom, targetAtom); - OS.memmove(ptr, transferTypes, transferTypes.length*4); - OS.memmove(type, new int[]{targetsAtom}, 4); - OS.memmove(value, new int[] {ptr}, 4); - OS.memmove(length, new int[]{transferTypes.length}, 4); - OS.memmove(format, new int[]{32}, 4); - return 1; - } - - TransferData tdata = new TransferData(); - tdata.type = targetAtom; - int index = -1; - for (int i = 0; i < types.length; i++) { - if (types[i].isSupportedType(tdata)) { - index = i; - break; - } - } - if (index == -1) return 0; - Object[] data = selectionAtom == clipboardAtom ? ClipboardData : PrimaryClipboardData; - types[index].javaToNative(data[index], tdata); - if (tdata.format < 8 || tdata.format % 8 != 0) { - OS.XtFree(tdata.pValue); - return 0; - } - // copy data back to value - OS.memmove(type, new int[]{tdata.type}, 4); - OS.memmove(value, new int[]{tdata.pValue}, 4); - OS.memmove(length, new int[]{tdata.length}, 4); - OS.memmove(format, new int[]{tdata.format}, 4); - storePtr(tdata.pValue, selectionAtom, targetAtom); - return 1; -} - -static int XtLoseSelection(int widget, int selection) { - int xDisplay = OS.XtDisplay (widget); - int clipboardAtom = OS.XInternAtom (xDisplay, CLIPBOARD, false); - if (selection == clipboardAtom) { - activeClipboard = null; - ClipboardData = null; - ClipboardDataTypes = null; - } - int primaryAtom = OS.XInternAtom (xDisplay, PRIMARY, false); - if (selection == primaryAtom) { - activePrimaryClipboard = null; - PrimaryClipboardData = null; - PrimaryClipboardDataTypes = null; - } - return 0; -} - -static int XtSelectionCallback(int widget, int client_data, int selection, int type, int value, int length, int format) { - done = true; - int[] selectionType = new int[1]; - if (type != 0) OS.memmove(selectionType, type, 4); - if (selectionType[0] == 0) return 0; - int[] selectionLength = new int[1]; - if (length != 0) OS.memmove(selectionLength, length, 4); - if (selectionLength[0] == 0) return 0; - int[] selectionFormat = new int[1]; - if (format != 0) OS.memmove(selectionFormat, format, 4); - int xDisplay = OS.XtDisplay (widget); - if (xDisplay == 0) return 0; - int targetsAtom = OS.XInternAtom (xDisplay, TARGETS, false); - if (selectionType[0] == targetsAtom) { - int[] targets = new int[selectionLength[0]]; - OS.memmove(targets, value, selectionLength[0] * selectionFormat [0] / 8); - selectionValue = targets; - return 0; - } - if (selectionTransfer != null) { - TransferData transferData = new TransferData(); - transferData.type = selectionType[0]; - transferData.length = selectionLength[0]; - transferData.format = selectionFormat[0]; - transferData.pValue = value; - transferData.result = 1; - selectionValue = selectionTransfer.nativeToJava(transferData); - } - return 0; -} - -static int XtSelectionDone(int widget, int selection, int target) { - if (target == 0 || selection == 0) return 0; - int[] selectionAtom = new int[1]; - OS.memmove(selectionAtom, selection, 4); - int[] targetAtom = new int[1]; - OS.memmove(targetAtom, target, 4); - for (int i = 0; i < convertData.length; i++) { - if (convertData[i][0] == selectionAtom[0] && convertData[i][1] == targetAtom[0]) { - OS.XtFree(convertData[i][2]); - convertData[i][0] = convertData[i][1] = convertData[i][2] = 0; - break; - } - } - return 0; + ClipboardProxy proxy = ClipboardProxy._getInstance(display); + proxy.setContents(this, data, dataTypes, clipboards); } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/ClipboardProxy.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/ClipboardProxy.java index b6f58c0ab2..65cf5af79c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/ClipboardProxy.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/ClipboardProxy.java @@ -1,17 +1,361 @@ -/* - * Created on Nov 22, 2004 - * - * TODO To change the template for this generated file go to - * Window - Preferences - Java - Code Style - Code Templates - */ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package org.eclipse.swt.dnd; -/** - * @author torres - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Style - Code Templates - */ -public class ClipboardProxy { +import org.eclipse.swt.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.motif.*; +import org.eclipse.swt.widgets.*; + +class ClipboardProxy { + + Display display; + int shellHandle; + int clipboardAtom, primaryAtom, targetsAtom; + int[][] convertData = new int[10][3]; + Clipboard activeClipboard = null; + Clipboard activePrimaryClipboard = null; + Object[] clipboardData; + Transfer[] clipboardDataTypes; + Object[] primaryClipboardData; + Transfer[] primaryClipboardDataTypes; + + boolean done = false; + Object selectionValue; + Transfer selectionTransfer; + + Callback XtConvertSelectionCallback; + Callback XtLoseSelectionCallback; + Callback XtSelectionDoneCallback; + Callback XtSelectionCallbackCallback; + + static byte [] CLIPBOARD = Converter.wcsToMbcs (null, "CLIPBOARD", true); //$NON-NLS-1$ + static byte [] PRIMARY = Converter.wcsToMbcs (null, "PRIMARY", true); //$NON-NLS-1$ + static byte [] TARGETS = Converter.wcsToMbcs (null, "TARGETS", true); //$NON-NLS-1$ + static String ID = "CLIPBOARD PROXY OBJECT"; //$NON-NLS-1$ + + static ClipboardProxy _getInstance(final Display display) { + ClipboardProxy proxy = (ClipboardProxy) display.getData(ID); + if (proxy != null) return proxy; + proxy = new ClipboardProxy(display); + display.setData(ID, proxy); + display.addListener(SWT.Dispose, new Listener() { + public void handleEvent(Event event) { + ClipboardProxy clipbordProxy = (ClipboardProxy)display.getData(ID); + if (clipbordProxy == null) return; + display.setData(ID, null); + clipbordProxy.dispose(); + } + }); + return proxy; + } + +ClipboardProxy(Display display) { + this.display = display; + XtConvertSelectionCallback = new Callback(this, "XtConvertSelection", 7); //$NON-NLS-1$ + XtLoseSelectionCallback = new Callback(this, "XtLoseSelection", 2); //$NON-NLS-1$ + XtSelectionDoneCallback = new Callback(this, "XtSelectionDone", 3); //$NON-NLS-1$ + XtSelectionCallbackCallback = new Callback(this, "XtSelectionCallback", 7); //$NON-NLS-1$ + + int widgetClass = OS.topLevelShellWidgetClass (); + shellHandle = OS.XtAppCreateShell (null, null, widgetClass, display.xDisplay, null, 0); + OS.XtSetMappedWhenManaged (shellHandle, false); + OS.XtRealizeWidget (shellHandle); + int xDisplay = OS.XtDisplay(shellHandle); + clipboardAtom = OS.XmInternAtom(xDisplay, CLIPBOARD, false); + primaryAtom = OS.XmInternAtom(xDisplay, PRIMARY, false); + targetsAtom = OS.XmInternAtom(xDisplay, TARGETS, false); +} + + + void clear(Clipboard owner, int clipboards) { + int xDisplay = OS.XtDisplay(shellHandle); + if (xDisplay == 0) return; + if ((clipboards & DND.CLIPBOARD) != 0 && activeClipboard == owner) { + OS.XtDisownSelection(shellHandle, clipboardAtom, OS.CurrentTime); + } + if ((clipboards & DND.SELECTION_CLIPBOARD) != 0 && activePrimaryClipboard == owner) { + OS.XtDisownSelection(shellHandle, primaryAtom, OS.CurrentTime); + } +} + + void dispose () { + if (display == null) return; + if (shellHandle != 0) { + if (activeClipboard != null) { + OS.XtDisownSelection(shellHandle, clipboardAtom, OS.CurrentTime); + } + if (activePrimaryClipboard != null) { + OS.XtDisownSelection(shellHandle, primaryAtom, OS.CurrentTime); + } + OS.XtDestroyWidget (shellHandle); + shellHandle = 0; + } + if (XtConvertSelectionCallback != null) XtConvertSelectionCallback.dispose(); + XtConvertSelectionCallback = null; + if (XtLoseSelectionCallback != null) XtLoseSelectionCallback.dispose(); + XtLoseSelectionCallback = null; + if (XtSelectionCallbackCallback != null) XtSelectionCallbackCallback.dispose(); + XtSelectionCallbackCallback = null; + if (XtSelectionDoneCallback != null) XtSelectionDoneCallback.dispose(); + XtSelectionDoneCallback = null; + clipboardData = null; + clipboardDataTypes = null; + primaryClipboardData = null; + primaryClipboardDataTypes = null; +} + +Object getContents(Transfer transfer, int clipboardType) { + int[] types = getAvailableTypes(clipboardType); + int index = -1; + TransferData transferData = new TransferData(); + for (int i = 0; i < types.length; i++) { + transferData.type = types[i]; + if (transfer.isSupportedType(transferData)) { + index = i; + break; + } + } + if (index == -1) return null; + done = false; + selectionValue = null; selectionTransfer = transfer; + int selection = clipboardType == DND.CLIPBOARD ? clipboardAtom : primaryAtom; + OS.XtGetSelectionValue(shellHandle, selection, types[index], XtSelectionCallbackCallback.getAddress(), 0, OS.CurrentTime); + if (!done) { + int xDisplay = OS.XtDisplay (shellHandle); + if (xDisplay == 0) return null; + int xtContext = OS.XtDisplayToApplicationContext(xDisplay); + int selectionTimeout = OS.XtAppGetSelectionTimeout(xtContext); + wait(selectionTimeout); + } + return (!done) ? null : selectionValue; +} + +int[] getAvailableTypes(int clipboardType) { + int xDisplay = OS.XtDisplay (shellHandle); + if (xDisplay == 0) return new int[0]; + done = false; + selectionValue = null; selectionTransfer = null; + int selection = clipboardType == DND.CLIPBOARD ? clipboardAtom : primaryAtom; + OS.XtGetSelectionValue(shellHandle, selection, targetsAtom, XtSelectionCallbackCallback.getAddress(), 0, OS.CurrentTime); + if (!done) { + int xtContext = OS.XtDisplayToApplicationContext(xDisplay); + int selectionTimeout = OS.XtAppGetSelectionTimeout(xtContext); + wait(selectionTimeout); + + } + return (!done || selectionValue == null) ? new int[0] : (int[])selectionValue; +} + +void setContents(Clipboard owner, Object[] data, Transfer[] dataTypes, int clipboards) { + if ((clipboards & DND.CLIPBOARD) != 0) { + clipboardData = data; + clipboardDataTypes = dataTypes; + int XtConvertSelectionProc = XtConvertSelectionCallback.getAddress(); + int XtLoseSelectionProc = XtLoseSelectionCallback.getAddress(); + int XtSelectionDoneProc = XtSelectionDoneCallback.getAddress(); + if (!OS.XtOwnSelection(shellHandle, clipboardAtom, OS.CurrentTime, XtConvertSelectionProc, XtLoseSelectionProc, XtSelectionDoneProc)) { + DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD); + } + activeClipboard = owner; + } + if ((clipboards & DND.SELECTION_CLIPBOARD) != 0) { + primaryClipboardData = data; + primaryClipboardDataTypes = dataTypes; + int XtConvertSelectionProc = XtConvertSelectionCallback.getAddress(); + int XtLoseSelectionProc = XtLoseSelectionCallback.getAddress(); + int XtSelectionDoneProc = XtSelectionDoneCallback.getAddress(); + if (!OS.XtOwnSelection(shellHandle, primaryAtom, OS.CurrentTime, XtConvertSelectionProc, XtLoseSelectionProc, XtSelectionDoneProc)) { + DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD); + } + activePrimaryClipboard = owner; + } +} + +void storePtr(int ptr, int selection, int target) { + int index = -1; + for (int i = 0; i < convertData.length; i++) { + if (convertData[i][0] == 0){ + index = i; + break; + } + } + if (index == -1) { + int[][] newConvertData = new int[convertData.length][3]; + System.arraycopy(convertData, 0, newConvertData, 0, convertData.length); + index = convertData.length; + convertData = newConvertData; + } + convertData[index][0] = selection; + convertData[index][1] = target; + convertData[index][2] = ptr; +} + +void wait(int timeout) { + int xDisplay = OS.XtDisplay(shellHandle); + if (xDisplay == 0) return; + long start = System.currentTimeMillis(); + int xEvent = OS.XtMalloc (XEvent.sizeof); + Callback checkEventCallback = new Callback(this, "checkEvent", 3); //$NON-NLS-1$ + int checkEventProc = checkEventCallback.getAddress(); + display.timerExec(timeout, new Runnable() { + public void run() { + // timer required to force display.sleep() to wake up + // in the case where no events are received + } + }); + while (!done && System.currentTimeMillis() - start < timeout && display != null) { + if (OS.XCheckIfEvent (xDisplay, xEvent, checkEventProc, 0) != 0) { + OS.XtDispatchEvent(xEvent); + } else { + display.sleep(); + } + } + OS.XtFree (xEvent); + checkEventCallback.dispose(); +} +int checkEvent(int display, int event, int arg) { + XEvent xEvent = new XEvent(); + OS.memmove (xEvent, event, XEvent.sizeof); + switch (xEvent.type) { + case OS.SelectionClear: + case OS.SelectionNotify: + case OS.SelectionRequest: + case OS.PropertyNotify: + return 1; + } + return 0; +} +int XtConvertSelection(int widget, int selection, int target, int type, int value, int length, int format) { + int selectionAtom = 0; + if (selection != 0) { + int[] dest = new int[1]; + OS.memmove(dest, selection, 4); + selectionAtom = dest[0]; + } + if (selectionAtom == 0) return 0; + Transfer[] types = null; + if (selectionAtom == clipboardAtom) types = clipboardDataTypes; + if (selectionAtom == primaryAtom) types = primaryClipboardDataTypes; + if (types == null) return 0; + + int targetAtom = 0; + if (target != 0) { + int[] dest = new int[1]; + OS.memmove(dest, target, 4); + targetAtom = dest[0]; + } + if (targetAtom == targetsAtom) { + int[] transferTypes = new int[] {targetAtom}; + for (int i = 0; i < types.length; i++) { + TransferData[] subTypes = types[i].getSupportedTypes(); + int[] newtransferTypes = new int[transferTypes.length + subTypes.length]; + System.arraycopy(transferTypes, 0, newtransferTypes, 0, transferTypes.length); + int index = transferTypes.length; + transferTypes = newtransferTypes; + for (int j = 0; j < subTypes.length; j++) { + transferTypes[index++] = subTypes[j].type; + } + } + int ptr = OS.XtMalloc(transferTypes.length*4); + storePtr(ptr, selectionAtom, targetAtom); + OS.memmove(ptr, transferTypes, transferTypes.length*4); + OS.memmove(type, new int[]{targetsAtom}, 4); + OS.memmove(value, new int[] {ptr}, 4); + OS.memmove(length, new int[]{transferTypes.length}, 4); + OS.memmove(format, new int[]{32}, 4); + return 1; + } + + TransferData tdata = new TransferData(); + tdata.type = targetAtom; + int index = -1; + for (int i = 0; i < types.length; i++) { + if (types[i].isSupportedType(tdata)) { + index = i; + break; + } + } + if (index == -1) return 0; + Object[] data = selectionAtom == clipboardAtom ? clipboardData : primaryClipboardData; + types[index].javaToNative(data[index], tdata); + if (tdata.format < 8 || tdata.format % 8 != 0) { + OS.XtFree(tdata.pValue); + return 0; + } + // copy data back to value + OS.memmove(type, new int[]{tdata.type}, 4); + OS.memmove(value, new int[]{tdata.pValue}, 4); + OS.memmove(length, new int[]{tdata.length}, 4); + OS.memmove(format, new int[]{tdata.format}, 4); + storePtr(tdata.pValue, selectionAtom, targetAtom); + return 1; +} + +int XtLoseSelection(int widget, int selection) { + if (selection == clipboardAtom) { + activeClipboard = null; + clipboardData = null; + clipboardDataTypes = null; + } + if (selection == primaryAtom) { + activePrimaryClipboard = null; + primaryClipboardData = null; + primaryClipboardDataTypes = null; + } + return 0; +} + +int XtSelectionCallback(int widget, int client_data, int selection, int type, int value, int length, int format) { + done = true; + int[] selectionType = new int[1]; + if (type != 0) OS.memmove(selectionType, type, 4); + if (selectionType[0] == 0) return 0; + int[] selectionLength = new int[1]; + if (length != 0) OS.memmove(selectionLength, length, 4); + if (selectionLength[0] == 0) return 0; + int[] selectionFormat = new int[1]; + if (format != 0) OS.memmove(selectionFormat, format, 4); + if (selectionType[0] == targetsAtom) { + int[] targets = new int[selectionLength[0]]; + OS.memmove(targets, value, selectionLength[0] * selectionFormat [0] / 8); + selectionValue = targets; + return 0; + } + if (selectionTransfer != null) { + TransferData transferData = new TransferData(); + transferData.type = selectionType[0]; + transferData.length = selectionLength[0]; + transferData.format = selectionFormat[0]; + transferData.pValue = value; + transferData.result = 1; + selectionValue = selectionTransfer.nativeToJava(transferData); + } + return 0; +} + +int XtSelectionDone(int widget, int selection, int target) { + if (target == 0 || selection == 0) return 0; + int[] selectionAtom = new int[1]; + OS.memmove(selectionAtom, selection, 4); + int[] targetAtom = new int[1]; + OS.memmove(targetAtom, target, 4); + for (int i = 0; i < convertData.length; i++) { + if (convertData[i][0] == selectionAtom[0] && convertData[i][1] == targetAtom[0]) { + OS.XtFree(convertData[i][2]); + convertData[i][0] = convertData[i][1] = convertData[i][2] = 0; + break; + } + } + return 0; +} } |