*** empty log message ***
diff --git a/bundles/org.eclipse.swt/.classpath_gtk b/bundles/org.eclipse.swt/.classpath_gtk
index 045d19e..5a85f7b 100644
--- a/bundles/org.eclipse.swt/.classpath_gtk
+++ b/bundles/org.eclipse.swt/.classpath_gtk
@@ -9,7 +9,7 @@
<classpathentry kind="src" path="Eclipse SWT PI/common_j2se"/>
<classpathentry kind="src" path="Eclipse SWT Accessibility/emulated"/>
<classpathentry kind="src" path="Eclipse SWT Accessibility/common"/>
- <classpathentry kind="src" path="Eclipse SWT Drag and Drop/emulated"/>
+ <classpathentry kind="src" path="Eclipse SWT Drag and Drop/gtk"/>
<classpathentry kind="src" path="Eclipse SWT Drag and Drop/common"/>
<classpathentry kind="src" path="Eclipse SWT Printing/gtk"/>
<classpathentry kind="src" path="Eclipse SWT Printing/common"/>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ByteArrayTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ByteArrayTransfer.java
new file mode 100644
index 0000000..15defa3
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ByteArrayTransfer.java
@@ -0,0 +1,62 @@
+package org.eclipse.swt.dnd;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.internal.gtk.OS;
+
+/**
+ * The class <code>ByteArrayTransfer</code> provides a platform specific mechanism for transforming
+ * a Java array of bytes into a format that can be passed around in a Drag and Drop operation and vice
+ * versa.
+ *
+ * <p>This abstract class can be subclassed to provided utilities for transforming Java data types
+ * into the byte array based platform specific drag and drop data types. See TextTransfer and
+ * FileTransfer for examples. If the data you are transferring <b>does not</b> map to a byte array,
+ * you should sub-class Transfer directly and do your own mapping to the platform data types.</p>
+ */
+public abstract class ByteArrayTransfer extends Transfer {
+
+public TransferData[] getSupportedTypes(){
+ int[] types = getTypeIds();
+ TransferData[] data = new TransferData[types.length];
+ for (int i = 0; i < types.length; i++) {
+ data[i] = new TransferData();
+ data[i].type = types[i];
+ }
+ return data;
+}
+
+public boolean isSupportedType(TransferData transferData){
+ if ( transferData == null ) return false;
+ int[] types = getTypeIds();
+ for (int i = 0; i < types.length; i++) {
+ if (transferData.type == types[i]) return true;
+ }
+ return false;
+}
+
+protected void javaToNative (Object object, TransferData transferData){
+ if ((object == null) || !(object instanceof byte[]) || !(isSupportedType(transferData))) {
+ if ( transferData != null ) transferData.result = 0;
+ return;
+ }
+ byte[] buffer = (byte[])object;
+ transferData.pValue = OS.g_malloc(buffer.length);
+ OS.memmove(transferData.pValue, buffer, buffer.length);
+ transferData.length = buffer.length;
+ transferData.format = 8;
+ transferData.result = 1;
+}
+
+protected Object nativeToJava(TransferData transferData){
+ if ( !isSupportedType(transferData) || transferData.pValue == 0 ) return null;
+ int size = transferData.format * transferData.length / 8;
+ byte[] buffer = new byte[size];
+ OS.memmove(buffer, transferData.pValue, size);
+ return buffer;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/Clipboard.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/Clipboard.java
new file mode 100644
index 0000000..1e04065
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/Clipboard.java
@@ -0,0 +1,180 @@
+package org.eclipse.swt.dnd;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.gtk.GtkSelectionData;
+import org.eclipse.swt.internal.gtk.GtkTargetEntry;
+import org.eclipse.swt.internal.gtk.OS;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ */
+public class Clipboard {
+
+ Display display;
+ Callback getFunc;
+ Callback clearFunc;
+
+ int pGtkClipboard;
+
+ /* Hold the reference for the data and transfer to be used in the callback */
+ Object[] data;
+ Transfer[] dataTypes;
+
+public Clipboard(Display display) {
+ checkSubclass ();
+ if (display == null) {
+ display = Display.getCurrent();
+ if (display == null) {
+ display = Display.getDefault();
+ }
+ }
+ if (display.getThread() != Thread.currentThread()) {
+ SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);
+ }
+ this.display = display;
+
+ //Setting callbacks
+ getFunc = new Callback( this, "getFunc", 4);
+ clearFunc = new Callback( this, "clearFunc", 2);
+
+ pGtkClipboard = OS.gtk_clipboard_get(OS.GDK_NONE);
+}
+
+int clearFunc(int clipboard,int user_data_or_owner){
+ data = null;
+ dataTypes = null;
+ return 1;
+}
+
+protected void checkSubclass () {
+ String name = getClass().getName ();
+ String validName = Clipboard.class.getName();
+ if (!validName.equals(name)) {
+ DND.error (SWT.ERROR_INVALID_SUBCLASS);
+ }
+}
+
+public void dispose () {
+ if (pGtkClipboard == 0) return;
+ if (data != null) OS.gtk_clipboard_clear(pGtkClipboard);
+ OS.g_free(pGtkClipboard);
+ pGtkClipboard = 0;
+ display = null;
+ if (getFunc != null ) getFunc.dispose();
+ getFunc = null;
+ if (clearFunc != null) clearFunc.dispose();
+ clearFunc = null;
+}
+public Object getContents(Transfer transfer) {
+ int selection_data = 0;
+ int[] typeIds = transfer.getTypeIds();
+ for (int i = 0; i < typeIds.length; i++) {
+ selection_data = OS.gtk_clipboard_wait_for_contents(pGtkClipboard, typeIds[i]);
+ if( selection_data != 0) break;
+ };
+ if (selection_data == 0) return null; // No data available for this transfer
+
+ GtkSelectionData gtkSelectionData = new GtkSelectionData(selection_data);
+ TransferData tdata = new TransferData();
+ tdata.type = gtkSelectionData.target;
+ tdata.pValue = gtkSelectionData.data;
+ tdata.length = gtkSelectionData.length;
+ tdata.format = gtkSelectionData.format;
+ Object result = transfer.nativeToJava(tdata);
+ OS.gtk_selection_data_free(selection_data);
+ return result;
+}
+
+/**
+ * This function provides the data to the clipboard.
+ * Because of the callback mechanism, the data in the clipboard
+ * will not be available when this object is disposed
+ * (just if the data was set in the clipboard by app who owns
+ * this Clipboard object)
+ */
+int getFunc( int clipboard, int selection_data, int info, int user_data_or_owner){
+ if (selection_data == 0) return 0;
+ GtkSelectionData selectionData = new GtkSelectionData(selection_data);
+ TransferData tdata = new TransferData();
+ tdata.type = selectionData.target;
+ int index = -1;
+ for (int i = 0; i < dataTypes.length; i++) {
+ if (dataTypes[i].isSupportedType(tdata)) {
+ index = i;
+ break;
+ }
+ }
+ if (index == -1) return 0;
+ dataTypes[index].javaToNative(data[index], tdata);
+ OS.gtk_selection_data_set(selection_data, tdata.type, tdata.format, tdata.pValue, tdata.length);
+ return 1;
+}
+
+public void setContents(Object[] data, Transfer[] dataTypes){
+ if (data == null || dataTypes == null || data.length != dataTypes.length) {
+ DND.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (display.isDisposed() ) DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD);
+ if (dataTypes.length == 0) return;
+
+ if (this.data != null) {
+ OS.gtk_clipboard_clear(pGtkClipboard);
+ }
+
+ GtkTargetEntry[] entries = new GtkTargetEntry [0];
+ for (int i = 0; i < dataTypes.length; i++) {
+ Transfer transfer = dataTypes[i];
+ int[] typeIds = transfer.getTypeIds();
+ String[] typeNames = transfer.getTypeNames();
+ for (int j = 0; j < typeIds.length; j++) {
+ GtkTargetEntry entry = new GtkTargetEntry();
+ entry.info = typeIds[j];
+ byte[] buffer = Converter.wcsToMbcs(null, typeNames[j], true);
+ int pName = OS.g_malloc(buffer.length);
+ OS.memmove(pName, buffer, buffer.length);
+ entry.target = pName;
+ GtkTargetEntry[] tmp = new GtkTargetEntry [entries.length + 1];
+ System.arraycopy(entries, 0, tmp, 0, entries.length);
+ tmp[entries.length] = entry;
+ entries = tmp;
+ }
+ }
+
+ int pTargetsList = OS.g_malloc(GtkTargetEntry.sizeof * entries.length);
+ int offset = 0;
+ for (int i = 0; i < entries.length; i++) {
+ OS.memmove(pTargetsList + offset, entries[i]);
+ offset += GtkTargetEntry.sizeof;
+ }
+
+ this.data = data;
+ this.dataTypes = dataTypes;
+
+ boolean result = OS.gtk_clipboard_set_with_data(pGtkClipboard, pTargetsList, entries.length, getFunc.getAddress(), clearFunc.getAddress(), 0);
+
+ if ( entries != null ) {
+ for (int i = 0; i < entries.length; i++) {
+ GtkTargetEntry entry = entries[i];
+ if( entry.target != 0) OS.g_free(entry.target);
+ }
+ }
+ if (pTargetsList != 0) OS.g_free(pTargetsList);
+
+ if (!result) DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD);
+}
+/*
+ * Note: getAvailableTypeNames is a tool for writing a Transfer sub-class only. It should
+ * NOT be used within an application because it provides platform specfic
+ * information.
+ */
+public String[] getAvailableTypeNames() {
+ return new String[0];
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DragSource.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DragSource.java
new file mode 100644
index 0000000..ff3cff3
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DragSource.java
@@ -0,0 +1,392 @@
+package org.eclipse.swt.dnd;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2002.
+ * All Rights Reserved
+ */
+
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.gtk.*;
+
+/**
+ *
+ * Class <code>DragSource</code> defines the source object for a drag and drop transfer.
+ *
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ *
+ * <p>This class defines the following items:<ul>
+ * <li>the <code>Control</code> that the user clicks on to intiate a drag;
+ * <li>the data that will be transferred on a successful drop;
+ * <li>and the modes (move, copy, link) of transfer that are allowed.
+ * </ul></p>
+ *
+ * <p>You may have several DragSources in an application but you can only have one DragSource
+ * per Control. Data dragged from this DragSource can be dropped on a site within this application
+ * but it can also be dropped on another application such as an external Text editor.</p>
+ *
+ * <p>The application supplies the content of the data being transferred by implementing the interface
+ * <code>DragSourceListener</code> which uses the class <code>DragSourceEvent</code>.
+ * The application is required to take the appropriate action to remove the data from the drag source
+ * when a successful move operation occurs.</p>
+ *
+ * <code><pre>
+ * // Enable a label as a Drag Source
+ * Label label = new Label(shell, SWT.NONE);
+ * // This example will allow text to be dragged
+ * Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
+ * // This example will allow the text to be copied or moved to the drop target
+ * int operations = DND.DROP_MOVE | DND.DROP_COPY;
+ *
+ * DragSource source = new DragSource (label, operations);
+ * source.setTransfer(types);
+ * source.addDragListener (new DragSourceListener() {
+ * public void dragStart(DragSourceEvent e) {
+ * // Only start the drag if there is actually text in the
+ * // label - this text will be what is dropped on the target.
+ * if (label.getText().length() == 0) {
+ * event.doit = false;
+ * }
+ * };
+ * public void dragSetData (DragSourceEvent event) {
+ * // A drop has been performed, so provide the data of the
+ * // requested type.
+ * // (Checking the type of the requested data is only
+ * // necessary if the drag source supports more than
+ * // one data type but is shown here as an example).
+ * if (TextTransfer.getInstance().isSupportedType(event.dataType)){
+ * event.data = label.getText();
+ * }
+ * }
+ * public void dragFinished(DragSourceEvent event) {
+ * // A Move operation has been performed so remove the data
+ * // from the source
+ * if (event.detail == DND.DROP_MOVE)
+ * label.setText("");
+ * }
+ * });
+ * </pre></code>
+ *
+ *
+ * <dl>
+ * <dt><b>Styles</b> <dd>DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK
+ * <dt><b>Events</b> <dd>DND.DragEnd, DND.DragSetData
+ * </dl>
+ */
+public final class DragSource extends Widget {
+ Control control;
+ Transfer[] transfers;
+ Callback dragBegin;
+ Callback dragGetData;
+ Callback dragEnd;
+ int dragBeginAddress;
+ int dragGetDataAddress;
+ int dragEndAddress;
+
+ GtkTargetEntry[] targets; //Data reference to be freed
+ int targets_list; //Data reference to be freed
+
+ final int buttonMask = OS.GDK_BUTTON1_MASK | OS.GDK_BUTTON3_MASK;
+ int operations;
+
+ Listener controlListener;
+
+/**
+ * Creates a new <code>DragSource</code> to handle dragging from the specified <code>Control</code>.
+ *
+ * @param control the <code>Control</code> that the user clicks on to initiate the drag
+ *
+ * @param style the bitwise OR'ing of allowed operations; this may be a combination of any of
+ * DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK
+ *
+ */
+public DragSource(Control control, int style) {
+ super (control, checkStyle(style));
+ this.control = control;
+
+ operations = 0;
+ if ( (style & DND.DROP_MOVE) != 0) operations |= OS.GDK_ACTION_MOVE;
+ if ( (style & DND.DROP_COPY) != 0) operations |= OS.GDK_ACTION_COPY;
+ if ( (style & DND.DROP_LINK) != 0) operations |= OS.GDK_ACTION_LINK;
+
+ // Drag Begin Callback
+ dragBegin = new Callback(this, "dragBegin", 3);
+ dragBeginAddress = dragBegin.getAddress();
+ byte[] dragBeginB = Converter.wcsToMbcs(null, "drag_begin", true);
+ OS.gtk_signal_connect(control.handle, dragBeginB, dragBeginAddress, 0);
+
+ // Drag Get Data Callback
+ dragGetData = new Callback(this, "dragGetData", 6);
+ dragGetDataAddress = dragGetData.getAddress();
+ byte[] dragGetDataB = Converter.wcsToMbcs(null, "drag_data_get", true);
+ OS.gtk_signal_connect(control.handle, dragGetDataB, dragGetDataAddress, 0);
+
+ // Drag End Callback
+ dragEnd = new Callback(this, "dragEnd", 3);
+ dragEndAddress = dragEnd.getAddress();
+ byte[] dragEndB = Converter.wcsToMbcs(null, "drag_end", true);
+ OS.gtk_signal_connect(control.handle, dragEndB, dragEndAddress, 0);
+
+
+ controlListener = new Listener(){
+ public void handleEvent(Event event){
+ DragSource.this.dispose();
+ }
+ };
+ control.addListener(SWT.Dispose, controlListener);
+ this.addListener(SWT.Dispose, new Listener(){
+ public void handleEvent(Event event){
+ DragSource.this.onDispose();
+ }
+ });
+
+}
+
+/**
+ * Adds the listener to receive events.
+ *
+ * @param listener the listener
+ *
+ * @exception SWTError
+ * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * <li>ERROR_NULL_ARGUMENT when listener is null</li></ul>
+ */
+public void addDragListener(DragSourceListener listener) {
+ if (listener == null) DND.error (SWT.ERROR_NULL_ARGUMENT);
+ DNDListener typedListener = new DNDListener (listener);
+ addListener (DND.DragStart, typedListener);
+ addListener (DND.DragEnd, typedListener);
+ addListener (DND.DragSetData, typedListener);
+}
+
+static int checkStyle (int style) {
+ if (style == SWT.NONE) return DND.DROP_MOVE;
+ return style;
+}
+
+
+int dragBegin(int widget, int context, int data){
+
+ int time = 0;
+ if(context != 0 ) {
+ GdkDragContext gdkDragContext = new GdkDragContext(context);
+ time = gdkDragContext.start_time; //BAD (ALWAYS ZERO)
+ if (time == 0) time = OS.GDK_CURRENT_TIME(); //BAD (ALWAYS ZERO)
+ }
+ DNDEvent event = new DNDEvent();
+ event.doit = true;
+ event.widget = this;
+ event.time = time;
+ notifyListeners(DND.DragStart, event);
+
+ if ( ! event.doit) {
+ OS.gdk_drag_abort(context, event.time ); //BAD (NOT WORKING)
+ }
+
+ return 1;
+}
+
+int dragEnd(int widget, int context, int data){
+ int op = DND.DROP_NONE;
+ boolean doit = true;
+ if (context != 0) {
+ GdkDragContext dragContext = new GdkDragContext (context);
+ switch (dragContext.action) {
+ case OS.GDK_ACTION_MOVE:
+ op = DND.DROP_MOVE;
+ break;
+ case OS.GDK_ACTION_COPY:
+ op = DND.DROP_COPY;
+ break;
+ case OS.GDK_ACTION_LINK:
+ op = DND.DROP_LINK;
+ break;
+ case 0: //Drag was cancel
+ doit = false;
+ break;
+ }
+ }
+
+ DNDEvent event = new DNDEvent();
+ event.widget = this;
+ event.doit = doit;
+ event.detail = op;
+ notifyListeners(DND.DragEnd, event);
+ return 1;
+}
+
+int dragGetData(int widget, int context, int selection_data, int info, int time, int data){
+ DNDEvent event = new DNDEvent();
+ event.widget = this;
+ event.time = time;
+ TransferData tdata = new TransferData ();
+ tdata.type = info;
+ event.dataType = tdata;
+
+ notifyListeners(DND.DragSetData, event);
+
+ if (event.data == null) return 0;
+
+ Transfer transfer = null;
+ for (int i = 0; i < transfers.length; i++) {
+ transfer = transfers[i];
+ if (transfer.isSupportedType(tdata)) break;
+ }
+ if (transfer == null) return 0;
+
+ if (selection_data == 0) return 0;
+ GtkSelectionData gtkSelectionData = new GtkSelectionData(selection_data);
+ if (gtkSelectionData.target == 0) return 0;
+
+ transfer.javaToNative(event.data, tdata);
+
+ OS.gtk_selection_data_set(selection_data, gtkSelectionData.target, transfer.format, tdata.pValue , tdata.length);
+
+ return 1;
+
+}
+
+public Display getDisplay () {
+ if (control == null) DND.error(SWT.ERROR_WIDGET_DISPOSED);
+ return control.getDisplay ();
+}
+
+/**
+ * Returns the list of data types that can be transferred by this DragSource.
+ *
+ * @return the list of data types that can be transferred by this DragSource
+ */
+public Transfer[] getTransfer(){
+ return transfers;
+}
+
+private void onDispose(){
+ if (dragBegin != null )
+ dragBegin.dispose();
+ dragBegin = null;
+
+ if (dragGetData != null )
+ dragGetData.dispose();
+ dragGetData = null;
+
+ if (dragEnd != null )
+ dragEnd.dispose();
+ dragEnd = null;
+
+
+ if (control != null){
+ OS.gtk_drag_source_unset(control.handle);
+ if (controlListener != null)
+ control.removeListener(SWT.Dispose, controlListener);
+ }
+
+ releaseTargets();
+ control = null;
+ controlListener = null;
+}
+
+
+private void releaseTargets(){
+
+ if ( targets != null ) {
+ for (int i = 0; i < targets.length; i++) {
+ GtkTargetEntry entry = targets[i];
+ if( entry.target != 0) OS.g_free(entry.target);
+ }
+ }
+
+ if (targets_list != 0) {
+ OS.g_free(targets_list);
+ }
+
+ targets_list = 0;
+ targets = null;
+}
+
+/**
+ * Removes the listener.
+ *
+ * @param listener the listener
+ *
+ * @exception SWTError
+ * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * <li>ERROR_NULL_ARGUMENT when listener is null</li></ul>
+ */
+public void removeDragListener(DragSourceListener listener) {
+ if (listener == null) DND.error (SWT.ERROR_NULL_ARGUMENT);
+ removeListener (DND.DragStart, listener);
+ removeListener (DND.DragEnd, listener);
+ removeListener (DND.DragSetData, listener);
+}
+
+private void setTargetList(){
+
+ if (transfers == null) return;
+ if (control == null) return;
+
+ releaseTargets();
+
+ int n_entry = 0;
+ GtkTargetEntry[] entrys = new GtkTargetEntry [n_entry];
+
+
+ Transfer[] transferAgents = transfers;
+ for (int i = 0; i < transferAgents.length; i++) {
+ Transfer transfer = transferAgents[i];
+ int[] types = transfer.getTypeIds();
+ for (int j = 0; j < types.length; j++) {
+ int type = types[j];
+ String typename = transfer.getTypeNames()[j];
+ byte[] buffer = Converter.wcsToMbcs(null, typename, true);
+ int ptr = OS.g_malloc(buffer.length);
+ OS.memmove(ptr, buffer, buffer.length);
+
+ GtkTargetEntry entry = new GtkTargetEntry();
+ entry.target = ptr;
+ entry.info = type;
+
+ GtkTargetEntry[] tmp = new GtkTargetEntry [n_entry + 1];
+ System.arraycopy(entrys, 0, tmp, 0, n_entry);
+ tmp[ n_entry ] = entry;
+ entrys = tmp;
+ n_entry++;
+ }
+ }
+
+ byte[] buffer = new byte[ GtkTargetEntry.sizeof * n_entry ];
+ byte[] tmp = new byte[ GtkTargetEntry.sizeof ];
+ for (int i = 0; i < n_entry; i++) {
+ OS.memmove(tmp, entrys[i], GtkTargetEntry.sizeof);
+ System.arraycopy(tmp, 0, buffer, i * GtkTargetEntry.sizeof, tmp.length);
+ }
+
+ int ptr = OS.g_malloc(buffer.length);
+ OS.memmove(ptr, buffer, buffer.length);
+
+ if (targets_list != 0){
+ OS.gtk_drag_source_unset(control.handle);
+ }
+
+ targets_list = ptr;
+ targets = entrys;
+
+ OS.gtk_drag_source_set(control.handle, buttonMask , targets_list, n_entry, operations );
+
+}
+
+/**
+ * Specifies the list of data types that can be transferred by this DragSource.
+ * The application must be able to provide data to match each of these types when
+ * a successful drop has occurred.
+ */
+public void setTransfer(Transfer[] transferAgents){
+ if (transferAgents == null) DND.error(SWT.ERROR_NULL_ARGUMENT);
+ this.transfers = transferAgents;
+ setTargetList();
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java
new file mode 100644
index 0000000..3cf19d4
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java
@@ -0,0 +1,505 @@
+package org.eclipse.swt.dnd;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2002.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.gtk.*;
+
+/**
+ *
+ * Class <code>DropTarget</code> defines the target object for a drag and drop transfer.
+ *
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ *
+ * <p>This class identifies the <code>Control</code> over which the user must position the cursor
+ * in order to drop the data being transferred. It also specifies what data types can be dropped on
+ * this control and what operations can be performed. You may have several DropTragets in an
+ * application but there can only be a one to one mapping between a <code>Control</code> and a <code>DropTarget</code>.
+ * The DropTarget can receive data from within the same application or from other applications
+ * (such as text dragged from a text editor like Word).</p>
+ *
+ * <code><pre>
+ * int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;
+ * Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
+ * DropTarget target = new DropTarget(label, operations);
+ * target.setTransfer(types);
+ * </code></pre>
+ *
+ * <p>The application is notified of data being dragged over this control and of when a drop occurs by
+ * implementing the interface <code>DropTargetListener</code> which uses the class
+ * <code>DropTargetEvent</code>. The application can modify the type of drag being performed
+ * on this Control at any stage of the drag by modifying the <code>event.detail</code> field or the
+ * <code>event.currentDataType</code> field. When the data is dropped, it is the responsibility of
+ * the application to copy this data for its own purposes.
+ *
+ * <code><pre>
+ * target.addDropListener (new DropTargetListener() {
+ * public void dragEnter(DropTargetEvent event) {};
+ * public void dragOver(DropTargetEvent event) {};
+ * public void dragLeave(DropTargetEvent event) {};
+ * public void dragOperationChanged(DropTargetEvent event) {};
+ * public void dropAccept(DropTargetEvent event) {}
+ * public void drop(DropTargetEvent event) {
+ * // A drop has occurred, copy over the data
+ * if (event.data == null) { // no data to copy, indicate failure in event.detail
+ * event.detail = DND.DROP_NONE;
+ * return;
+ * }
+ * label.setText ((String) event.data); // data copied to label text
+ * }
+ * });
+ * </pre></code>
+ *
+ * <dl>
+ * <dt><b>Styles</b> <dd>DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK
+ * <dt><b>Events</b> <dd>DND.DragEnter, DND.DragLeave, DND.DragOver, DND.DragOperationChanged,
+ * DND.Drop, DND.DropAccept
+ * </dl>
+ */
+public final class DropTarget extends Widget {
+
+/**
+ * Creates a new <code>DropTarget</code> to handle dropping on the specified <code>Control</code>.
+ *
+ * @param control the <code>Control</code> over which the user positions the cursor to drop data
+ *
+ * @param style the bitwise OR'ing of allowed operations; this may be a combination of any of
+ * DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK
+ *
+ */
+ Control control;
+ boolean isEnter = true;
+ Callback dragMotion;
+ Callback dragLeave;
+ Callback dragDataReceived;
+
+ int dragMotionAddress;
+ int dragLeaveAddress;
+ int dragDataReceivedAddress;
+
+ Transfer[] transfers;
+ TransferData[] transferDatas;
+
+ GtkTargetEntry[] targets; //Data reference to be freed
+ int targets_list; //Data reference to be freed
+
+ Listener controlListener;
+
+ int lastOperation = -1; // To control operations changed events
+ int lastX, lastY; // To be used in drag leave event (callback do not provided it)
+
+ private DragUnderEffect effect;
+
+public DropTarget(Control control, int style) {
+ super(control, checkStyle(style));
+ this.control = control;
+
+ // Drag Motion Callback
+ dragMotion = new Callback(this, "dragMotion", 5);
+ dragMotionAddress = dragMotion.getAddress();
+ byte[] dragMotionB = Converter.wcsToMbcs(null, "drag_motion", true);
+ OS.gtk_signal_connect(control.handle, dragMotionB, dragMotionAddress, 0);
+
+ // Drag Leave Callback
+ dragLeave = new Callback(this, "dragLeave", 3);
+ dragLeaveAddress = dragLeave.getAddress();
+ byte[] dragLeaveB = Converter.wcsToMbcs(null, "drag_leave", true);
+ OS.gtk_signal_connect(control.handle, dragLeaveB, dragLeaveAddress, 0);
+
+ // Drag Data Received Callback
+ dragDataReceived = new Callback(this, "dragDataReceived", 7);
+ dragDataReceivedAddress = dragDataReceived.getAddress();
+ byte[] DataReceivedB = Converter.wcsToMbcs(null, "drag_data_received", true);
+ OS.gtk_signal_connect(control.handle, DataReceivedB, dragDataReceivedAddress, 0);
+
+ // Dispose listeners
+ controlListener = new Listener(){
+ public void handleEvent(Event event){
+ DropTarget.this.dispose();
+ }
+ };
+ control.addListener(SWT.Dispose, controlListener);
+ this.addListener(SWT.Dispose, new Listener(){
+ public void handleEvent(Event event){
+ DropTarget.this.onDispose();
+ }
+ });
+
+ // Drag under effect
+ if (control instanceof Tree) {
+ effect = new TreeDragUnderEffect((Tree)control);
+ } else if (control instanceof Table) {
+ effect = new TableDragUnderEffect((Table)control);
+ } else {
+ effect = new NoDragUnderEffect(control);
+ }
+}
+
+/**
+ * Adds the listener to receive events.
+ *
+ * @param listener the listener
+ *
+ * @exception SWTError
+ * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * <li>ERROR_NULL_ARGUMENT when listener is null</li></ul>
+ */
+public void addDropListener(DropTargetListener listener) {
+ if (listener == null) DND.error (SWT.ERROR_NULL_ARGUMENT);
+ DNDListener typedListener = new DNDListener (listener);
+ addListener (DND.DragEnter, typedListener);
+ addListener (DND.DragLeave, typedListener);
+ addListener (DND.DragOver, typedListener);
+ addListener (DND.DragOperationChanged, typedListener);
+ addListener (DND.Drop, typedListener);
+ addListener (DND.DropAccept, typedListener);
+}
+
+static int checkStyle (int style) {
+ if (style == SWT.NONE) return DND.DROP_MOVE;
+ return style;
+}
+
+int dragDataReceived ( int widget, int context, int x, int y, int data, int info, int time){
+ if (data == 0) return 0;
+ GtkSelectionData gtkSelectionData = new GtkSelectionData( data );
+ if (context == 0) return 0;
+ GdkDragContext dragContext = new GdkDragContext( context );
+
+ if (gtkSelectionData.data == 0) return 0;
+
+ TransferData tdata = new TransferData ();
+ tdata.type = info;
+ tdata.length = gtkSelectionData.length;
+ tdata.pValue = gtkSelectionData.data;
+
+ Point coordinates = new Point( x, y );
+ coordinates = control.toDisplay( coordinates );
+
+ int[] act = getCurrentOperation(context);
+
+ DNDEvent event = new DNDEvent();
+ event.widget = this;
+ event.x = coordinates.x;
+ event.y = coordinates.y;
+ event.time = time;
+ event.detail = act[0];
+ event.operations = act[1];
+ event.dataType = tdata;
+ event.dataTypes = new TransferData[] { tdata }; //looks bad, but the dataType cann't be changed at this step anyway
+ notifyListeners(DND.DropAccept, event);
+
+ /* NOTE: GTK do not provided a way to choose the typedata just before the drop */
+
+
+ if (event.detail == DND.DROP_NONE) {
+ OS.gtk_drag_finish(context, false, false, time); // It's Useless
+// OS.gdk_drag_abort(context, time); // can not be used in this callback (GP)
+ return 0;
+ }
+
+ Transfer transfer = null;
+ for (int i = 0; i < transfers.length; i++) {
+ transfer = transfers[i];
+ if (transfer.isSupportedType(tdata)) break;
+ }
+ if (transfer == null) return 0;
+
+ Object value = transfer.nativeToJava(tdata);
+
+ event = new DNDEvent();
+ event.widget = this;
+ event.x = coordinates.x;
+ event.y = coordinates.y;
+ event.detail = act[0];
+ event.operations = act[1];
+ event.time = time;
+ event.dataType = tdata;
+ event.data = value;
+ this.notifyListener(DND.Drop, event);
+
+ OS.gtk_drag_finish(context, true, dragContext.action == OS.GDK_ACTION_MOVE, time);
+ return 1;
+}
+
+int dragLeave ( int widget, int context, int time){
+ int[] act = getCurrentOperation(context);
+ DNDEvent event = new DNDEvent();
+ event.widget = this;
+ event.time = time;
+ event.x = lastX;
+ event.y = lastY;
+ event.dataType = getTransferData(context);
+ event.dataTypes = new TransferData[] { event.dataType }; //BAD
+ event.detail = act[0];
+ event.operations = act[1];
+ notifyListeners(DND.DragLeave, event);
+ isEnter = true;
+ return 1;
+}
+
+int dragMotion ( int widget, int context, int x, int y, int time){
+ DNDEvent event = new DNDEvent();
+ int[] act = getCurrentOperation(context);
+ Point coordinates = control.toDisplay( new Point( x, y) );
+ event.widget = this;
+ event.x = coordinates.x;
+ event.y = coordinates.y;
+ event.dataType = getTransferData(context);
+ event.dataTypes = new TransferData[] { event.dataType }; //BAD
+ event.detail = act[0];
+ event.operations = act[1];
+ event.time = time;
+ event.feedback = DND.FEEDBACK_NONE;
+
+ // to be used in dragleave
+ lastX = event.x;
+ lastY = event.y;
+
+ int type = DND.DragOver;
+ if(isEnter){
+ type = DND.DragEnter;
+ isEnter = false;
+ } else {
+ if ( lastOperation != -1 && event.detail != lastOperation ) {
+ type = DND.DragOperationChanged;
+ }
+ }
+ lastOperation = event.detail;
+
+ notifyListeners(type, event);
+
+ effect.show( event.feedback, coordinates.x, coordinates.y);
+
+ if (event.detail == DND.DROP_NONE) {
+ // Does not work properly, do not send drag_end signal for the source side
+ OS.gdk_drag_abort(context, time);
+ return 0;
+ }
+
+ return 1;
+}
+
+private int getActions(){
+ int style = getStyle();
+ int operationsDnd = 0;
+ if ( (style & DND.DROP_MOVE) != 0) operationsDnd |= OS.GDK_ACTION_MOVE;
+ if ( (style & DND.DROP_COPY) != 0) operationsDnd |= OS.GDK_ACTION_COPY;
+ if ( (style & DND.DROP_LINK) != 0) operationsDnd |= OS.GDK_ACTION_LINK;
+ return operationsDnd;
+}
+
+/**
+ * Returns the Control which is registered for this DropTarget. This is the control over which the
+ * user positions the cursor to drop the data.
+ *
+ * @return the Control which is registered for this DropTarget
+ *
+ */
+public Control getControl () {
+ return control;
+}
+
+/**
+ * @return int[] length equals 2,
+ * index 0 holds the currentAction
+ * index 1 holds a bitwise of all possible actions
+ *
+ */
+private int[] getCurrentOperation(int context){
+ if(context == 0) return new int[]{ DND.DROP_MOVE, DND.DROP_MOVE};
+ GdkDragContext dragContext = new GdkDragContext(context);
+
+ int action = DND.DROP_MOVE;
+ if(dragContext.action == OS.GDK_ACTION_COPY) action = DND.DROP_COPY;
+ if(dragContext.action == OS.GDK_ACTION_LINK) action = DND.DROP_LINK;
+
+ int actions = 0;
+ if((dragContext.actions & OS.GDK_ACTION_MOVE) != 0) actions |= DND.DROP_MOVE;
+ if((dragContext.actions & OS.GDK_ACTION_COPY) != 0) actions |= DND.DROP_COPY;
+ if((dragContext.actions & OS.GDK_ACTION_LINK) != 0) actions |= DND.DROP_LINK;
+
+ return new int[] {action, actions};
+}
+
+public Display getDisplay () {
+ if (control == null) DND.error(SWT.ERROR_WIDGET_DISPOSED);
+ return control.getDisplay ();
+}
+
+/**
+ * Returns the list of data types that can be transferred to this DropTarget.
+ *
+ * @return the list of data types that can be transferred to this DropTarget
+ *
+ */
+public Transfer[] getTransfer() {
+ return transfers;
+}
+
+private TransferData getTransferData(int context){
+ TransferData tdata = new TransferData();
+ if ( context == 0) return tdata;
+ GdkDragContext dragContext = new GdkDragContext(context);
+ int atom = OS.gtk_drag_dest_find_target(control.handle, context, 0);
+ int ptr = OS.gdk_atom_name(atom);
+ int len = OS.strlen(ptr);
+ byte[] buffer = new byte [ len ];
+ OS.memmove(buffer, ptr, len);
+ String formatname = new String ( Converter.mbcsToWcs(null, buffer) );
+ tdata.type = Transfer.registerType(formatname); // Lazy way
+ return tdata;
+}
+
+public void notifyListener (int eventType, Event event) {
+ Point coordinates = new Point(event.x, event.y);
+ coordinates = control.toControl(coordinates);
+ if (this.control instanceof Tree) {
+ event.item = ((Tree)control).getItem(coordinates);
+ }
+ if (this.control instanceof Table) {
+ event.item = ((Table)control).getItem(coordinates);
+ }
+ super.notifyListeners(eventType, event);
+}
+
+private void onDispose(){
+ if (dragMotion != null )
+ dragMotion.dispose();
+ dragMotion = null;
+
+ if (dragDataReceived != null )
+ dragDataReceived.dispose();
+ dragDataReceived = null;
+
+ if (dragLeave!= null )
+ dragLeave.dispose();
+ dragLeave = null;
+
+ if (control != null){
+ OS.gtk_drag_dest_unset(control.handle);
+ if (controlListener != null)
+ control.removeListener(SWT.Dispose, controlListener);
+ }
+
+ releaseTargets();
+ control = null;
+ controlListener = null;
+}
+
+private void releaseTargets(){
+
+ if ( targets != null ) {
+ for (int i = 0; i < targets.length; i++) {
+ GtkTargetEntry entry = targets[i];
+ if( entry.target != 0) OS.g_free(entry.target);
+ }
+ }
+
+ if (targets_list != 0) {
+ OS.g_free(targets_list);
+ }
+
+ targets_list = 0;
+ targets = null;
+}
+
+/**
+ * Removes the listener.
+ *
+ * @param listener the listener
+ *
+ * @exception SWTError
+ * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * <li>ERROR_NULL_ARGUMENT when listener is null</li></ul>
+ */
+public void removeDropListener(DropTargetListener listener) {
+ if (listener == null) DND.error (SWT.ERROR_NULL_ARGUMENT);
+ removeListener (DND.DragEnter, listener);
+ removeListener (DND.DragLeave, listener);
+ removeListener (DND.DragOver, listener);
+ removeListener (DND.DragOperationChanged, listener);
+ removeListener (DND.Drop, listener);
+ removeListener (DND.DropAccept, listener);
+}
+
+private void setTargetList(){
+
+ if (transfers == null) return;
+ if (control == null) return;
+
+ //Release previous allocates data (remember)
+
+ int n_entry = 0;
+ GtkTargetEntry[] entrys = new GtkTargetEntry [n_entry];
+
+
+ Transfer[] transferAgents = transfers;
+ for (int i = 0; i < transferAgents.length; i++) {
+ Transfer transfer = transferAgents[i];
+ int[] types = transfer.getTypeIds();
+ for (int j = 0; j < types.length; j++) {
+ int type = types[j];
+ String typename = transfer.getTypeNames()[j];
+ byte[] buffer = Converter.wcsToMbcs(null, typename, true);
+ int ptr = OS.g_malloc(buffer.length);
+ OS.memmove(ptr, buffer, buffer.length);
+
+ GtkTargetEntry entry = new GtkTargetEntry();
+ entry.target = ptr;
+ entry.info = type;
+
+ GtkTargetEntry[] tmp = new GtkTargetEntry [n_entry + 1];
+ System.arraycopy(entrys, 0, tmp, 0, n_entry);
+ tmp[ n_entry ] = entry;
+ entrys = tmp;
+ n_entry++;
+ }
+ }
+
+ byte[] buffer = new byte[ GtkTargetEntry.sizeof * n_entry ];
+ byte[] tmp = new byte[ GtkTargetEntry.sizeof ];
+ for (int i = 0; i < n_entry; i++) {
+ OS.memmove(tmp, entrys[i], GtkTargetEntry.sizeof);
+ System.arraycopy(tmp, 0, buffer, i * GtkTargetEntry.sizeof, tmp.length);
+ }
+
+ transferDatas = new TransferData[entrys.length];
+ for (int i = 0; i < transferDatas.length; i++) {
+ TransferData td = new TransferData();
+ td.type = entrys[i].target;
+ transferDatas[i] = td;
+ }
+
+ if (targets_list != 0){
+ OS.gtk_drag_dest_unset(control.handle);
+ }
+
+ targets_list = OS.g_malloc(buffer.length);
+ OS.memmove(targets_list, buffer, buffer.length);
+ targets = entrys;
+
+ OS.gtk_drag_dest_set(control.handle, OS.GTK_DEST_DEFAULT_ALL, targets_list, n_entry, getActions());
+
+}
+
+/**
+ * Specifies the list of data types that can be transferred to this DropTarget.
+ *
+ * @param transferAgents a list of Transfer objects which define the types of data that can be
+ * dropped on this target
+ */
+public void setTransfer(Transfer[] transferAgents){
+ if (transferAgents == null) DND.error(SWT.ERROR_NULL_ARGUMENT);
+ this.transfers = transferAgents;
+ setTargetList();
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/FileTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/FileTransfer.java
new file mode 100644
index 0000000..d792b76
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/FileTransfer.java
@@ -0,0 +1,104 @@
+package org.eclipse.swt.dnd;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.internal.Converter;
+import org.eclipse.swt.internal.gtk.OS;
+
+/**
+ * The <code>FileTransfer</code> class is used to transfer files in a drag and drop operation.
+ */
+public class FileTransfer extends ByteArrayTransfer {
+
+ private static final FileTransfer _instance = new FileTransfer();
+ private static final String TYPENAME = "text/uri-list";
+ private static final int TYPEID = Transfer.registerType(TYPENAME);
+
+private FileTransfer() {}
+/**
+ * Returns the singleton instance of the FileTransfer class.
+ *
+ * @return the singleton instance of the FileTransfer class
+ */
+public static FileTransfer getInstance () {
+ return _instance;
+}
+/**
+ * Converts a list of filenames to a platform specific representation.
+ * <p>
+ * On a successful conversion, the transferData.result field will be set as follows:
+ * <ul>
+ * <li>Windows: OLE.S_OK
+ * <li>Motif: 0
+ * </ul>
+ * If this transfer agent is unable to perform the conversion,
+ * the transferData.result field will be set to a failure value as follows:
+ * <ul>
+ * <li>Windows: OLE.DV_E_TYMED
+ * <li>Motif: 1
+ * </ul></p>
+ *
+ * @param object a list of file names
+ * @param transferData an empty TransferData object; this object will be filled in on return
+ * with the platform specific format of the data
+ */
+public void javaToNative(Object object, TransferData transferData) {
+ if (object == null || !(object instanceof String[])) return;
+
+ // build a byte array from data
+ String[] files = (String[])object;
+
+ // create a string separated by "new lines" to represent list of files
+ String nativeFormat = "file:";
+ for (int i = 0, length = files.length; i < length; i++){
+ nativeFormat += files[i]+"\r";
+ }
+ nativeFormat += "\0";
+ // pass byte array on to super to convert to native
+ super.javaToNative(nativeFormat.getBytes(), transferData);
+}
+/**
+ * Converts a platform specific representation of a list of file names to a Java array of String.
+ *
+ * @param transferData the platform specific representation of the data that has been transferred
+ * @return a Java array of String containing a list of file names if the conversion was successful;
+ * otherwise null
+ */
+public Object nativeToJava(TransferData transferData) {
+
+ byte[] data = (byte[])super.nativeToJava(transferData);
+ if (data == null) return null;
+ String string = new String(data);
+ // parse data and convert string to array of files
+ int start = string.indexOf("file:");
+ if (start == -1) return null;
+ start += 5;
+ String[] fileNames = new String[0];
+ while (start < string.length()) {
+ int end = string.indexOf("\r", start);
+ if (end == -1) end = string.length() - 1;
+
+ String fileName = string.substring(start, end);
+ String[] newFileNames = new String[fileNames.length + 1];
+ System.arraycopy(fileNames, 0, newFileNames, 0, fileNames.length);
+ newFileNames[fileNames.length] = fileName;
+ fileNames = newFileNames;
+
+ start = string.indexOf("file:", end);
+ if (start == -1) break;
+ start += 5;
+ }
+ return fileNames;
+}
+
+protected String[] getTypeNames(){
+ return new String[]{TYPENAME};
+}
+protected int[] getTypeIds(){
+ return new int[]{TYPEID};
+}
+}
+
\ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/RTFTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/RTFTransfer.java
new file mode 100644
index 0000000..8baed20
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/RTFTransfer.java
@@ -0,0 +1,80 @@
+package org.eclipse.swt.dnd;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.internal.Converter;
+import org.eclipse.swt.internal.gtk.OS;
+
+/**
+ * The <code>RTFTransfer</code> class is used to transfer text with the RTF format
+ * in a drag and drop operation.
+ */
+public class RTFTransfer extends ByteArrayTransfer {
+
+ private static RTFTransfer _instance = new RTFTransfer();
+ private static final String TYPENAME1 = "text/rtf";
+ private static final int TYPEID1 = registerType(TYPENAME1);
+ private static final String TYPENAME2 = "TEXT/RTF";
+ private static final int TYPEID2 = registerType(TYPENAME2);
+ private static final String TYPENAME3 = "application/rtf";
+ private static final int TYPEID3 = registerType(TYPENAME3);
+
+private RTFTransfer() {
+}
+/**
+ * Returns the singleton instance of the RTFTransfer class.
+ *
+ * @return the singleton instance of the RTFTransfer class
+ */
+public static RTFTransfer getInstance () {
+ return _instance;
+}
+/**
+ * Converts a RTF-formatted Java String to a platform specific representation.
+ * <p>
+ * On a successful conversion, the transferData.result field will be set as follows:
+ * <ul>
+ * <li>Windows: OLE.S_OK
+ * <li>Motif: 0
+ * </ul>
+ * If this transfer agent is unable to perform the conversion,
+ * the transferData.result field will be set to a failure value as follows:
+ * <ul>
+ * <li>Windows: OLE.DV_E_TYMED
+ * <li>Motif: 1
+ * </ul></p>
+ *
+ * @param object a Java String containing the data to be transferred
+ * @param transferData an empty TransferData object; this object will be filled in on return
+ * with the platform specific format of the data
+ */
+public void javaToNative (Object object, TransferData transferData){
+ if (object == null || !(object instanceof String)) return;
+ byte [] buffer = Converter.wcsToMbcs (null, (String)object, true);
+ super.javaToNative(buffer, transferData);
+}
+/**
+ * Converts a platform specific representation of a string to a Java String.
+ *
+ * @param transferData the platform specific representation of the data that has been transferred
+ * @return a Java String containing the transferred data if the conversion was successful;
+ * otherwise null
+ */
+public Object nativeToJava(TransferData transferData){
+ if ( !isSupportedType(transferData) || transferData.pValue == 0 ) return null;
+ if (transferData.length <=0) transferData.length = OS.strlen(transferData.pValue);
+ byte[] buffer = (byte[]) super.nativeToJava(transferData);
+ if (buffer == null) return null;
+ char [] unicode = Converter.mbcsToWcs (null, buffer);
+ return new String (unicode);
+}
+protected String[] getTypeNames(){
+ return new String[]{TYPENAME1, TYPENAME2, TYPENAME3};
+}
+protected int[] getTypeIds(){
+ return new int[]{TYPEID1, TYPEID2, TYPEID3};
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragUnderEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragUnderEffect.java
new file mode 100644
index 0000000..7b9e962
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragUnderEffect.java
@@ -0,0 +1,101 @@
+package org.eclipse.swt.dnd;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+class TableDragUnderEffect extends DragUnderEffect {
+ private Table table;
+ private TableItem[] selection = new TableItem[0];
+ private int currentEffect = DND.FEEDBACK_NONE;
+ private TableItem dropSelection;
+ private TableItem scrollItem;
+ private long scrollBeginTime;
+ private static final int SCROLL_HYSTERESIS = 400; // milli seconds
+ private static final int SCROLL_WIDTH = 100; // pixels
+
+TableDragUnderEffect(Table table) {
+ this.table = table;
+}
+void show(int effect, int x, int y) {
+ TableItem item = findItem(x, y);
+ if (item == null) effect = DND.FEEDBACK_NONE;
+ if (currentEffect == DND.FEEDBACK_NONE && effect != DND.FEEDBACK_NONE) {
+ selection = table.getSelection();
+ table.deselectAll();
+ }
+ scrollHover(effect, item, x, y);
+ setDragUnderEffect(effect, item);
+ if (currentEffect != DND.FEEDBACK_NONE && effect == DND.FEEDBACK_NONE) {
+ table.setSelection(selection);
+ selection = new TableItem[0];
+ }
+ currentEffect = effect;
+}
+private TableItem findItem(int x, int y){
+ if (table == null) return null;
+ Point coordinates = new Point(x, y);
+ coordinates = table.toControl(coordinates);
+ TableItem item = table.getItem(coordinates);
+ if (item != null) return item;
+
+ Rectangle area = table.getClientArea();
+ for (int x1 = area.x; x1 < area.x + area.width; x1++) {
+ coordinates = new Point(x1, y);
+ coordinates = table.toControl(coordinates);
+ item = table.getItem(coordinates);
+ if (item != null) return item;
+ }
+ return null;
+}
+private void setDragUnderEffect(int effect, TableItem item) {
+ if ((effect & DND.FEEDBACK_SELECT) != 0) {
+ setDropSelection(item);
+ return;
+ }
+ if ((currentEffect & DND.FEEDBACK_SELECT) != 0) setDropSelection(null);
+}
+private void setDropSelection (TableItem item) {
+ if (item == dropSelection) return;
+ if (dropSelection != null) table.deselectAll();
+ dropSelection = item;
+ if (dropSelection != null) table.setSelection(new TableItem[]{dropSelection});
+}
+private void scrollHover (int effect, TableItem item, int x, int y) {
+ if ((effect & DND.FEEDBACK_SCROLL) == 0) {
+ scrollBeginTime = 0;
+ scrollItem = null;
+ return;
+ }
+ if (scrollItem == item && scrollBeginTime != 0) {
+ if (System.currentTimeMillis() >= scrollBeginTime) {
+ scroll(item, x, y);
+ scrollBeginTime = 0;
+ scrollItem = null;
+ }
+ return;
+ }
+ scrollBeginTime = System.currentTimeMillis() + SCROLL_HYSTERESIS;
+ scrollItem = item;
+}
+private void scroll(TableItem item, int x, int y) {
+ if (item == null) return;
+ Point coordinates = new Point(x, y);
+ coordinates = table.toControl(coordinates);
+ Rectangle area = table.getClientArea();
+ TableItem showItem = null;
+ int itemIndex = table.indexOf(item);
+ if (coordinates.y - area.y < SCROLL_WIDTH) {
+ showItem = table.getItem(Math.max(0, itemIndex - 1));
+ } else if ((area.y + area.height - coordinates.y) < SCROLL_WIDTH) {
+ showItem = table.getItem(Math.min(table.getItemCount() - 1, itemIndex + 1));
+ }
+ if (showItem != null) {
+ table.showItem(showItem);
+ }
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TextTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TextTransfer.java
new file mode 100644
index 0000000..4ee2647
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TextTransfer.java
@@ -0,0 +1,79 @@
+package org.eclipse.swt.dnd;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.internal.Converter;
+import org.eclipse.swt.internal.gtk.OS;
+
+/**
+ * The <code>TextTransfer</code> class is used to transfer text in a drag and drop operation.
+ */
+public class TextTransfer extends ByteArrayTransfer {
+
+ private static TextTransfer _instance = new TextTransfer();
+ private static final String TYPENAME1 = "STRING";
+ private static final int TYPEID1 = registerType(TYPENAME1);
+ private static final String TYPENAME2 = "text/plain";
+ private static final int TYPEID2 = registerType(TYPENAME2);
+ private static final String TYPENAME3 = "text/text";
+ private static final int TYPEID3 = registerType(TYPENAME3);
+
+private TextTransfer() {
+}
+/**
+ * Returns the singleton instance of the TextTransfer class.
+ *
+ * @return the singleton instance of the TextTransfer class
+ */
+public static TextTransfer getInstance () {
+ return _instance;
+}
+/**
+ * Converts a plain text Java String to a platform specific representation.
+ * <p>
+ * On a successful conversion, the transferData.result field will be set as follows:
+ * <ul>
+ * <li>Windows: OLE.S_OK
+ * <li>Motif: 0
+ * </ul>
+ * If this transfer agent is unable to perform the conversion,
+ * the transferData.result field will be set to a failure value as follows:
+ * <ul>
+ * <li>Windows: OLE.DV_E_TYMED
+ * <li>Motif: 1
+ * </ul></p>
+ *
+ * @param object a Java String containing the data to be transferred
+ * @param transferData an empty TransferData object; this object will be filled in on return
+ * with the platform specific format of the data
+ */
+public void javaToNative (Object object, TransferData transferData){
+ if (object == null || !(object instanceof String)) return;
+ byte [] buffer = Converter.wcsToMbcs (null, (String)object, true);
+ super.javaToNative(buffer, transferData);
+}
+/**
+ * Converts a platform specific representation of a string to a Java String.
+ *
+ * @param transferData the platform specific representation of the data that has been transferred
+ * @return a Java String containing the transferred data if the conversion was successful;
+ * otherwise null
+ */
+public Object nativeToJava(TransferData transferData){
+ if ( !isSupportedType(transferData) || transferData.pValue == 0 ) return null;
+ if (transferData.length <=0) transferData.length = OS.strlen(transferData.pValue);
+ byte[] buffer = (byte[]) super.nativeToJava(transferData);
+ char [] unicode = Converter.mbcsToWcs (null, buffer);
+ return new String (unicode);
+}
+
+protected String[] getTypeNames(){
+ return new String[]{TYPENAME1, TYPENAME2, TYPENAME3};
+}
+protected int[] getTypeIds(){
+ return new int[]{TYPEID1, TYPEID2, TYPEID3};
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/Transfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/Transfer.java
new file mode 100644
index 0000000..253f50e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/Transfer.java
@@ -0,0 +1,58 @@
+package org.eclipse.swt.dnd;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.internal.Converter;
+import org.eclipse.swt.internal.gtk.OS;
+
+/**
+ * The class <code>Transfer</code> provides a mechanism for converting a Java object to a
+ * platform specific format that can be passed around in a Drag and Drop operation and vice versa.
+ *
+ * <p>You should only need to become familiar with this class if you are implementing
+ * a Transfer subclass and you are unable to subclass the ByteArrayTransfer class.</p>
+ */
+public abstract class Transfer {
+/**
+ * Returns a list of the data types that can be transferred using this Transfer agent.
+ *
+ * <p>Only the data type fields of the TransferData Object are filled in.</p>
+ *
+ * @return a list of the data types that can be transferred using this Transfer agent
+ */
+abstract public TransferData[] getSupportedTypes();
+/**
+ * Returns true if the transferData data type can be transferred using this Transfer agent.
+ *
+ * @param transferData a platform specific description of a data type; only the data type fields
+ * of the TransferData Object need to be filled in
+ *
+ * @return true if the transferData data type can be transferred using this Transfer agent
+ */
+abstract public boolean isSupportedType(TransferData transferData);
+abstract protected String[] getTypeNames();
+abstract protected int[] getTypeIds();
+abstract protected void javaToNative (Object object, TransferData transferData);
+abstract protected Object nativeToJava(TransferData transferData);
+/**
+ * Registers a name for a data type and returns the associated unique identifier.
+ *
+ * <p>You may register the same type more than once, the same unique identifier will be returned if the
+ * type has been previously registered.</p>
+ *
+ * <p>Note: Do <b>not</b> call this method with pre-defined Clipboard Format types such as CF_TEXT
+ * or CF_BITMAP because the pre-defined value will not be returned</p>
+ *
+ * @param formatName the name of a data type
+ *
+ * @return the unique identifier associated with this data type
+ */
+public static int registerType(String formatName){
+ if (formatName == null) return OS.GDK_NONE;
+ byte[] buffer = Converter.wcsToMbcs(null, formatName, true);
+ return OS.gdk_atom_intern(buffer, 0);
+}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TransferData.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TransferData.java
new file mode 100644
index 0000000..64a8c75
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TransferData.java
@@ -0,0 +1,35 @@
+package org.eclipse.swt.dnd;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+/**
+ * The <code>TransferData</code> class is a platform specific data structure for describing the type and the
+ * contents of data being transferred in a Drag and Drop operation.
+ *
+ * <p>As an application writer, you do not need to know anything about the specifics of TransferData. You
+ * should just pass the TransferData instances to subclass of Transfer and let the Transfer objects deal
+ * with the platform specific issues. You can ask a Transfer subclass if it can handle this data by calling
+ * TextTransfer.isSupportedType(transferData). You can get a list of the types of TransferData supported by a
+ * Transfer object by calling TextTransfer.getSupportedTypes().</p>
+ *
+ * <p>You should only need to become familiar with the fields in this class if you are implementing
+ * a Transfer subclass and you are unable to subclass the ByteArrayTransfer class.</p>
+ */
+public class TransferData {
+ /**
+ * Data Type - a pre-defined clipboard format <b>or</b> the unique identifier of a user defined format
+ * (Warning: This field is platform dependent)
+ */
+ public int type;
+
+ // attributes specific to set/get
+ int length;
+ int format;
+ int pValue;
+
+ int result;
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragUnderEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragUnderEffect.java
new file mode 100644
index 0000000..9698a3a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragUnderEffect.java
@@ -0,0 +1,214 @@
+package org.eclipse.swt.dnd;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.SWT;
+
+class TreeDragUnderEffect extends DragUnderEffect {
+
+ private Tree tree;
+ private int currentEffect = DND.FEEDBACK_NONE;
+ private TreeItem[] selection = new TreeItem[0];
+ private TreeItem dropSelection = null;
+ private TreeItem insertMark = null;
+ private boolean insertBefore = false;
+
+ private TreeItem scrollItem;
+ private long scrollBeginTime;
+ private static final int SCROLL_HYSTERESIS = 400; // milli seconds
+ private static final int SCROLL_WIDTH = 100; // pixels
+
+ private TreeItem expandItem;
+ private long expandBeginTime;
+ private static final int EXPAND_HYSTERESIS = 1000; // milli seconds
+
+TreeDragUnderEffect(Tree tree) {
+ this.tree = tree;
+}
+void show(int effect, int x, int y) {
+ effect = checkEffect(effect);
+ TreeItem item = findItem(x, y);
+ if (item == null) effect = DND.FEEDBACK_NONE;
+ if (currentEffect == DND.FEEDBACK_NONE && effect != DND.FEEDBACK_NONE) {
+ selection = tree.getSelection();
+ tree.deselectAll();
+ }
+ scrollHover(effect, item, x, y);
+ expandHover(effect, item, x, y);
+ setDragUnderEffect(effect, item);
+ if (currentEffect != DND.FEEDBACK_NONE && effect == DND.FEEDBACK_NONE) {
+ tree.setSelection(selection);
+ selection = new TreeItem[0];
+ }
+ currentEffect = effect;
+}
+private int checkEffect(int effect) {
+ // Some effects are mutually exclusive. Make sure that only one of the mutually exclusive effects has been specified.
+ int mask = DND.FEEDBACK_INSERT_AFTER | DND.FEEDBACK_INSERT_BEFORE | DND.FEEDBACK_SELECT;
+ int bits = effect & mask;
+ if (bits == DND.FEEDBACK_INSERT_AFTER || bits == DND.FEEDBACK_INSERT_BEFORE || bits == DND.FEEDBACK_SELECT) return effect;
+ return (effect & ~mask);
+}
+private TreeItem findItem(int x , int y){
+ Point coordinates = new Point(x, y);
+ coordinates = tree.toControl(coordinates);
+ Rectangle area = tree.getClientArea();
+ if (!area.contains(coordinates)) return null;
+
+ TreeItem item = tree.getItem(coordinates);
+ if (item != null) return item;
+
+ // Scan across the width of the tree.
+ for (int x1 = area.x; x1 < area.x + area.width; x1++) {
+ coordinates = new Point(x1, coordinates.y);
+ item = tree.getItem(coordinates);
+ if (item != null) return item;
+ }
+ // Check if we are just below the last item of the tree
+ coordinates = new Point(x, y);
+ coordinates = tree.toControl(coordinates);
+ if (coordinates.y > area.y + area.height - tree.getItemHeight()) {;
+ int y1 = area.y + area.height - tree.getItemHeight();
+ coordinates = new Point(coordinates.x, y1);
+
+ item = tree.getItem(coordinates);
+ if (item != null) return item;
+
+ // Scan across the width of the tree just above the bottom..
+ for (int x1 = area.x; x1 < area.x + area.width; x1++) {
+ coordinates = new Point(x1, y1);
+ item = tree.getItem(coordinates);
+ if (item != null) return item;
+ }
+ }
+ return null;
+}
+private void setDragUnderEffect(int effect, TreeItem item) {
+ if ((effect & DND.FEEDBACK_SELECT) != 0) {
+ if ((currentEffect & DND.FEEDBACK_INSERT_AFTER) != 0 ||
+ (currentEffect & DND.FEEDBACK_INSERT_BEFORE) != 0) {
+// tree.setInsertMark(null, false);
+ }
+ setDropSelection(item);
+ return;
+ }
+ if ((effect & DND.FEEDBACK_INSERT_AFTER) != 0 ||
+ (effect & DND.FEEDBACK_INSERT_BEFORE) != 0) {
+ if ((currentEffect & DND.FEEDBACK_SELECT) != 0) {
+ setDropSelection(null);
+ }
+ setInsertMark(item, (effect & DND.FEEDBACK_INSERT_BEFORE) != 0);
+ return;
+ }
+
+ setInsertMark(null, false);
+ setDropSelection(null);
+}
+private void setDropSelection (TreeItem item) {
+ if (item == dropSelection) return;
+ if (dropSelection != null) tree.deselectAll();
+ dropSelection = item;
+ if (dropSelection != null) tree.setSelection(new TreeItem[]{dropSelection});
+}
+private void setInsertMark(TreeItem item, boolean before) {
+ if (item == insertMark && before == insertBefore) return;
+ insertMark = item;
+ insertBefore = before;
+// tree.setInsertMark(item, before);
+}
+private void scrollHover (int effect, TreeItem item, int x, int y) {
+ if ((effect & DND.FEEDBACK_SCROLL) == 0) {
+ scrollBeginTime = 0;
+ scrollItem = null;
+ return;
+ }
+ if (scrollItem == item && scrollBeginTime != 0) {
+ if (System.currentTimeMillis() >= scrollBeginTime) {
+ scroll(item, x, y);
+ scrollBeginTime = 0;
+ scrollItem = null;
+ }
+ return;
+ }
+ scrollBeginTime = System.currentTimeMillis() + SCROLL_HYSTERESIS;
+ scrollItem = item;
+}
+private void scroll(TreeItem item, int x, int y) {
+ if (item == null) return;
+ Point coordinates = new Point(x, y);
+ coordinates = tree.toControl(coordinates);
+ Rectangle area = tree.getClientArea();
+ TreeItem showItem = null;
+ if (coordinates.y - area.y < SCROLL_WIDTH) {
+ showItem = getPreviousVisibleItem(item);
+ } else if ((area.y + area.height - coordinates.y) < SCROLL_WIDTH) {
+ showItem = getNextVisibleItem(item, true);
+ }
+ if (showItem != null) {
+ tree.showItem(showItem);
+ }
+}
+private void expandHover (int effect, TreeItem item, int x, int y) {
+ if ((effect & DND.FEEDBACK_EXPAND) == 0) {
+ expandBeginTime = 0;
+ expandItem = null;
+ return;
+ }
+ if (expandItem == item && expandBeginTime != 0) {
+ if (System.currentTimeMillis() >= expandBeginTime) {
+ expand(item, x, y);
+ expandBeginTime = 0;
+ expandItem = null;
+ }
+ return;
+ }
+ expandBeginTime = System.currentTimeMillis() + EXPAND_HYSTERESIS;
+ expandItem = item;
+}
+private void expand(TreeItem item, int x, int y) {
+ if (item == null || item.getExpanded()) return;
+ Event event = new Event();
+ event.x = x;
+ event.y = y;
+ event.item = item;
+ event.time = (int) System.currentTimeMillis();
+ tree.notifyListeners(SWT.Expand, event);
+ if (item.isDisposed()) return;
+ item.setExpanded(true);
+}
+private TreeItem getNextVisibleItem(TreeItem item, boolean includeChildren) {
+ // look down
+ // neccesary on the first pass only
+ if (includeChildren && item.getItemCount() > 0 && item.getExpanded()) {
+ return item.getItems()[0];
+ }
+ // look sideways
+ TreeItem parent = item.getParentItem();
+ TreeItem[] peers = (parent != null) ? parent.getItems() : tree.getItems();
+ for (int i = 0; i < peers.length - 1; i++) {
+ if (peers[i] == item) return peers[i + 1];
+ }
+ // look up
+ if (parent != null) return getNextVisibleItem(parent, false);
+ return null;
+}
+private TreeItem getPreviousVisibleItem(TreeItem item) {
+ // look sideways
+ TreeItem parent = item.getParentItem();
+ TreeItem[] peers = (parent != null) ? parent.getItems() : tree.getItems();
+ for (int i = peers.length - 1; i > 0; i--) {
+ if (peers[i] == item) {
+ TreeItem peer = peers[i-1];
+ if (!peer.getExpanded() || peer.getItemCount() == 0) return peer;
+ TreeItem[] peerItems = peer.getItems();
+ return peerItems[peerItems.length - 1];
+ }
+ }
+ // look up
+ return parent;
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/ByteArrayTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/ByteArrayTransfer.java
index 13155b4..633c288 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/ByteArrayTransfer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/ByteArrayTransfer.java
@@ -5,7 +5,7 @@
* All Rights Reserved
*/
-import org.eclipse.swt.internal.motif.*;
+import org.eclipse.swt.internal.motif.OS;
/**
* The class <code>ByteArrayTransfer</code> provides a platform specific mechanism for transforming
@@ -37,18 +37,18 @@
}
protected void javaToNative (Object object, TransferData transferData){
if ((object == null) || !(object instanceof byte[]) || !(isSupportedType(transferData))) {
- transferData.result = 0;
+ if ( transferData != null ) transferData.result = 0;
return;
}
byte[] buffer = (byte[])object;
- transferData.pValue = OS.XtMalloc(buffer.length + 1);
+ transferData.pValue = OS.XtMalloc(buffer.length);
OS.memmove(transferData.pValue, buffer, buffer.length);
transferData.length = buffer.length;
transferData.format = 8;
transferData.result = 1;
}
protected Object nativeToJava(TransferData transferData){
- if (transferData == null || transferData.pValue == 0 || !(isSupportedType(transferData))) return null;
+ if ( !(isSupportedType(transferData) || transferData.pValue == 0)) return null;
int size = transferData.format * transferData.length / 8;
byte[] buffer = new byte[size];
OS.memmove(buffer, transferData.pValue, size);
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 4bf7a12..a83d896 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
@@ -111,12 +111,9 @@
return result;
}
-public void setContents(Object[] data, Transfer[] transferAgents){
+public void setContents(Object[] data, Transfer[] dataTypes){
- if (data == null) {
- DND.error(SWT.ERROR_NOT_IMPLEMENTED);
- }
- if (transferAgents == null || data.length != transferAgents.length) {
+ if (data == null || dataTypes == null || data.length != dataTypes.length) {
DND.error(SWT.ERROR_INVALID_ARGUMENT);
}
@@ -141,15 +138,15 @@
DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD);
// copy data directly over to System clipboard (not deferred)
- for (int i = 0; i < transferAgents.length; i++) {
- String[] names = transferAgents[i].getTypeNames();
+ for (int i = 0; i < dataTypes.length; i++) {
+ String[] names = dataTypes[i].getTypeNames();
for (int j = 0; j < names.length; j++) {
TransferData transferData = new TransferData();
/* Use the character encoding for the default locale */
byte[] bName = Converter.wcsToMbcs (null, names[j], false);
transferData.type = OS.XmInternAtom (xDisplay, bName, false);
- transferAgents[i].javaToNative(data[i], transferData);
+ dataTypes[i].javaToNative(data[i], transferData);
status = OS.XmClipboardFail;
if (transferData.result == 1 && transferData.format == 8){
byte[] buffer = new byte[transferData.length];
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/FileTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/FileTransfer.java
index 0bda4b5..f749b42 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/FileTransfer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/FileTransfer.java
@@ -11,7 +11,7 @@
public class FileTransfer extends ByteArrayTransfer {
private static FileTransfer _instance = new FileTransfer();
- private static final String TYPENAME = "text/uri-list\0";
+ private static final String TYPENAME = "text/uri-list";
private static final int TYPEID = registerType(TYPENAME);
private FileTransfer() {}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/RTFTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/RTFTransfer.java
index f2b015d..a10e757 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/RTFTransfer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/RTFTransfer.java
@@ -12,11 +12,11 @@
public class RTFTransfer extends ByteArrayTransfer {
private static RTFTransfer _instance = new RTFTransfer();
- private static final String TYPENAME1 = "text/rtf\0";
+ private static final String TYPENAME1 = "text/rtf";
private static final int TYPEID1 = registerType(TYPENAME1);
- private static final String TYPENAME2 = "TEXT/RTF\0";
+ private static final String TYPENAME2 = "TEXT/RTF";
private static final int TYPEID2 = registerType(TYPENAME2);
- private static final String TYPENAME3 = "application/rtf\0";
+ private static final String TYPENAME3 = "application/rtf";
private static final int TYPEID3 = registerType(TYPENAME3);
private RTFTransfer() {
@@ -50,9 +50,8 @@
*/
public void javaToNative (Object object, TransferData transferData){
if (object == null || !(object instanceof String)) return;
-
- String text = (String)object;
- super.javaToNative(text.getBytes(), transferData);
+ byte [] buffer = Converter.wcsToMbcs (null, (String)object, true);
+ super.javaToNative(buffer, transferData);
}
/**
* Converts a platform specific representation of a string to a Java String.
@@ -66,7 +65,8 @@
byte[] buffer = (byte[])super.nativeToJava(transferData);
if (buffer == null) return null;
// convert byte array to a string
- return new String(buffer);
+ char [] unicode = Converter.mbcsToWcs (null, buffer);
+ return new String (unicode);
}
protected String[] getTypeNames(){
return new String[]{TYPENAME1, TYPENAME2, TYPENAME3};
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/TextTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/TextTransfer.java
index 93fb0cf..6120790 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/TextTransfer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/TextTransfer.java
@@ -11,11 +11,11 @@
public class TextTransfer extends ByteArrayTransfer {
private static TextTransfer _instance = new TextTransfer();
- private static final String TYPENAME1 = "STRING\0";
+ private static final String TYPENAME1 = "STRING";
private static final int TYPEID1 = registerType(TYPENAME1);
- private static final String TYPENAME2 = "text/plain\0";
+ private static final String TYPENAME2 = "text/plain";
private static final int TYPEID2 = registerType(TYPENAME2);
- private static final String TYPENAME3 = "text/text\0";
+ private static final String TYPENAME3 = "text/text";
private static final int TYPEID3 = registerType(TYPENAME3);
private TextTransfer() {
@@ -49,9 +49,8 @@
*/
public void javaToNative (Object object, TransferData transferData){
if (object == null || !(object instanceof String)) return;
-
- String text = (String)object;
- super.javaToNative(text.getBytes(), transferData);
+ byte [] buffer = Converter.wcsToMbcs (null, (String)object, true);
+ super.javaToNative(buffer, transferData);
}
/**
* Converts a platform specific representation of a string to a Java String.
@@ -65,7 +64,8 @@
byte[] buffer = (byte[])super.nativeToJava(transferData);
if (buffer == null) return null;
// convert byte array to a string
- return new String(buffer);
+ char [] unicode = Converter.mbcsToWcs (null, buffer);
+ return new String (unicode);
}
protected String[] getTypeNames(){
return new String[]{TYPENAME1, TYPENAME2, TYPENAME3};
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/Transfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/Transfer.java
index adfd307..ec816ae 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/Transfer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/motif/org/eclipse/swt/dnd/Transfer.java
@@ -49,14 +49,12 @@
*
* @param formatName the name of a data type
*
- * @return the unique identifier associated with htis data type
+ * @return the unique identifier associated with this data type
*/
public static int registerType(String formatName){
-
int xDisplay = Display.getDefault().xDisplay; // using default because we don't have a particular widget
/* Use the character encoding for the default locale */
- byte[] bName = Converter.wcsToMbcs (null, formatName, false);
- int atom = OS.XmInternAtom (xDisplay, bName, false);
- return atom;
+ byte[] bName = Converter.wcsToMbcs (null, formatName, true);
+ return OS.XmInternAtom (xDisplay, bName, false);
}
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/structs.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/structs.c
index b1228fa..ecc4273 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/structs.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/structs.c
@@ -19,6 +19,9 @@
#include "structs.h"
/* Globals */
+GdkDragContext_FID_CACHE GdkDragContextFc;
+GtkTargetEntry_FID_CACHE GtkTargetEntryFc;
+GtkSelectionData_FID_CACHE GtkSelectionDataFc;
GdkColor_FID_CACHE GdkColorFc;
GdkEventExpose_FID_CACHE GdkEventExposeFc;
GdkFont_FID_CACHE GdkFontFc;
@@ -1502,3 +1505,125 @@
(*env)->SetIntField(env, lpObject, lpGtkCTreeRowFc->is_leaf, (jint)lpGtkCTreeRow->is_leaf);
(*env)->SetIntField(env, lpObject, lpGtkCTreeRowFc->expanded, (jint)lpGtkCTreeRow->expanded);
}
+
+void cacheGtkSelectionDataFids(JNIEnv *env, jobject lpObject, PGtkSelectionData_FID_CACHE lpCache)
+{
+ if (lpCache->cached) return;
+ lpCache->clazz = (*env)->GetObjectClass(env, lpObject);
+ lpCache->selection = (*env)->GetFieldID(env, lpCache->clazz, "selection", "I");
+ lpCache->target = (*env)->GetFieldID(env, lpCache->clazz, "target", "I");
+ lpCache->type = (*env)->GetFieldID(env, lpCache->clazz, "type", "I");
+ lpCache->format = (*env)->GetFieldID(env, lpCache->clazz, "format", "I");
+ lpCache->data = (*env)->GetFieldID(env, lpCache->clazz, "data", "I");
+ lpCache->length = (*env)->GetFieldID(env, lpCache->clazz, "length", "I");
+ lpCache->cached = 1;
+}
+
+GtkSelectionData* getGtkSelectionDataFields(JNIEnv *env, jobject lpObject, GtkSelectionData *lpStruct, PGtkSelectionData_FID_CACHE lpCache)
+{
+ if (!lpCache->cached) cacheGtkSelectionDataFids(env, lpObject, lpCache);
+ lpStruct->selection = (GdkAtom)(*env)->GetIntField(env, lpObject, lpCache->selection);
+ lpStruct->target = (GdkAtom)(*env)->GetIntField(env, lpObject, lpCache->target);
+ lpStruct->type = (GdkAtom)(*env)->GetIntField(env, lpObject, lpCache->type);
+ lpStruct->format = (*env)->GetIntField(env, lpObject, lpCache->format);
+ lpStruct->data = (guchar*)(*env)->GetIntField(env, lpObject, lpCache->data);
+ lpStruct->length = (*env)->GetIntField(env, lpObject, lpCache->length);
+ return lpStruct;
+}
+
+void setGtkSelectionDataFields(JNIEnv *env, jobject lpObject, GtkSelectionData *lpStruct, PGtkSelectionData_FID_CACHE lpCache)
+{
+ if (!lpCache->cached) cacheGtkSelectionDataFids(env, lpObject, lpCache);
+ (*env)->SetIntField(env, lpObject, lpCache->selection, (jint) lpStruct->selection);
+ (*env)->SetIntField(env, lpObject, lpCache->target, (jint)lpStruct->target);
+ (*env)->SetIntField(env, lpObject, lpCache->type, (jint)lpStruct->type);
+ (*env)->SetIntField(env, lpObject, lpCache->format, lpStruct->format);
+ (*env)->SetIntField(env, lpObject, lpCache->data, (jint)lpStruct->data);
+ (*env)->SetIntField(env, lpObject, lpCache->length, lpStruct->length);
+}
+
+void cacheGtkTargetEntryFids(JNIEnv *env, jobject lpObject, PGtkTargetEntry_FID_CACHE lpCache)
+{
+ if (lpCache->cached) return;
+ lpCache->clazz = (*env)->GetObjectClass(env, lpObject);
+ lpCache->target = (*env)->GetFieldID(env, lpCache->clazz, "target", "I");
+ lpCache->flags = (*env)->GetFieldID(env, lpCache->clazz, "flags", "I");
+ lpCache->info = (*env)->GetFieldID(env, lpCache->clazz, "info", "I");
+ lpCache->cached = 1;
+}
+
+GtkTargetEntry* getGtkTargetEntryFields(JNIEnv *env, jobject lpObject, GtkTargetEntry *lpStruct, PGtkTargetEntry_FID_CACHE lpCache)
+{
+ if (!lpCache->cached) cacheGtkTargetEntryFids(env, lpObject, lpCache);
+ lpStruct->target = (gchar*)(*env)->GetIntField(env, lpObject, lpCache->target);
+ lpStruct->flags = (*env)->GetIntField(env, lpObject, lpCache->flags);
+ lpStruct->info = (*env)->GetIntField(env, lpObject, lpCache->info);
+ return lpStruct;
+}
+
+void setGtkTargetEntryFields(JNIEnv *env, jobject lpObject, GtkTargetEntry *lpStruct, PGtkTargetEntry_FID_CACHE lpCache)
+{
+ if (!lpCache->cached) cacheGtkTargetEntryFids(env, lpObject, lpCache);
+ (*env)->SetIntField(env, lpObject, lpCache->target, (jint)lpStruct->target);
+ (*env)->SetIntField(env, lpObject, lpCache->flags, (jint)lpStruct->flags);
+ (*env)->SetIntField(env, lpObject, lpCache->info, (jint)lpStruct->info);
+}
+
+void cacheGdkDragContextFids(JNIEnv *env, jobject lpObject, PGdkDragContext_FID_CACHE lpCache)
+{
+ if (lpCache->cached) return;
+ lpCache->clazz = (*env)->GetObjectClass(env, lpObject);
+ lpCache->parent_instance$g_type_instance$g_class = (*env)->GetFieldID(env, lpCache->clazz, "parent_instance$g_type_instance$g_class", "I");
+ lpCache->parent_instance$ref_count = (*env)->GetFieldID(env, lpCache->clazz, "parent_instance$ref_count", "I");
+ lpCache->parent_instance$qdata = (*env)->GetFieldID(env, lpCache->clazz, "parent_instance$qdata", "I");
+ lpCache->protocol = (*env)->GetFieldID(env, lpCache->clazz, "protocol", "I");
+ lpCache->is_source = (*env)->GetFieldID(env, lpCache->clazz, "is_source", "Z");
+ lpCache->source_window = (*env)->GetFieldID(env, lpCache->clazz, "source_window", "I");
+ lpCache->dest_window = (*env)->GetFieldID(env, lpCache->clazz, "dest_window", "I");
+ lpCache->targets = (*env)->GetFieldID(env, lpCache->clazz, "targets", "I");
+ lpCache->actions = (*env)->GetFieldID(env, lpCache->clazz, "actions", "I");
+ lpCache->suggested_action = (*env)->GetFieldID(env, lpCache->clazz, "suggested_action", "I");
+ lpCache->action = (*env)->GetFieldID(env, lpCache->clazz, "action", "I");
+ lpCache->start_time = (*env)->GetFieldID(env, lpCache->clazz, "start_time", "I");
+ lpCache->windowing_data = (*env)->GetFieldID(env, lpCache->clazz, "windowing_data", "I");
+ lpCache->cached = 1;
+}
+
+GdkDragContext* getGdkDragContextFields(JNIEnv *env, jobject lpObject, GdkDragContext *lpStruct, PGdkDragContext_FID_CACHE lpCache)
+{
+ if (!lpCache->cached) cacheGdkDragContextFids(env, lpObject, lpCache);
+ lpStruct->parent_instance.g_type_instance.g_class = (GTypeClass*)(*env)->GetIntField(env, lpObject, lpCache->parent_instance$g_type_instance$g_class);
+ lpStruct->parent_instance.ref_count = (*env)->GetIntField(env, lpObject, lpCache->parent_instance$ref_count);
+ lpStruct->parent_instance.qdata = (GData*)(*env)->GetIntField(env, lpObject, lpCache->parent_instance$qdata);
+ lpStruct->protocol = (*env)->GetIntField(env, lpObject, lpCache->protocol);
+ lpStruct->is_source = (*env)->GetBooleanField(env, lpObject, lpCache->is_source);
+ lpStruct->source_window = (GdkWindow*)(*env)->GetIntField(env, lpObject, lpCache->source_window);
+ lpStruct->dest_window = (GdkWindow*)(*env)->GetIntField(env, lpObject, lpCache->dest_window);
+ lpStruct->targets = (GList*)(*env)->GetIntField(env, lpObject, lpCache->targets);
+ lpStruct->actions = (*env)->GetIntField(env, lpObject, lpCache->actions);
+ lpStruct->suggested_action = (*env)->GetIntField(env, lpObject, lpCache->suggested_action);
+ lpStruct->action = (*env)->GetIntField(env, lpObject, lpCache->action);
+ lpStruct->start_time = (*env)->GetIntField(env, lpObject, lpCache->start_time);
+ lpStruct->windowing_data = (gpointer)(*env)->GetIntField(env, lpObject, lpCache->windowing_data);
+ return lpStruct;
+}
+
+void setGdkDragContextFields(JNIEnv *env, jobject lpObject, GdkDragContext *lpStruct, PGdkDragContext_FID_CACHE lpCache)
+{
+ if (!lpCache->cached) cacheGdkDragContextFids(env, lpObject, lpCache);
+ (*env)->SetIntField(env, lpObject, lpCache->parent_instance$g_type_instance$g_class,(jint) lpStruct->parent_instance.g_type_instance.g_class);
+ (*env)->SetIntField(env, lpObject, lpCache->parent_instance$ref_count, lpStruct->parent_instance.ref_count);
+ (*env)->SetIntField(env, lpObject, lpCache->parent_instance$qdata, (jint) lpStruct->parent_instance.qdata);
+ (*env)->SetIntField(env, lpObject, lpCache->protocol, (jint) lpStruct->protocol);
+ (*env)->SetBooleanField(env, lpObject, lpCache->is_source, (jboolean) lpStruct->is_source);
+ (*env)->SetIntField(env, lpObject, lpCache->source_window, (jint) lpStruct->source_window);
+ (*env)->SetIntField(env, lpObject, lpCache->dest_window, (jint) lpStruct->dest_window);
+ (*env)->SetIntField(env, lpObject, lpCache->targets, (jint) lpStruct->targets);
+ (*env)->SetIntField(env, lpObject, lpCache->actions, (jint) lpStruct->actions);
+ (*env)->SetIntField(env, lpObject, lpCache->suggested_action, (jint) lpStruct->suggested_action);
+ (*env)->SetIntField(env, lpObject, lpCache->action, (jint) lpStruct->action);
+ (*env)->SetIntField(env, lpObject, lpCache->start_time, lpStruct->start_time);
+ (*env)->SetIntField(env, lpObject, lpCache->windowing_data, (jint) lpStruct->windowing_data);
+}
+
+
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/structs.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/structs.h
index f3bb667..b5a9ea7 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/structs.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/structs.h
@@ -245,6 +245,45 @@
typedef GtkCTree_FID_CACHE *PGtkCTree_FID_CACHE;
+
+/* GtkSelectionData struct */
+typedef struct GtkSelectionData_FID_CACHE {
+ int cached;
+ jclass clazz;
+ jfieldID selection, target, type, format, data, length;
+} GtkSelectionData_FID_CACHE;
+typedef GtkSelectionData_FID_CACHE *PGtkSelectionData_FID_CACHE;
+
+void cacheGtkSelectionDataFids(JNIEnv *env, jobject lpObject, PGtkSelectionData_FID_CACHE lpCache);
+GtkSelectionData* getGtkSelectionDataFields(JNIEnv *env, jobject lpObject, GtkSelectionData *lpStruct, PGtkSelectionData_FID_CACHE lpCache);
+void setGtkSelectionDataFields(JNIEnv *env, jobject lpObject, GtkSelectionData *lpStruct, PGtkSelectionData_FID_CACHE lpCache);
+
+
+/* GtkTargetEntry struct */
+typedef struct GtkTargetEntry_FID_CACHE {
+ int cached;
+ jclass clazz;
+ jfieldID target, flags, info;
+} GtkTargetEntry_FID_CACHE;
+typedef GtkTargetEntry_FID_CACHE *PGtkTargetEntry_FID_CACHE;
+
+void cacheGtkTargetEntryFids(JNIEnv *env, jobject lpObject, PGtkTargetEntry_FID_CACHE lpCache);
+GtkTargetEntry* getGtkTargetEntryFields(JNIEnv *env, jobject lpObject, GtkTargetEntry *lpStruct, PGtkTargetEntry_FID_CACHE lpCache);
+void setGtkTargetEntryFields(JNIEnv *env, jobject lpObject, GtkTargetEntry *lpStruct, PGtkTargetEntry_FID_CACHE lpCache);
+
+/* GdkDragContext struct */
+typedef struct GdkDragContext_FID_CACHE {
+ int cached;
+ jclass clazz;
+ jfieldID parent_instance$g_type_instance$g_class, parent_instance$ref_count, parent_instance$qdata, protocol, is_source, source_window, dest_window, targets, actions, suggested_action, action, start_time, windowing_data;
+} GdkDragContext_FID_CACHE;
+typedef GdkDragContext_FID_CACHE *PGdkDragContext_FID_CACHE;
+
+void cacheGdkDragContextFids(JNIEnv *env, jobject lpObject, PGdkDragContext_FID_CACHE lpCache);
+GdkDragContext* getGdkDragContextFields(JNIEnv *env, jobject lpObject, GdkDragContext *lpStruct, PGdkDragContext_FID_CACHE lpCache);
+void setGdkDragContextFields(JNIEnv *env, jobject lpObject, GdkDragContext *lpStruct, PGdkDragContext_FID_CACHE lpCache);
+
+
/* ----------- cache function prototypes ----------- */
void cacheGdkColorFids(JNIEnv *env, jobject lpGdkColor, PGdkColor_FID_CACHE lpCache);
@@ -331,5 +370,9 @@
extern GtkRequisition_FID_CACHE GtkRequisitionFc;
extern GtkStyle_FID_CACHE GtkStyleFc;
extern GtkStyleClass_FID_CACHE GtkStyleClassFc;
+extern GtkSelectionData_FID_CACHE GtkSelectionDataFc;
+extern GtkTargetEntry_FID_CACHE GtkTargetEntryFc;
+extern GdkDragContext_FID_CACHE GdkDragContextFc;
+
#endif // INC_structs_H
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt-gtkwidget.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt-gtkwidget.c
index 8cb5bab..33f2fb1 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt-gtkwidget.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt-gtkwidget.c
@@ -633,3 +633,216 @@
return gtk_widget_send_expose((GtkWidget*)wid, (GdkEvent*)event);
}
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_drag_source_set
+ * Signature: (IIIII)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1drag_1source_1set
+ (JNIEnv *env, jclass that, jint widget, jint start_button_mask, jint targets, jint n_targets, jint actions)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_drag_source_set");
+#endif
+ gtk_drag_source_set( (GtkWidget*)widget, (GdkModifierType) start_button_mask, (const GtkTargetEntry*) targets,
+ n_targets, (GdkDragAction) actions );
+
+}
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_drag_source_unset
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1drag_1source_1unset
+ (JNIEnv *env, jclass that, jint widget)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_drag_source_unset");
+#endif
+ gtk_drag_source_unset( (GtkWidget*)widget);
+}
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_selection_data_set
+ * Signature: (IIIII)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1selection_1data_1set
+ (JNIEnv *env, jclass that, jint selection_data, jint type, jint format, jint data, jint length)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_selection_data_set");
+#endif
+ gtk_selection_data_set( (GtkSelectionData*) selection_data, (GdkAtom) type, format,
+ (guchar*) data, length);
+
+}
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_drag_dest_set
+ * Signature: (IIIII)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1drag_1dest_1set
+ (JNIEnv *env, jclass that, jint widget, jint flags, jint targets, jint n_targets, jint actions)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_drag_dest_set");
+#endif
+ gtk_drag_dest_set( (GtkWidget*)widget, (GtkDestDefaults) flags, (const GtkTargetEntry*) targets,
+ n_targets, (GdkDragAction) actions );
+
+}
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_drag_dest_unset
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1drag_1dest_1unset
+ (JNIEnv *env, jclass that, jint widget)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_drag_dest_unset");
+#endif
+ gtk_drag_dest_unset( (GtkWidget*)widget );
+}
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_drag_dest_find_target
+ * Signature: (III)I
+ */
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1drag_1dest_1find_1target
+ (JNIEnv *env, jclass that, jint widget, jint context, jint target_list)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_drag_dest_find_target");
+#endif
+ return (jint)gtk_drag_dest_find_target( (GtkWidget*)widget , (GdkDragContext*)context, (GtkTargetList*)target_list);
+}
+
+
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gdk_drag_abort
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_gdk_1drag_1abort
+ (JNIEnv *env, jclass that, jint context, jint time)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gdk_drag_abort");
+#endif
+ gdk_drag_abort( (GdkDragContext *) context, time);
+}
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_drag_finish
+ * Signature: (IBBI)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1drag_1finish
+ (JNIEnv *env, jclass that, jint context, jboolean sucess, jboolean del, jint time)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_drag_finish");
+#endif
+ gtk_drag_finish( (GdkDragContext *) context, sucess, del, time);
+}
+
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_clipboard_get
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1clipboard_1get
+ (JNIEnv *env, jclass that, jint selection)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_clipboard_get");
+#endif
+ return (jint) gtk_clipboard_get ( (GdkAtom) selection );
+}
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_clipboard_set_with_data
+ * Signature: (I)I
+ */
+JNIEXPORT jboolean JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1clipboard_1set_1with_1data
+ (JNIEnv *env, jclass that, jint clipboard, jint targets, jint n_targets, jint get_func, jint clear_func, jint user_data)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_clipboard_set_with_data");
+#endif
+ return gtk_clipboard_set_with_data ( (GtkClipboard*) clipboard, (GtkTargetEntry*) targets,
+ n_targets, (GtkClipboardGetFunc) get_func,
+ (GtkClipboardClearFunc) clear_func, (gpointer) user_data);
+}
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_clipboard_wait_for_contents
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1clipboard_1wait_1for_1contents
+ (JNIEnv *env, jclass that, jint clipboard, jint target)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_clipboard_wait_for_contents");
+#endif
+ return (jint) gtk_clipboard_wait_for_contents( (GtkClipboard*) clipboard,(GdkAtom) target);
+}
+
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gdk_atom_name
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_gdk_1atom_1name
+ (JNIEnv *env, jclass that, jint atom)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gdk_atom_name");
+#endif
+ return (jint) gdk_atom_name( (GdkAtom) atom );
+}
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_selection_data_free
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1selection_1data_1free
+ (JNIEnv *env, jclass that, jint data)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_selection_data_free");
+#endif
+ gtk_selection_data_free( (GtkSelectionData*) data);
+}
+
+/*
+ * Class: org_eclipse_swt_internal_gtk_OS
+ * Method: gtk_clipboard_clear
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1clipboard_1clear
+ (JNIEnv *env, jclass that, jint clipboard)
+{
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "gtk_clipboard_clear");
+#endif
+ gtk_clipboard_clear( (GtkClipboard*) clipboard);
+}
+
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_GDK_1POINTER_1TO_1ATOM
+ (JNIEnv *env, jclass that, jint ptr)
+{
+ return (jint) GDK_POINTER_TO_ATOM((GdkAtom)ptr);
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt-memmove.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt-memmove.c
index 2d3ad9d..ac88d7c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt-memmove.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt-memmove.c
@@ -269,3 +269,55 @@
(*env)->ReleaseByteArrayElements(env, src, src1, 0);
}
}
+
+/* Drag and Drop adds */
+
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_memmove__Lorg_eclipse_swt_internal_gtk_GtkSelectionData_2I
+ (JNIEnv *env, jclass that, jobject dest, jint src)
+{
+ DECL_GLOB(pGlob)
+ if (dest) {
+ cacheGtkSelectionDataFids(env, dest, &PGLOB(GtkSelectionDataFc));
+ setGtkSelectionDataFields(env, dest, (GtkSelectionData *)src, &PGLOB(GtkSelectionDataFc));
+ }
+}
+
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_memmove__Lorg_eclipse_swt_internal_gtk_GdkDragContext_2I
+ (JNIEnv *env, jclass that, jobject dest, jint src)
+{
+ DECL_GLOB(pGlob)
+ if (dest) {
+ cacheGdkDragContextFids(env, dest, &PGLOB(GdkDragContextFc));
+ setGdkDragContextFields(env, dest, (GdkDragContext *)src, &PGLOB(GdkDragContextFc));
+ }
+}
+
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_memmove__ILorg_eclipse_swt_internal_gtk_GdkDragContext_2
+ (JNIEnv *env, jclass that, jint dest, jobject src)
+{
+ DECL_GLOB(pGlob)
+ if (src) {
+ cacheGdkDragContextFids(env, src, &PGLOB(GdkDragContextFc));
+ getGdkDragContextFields(env, src, (GdkDragContext *)dest, &PGLOB(GdkDragContextFc));
+ }
+}
+
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_memmove__ILorg_eclipse_swt_internal_gtk_GtkTargetEntry_2
+ (JNIEnv *env, jclass that, jint dest, jobject src)
+{
+ DECL_GLOB(pGlob)
+ if (src) {
+ cacheGtkTargetEntryFids(env, src, &PGLOB(GtkTargetEntryFc));
+ getGtkTargetEntryFields(env, src, (GtkTargetEntry *)dest, &PGLOB(GtkTargetEntryFc));
+ }
+}
+
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_memmove__Lorg_eclipse_swt_internal_gtk_GtkTargetEntry_2I
+ (JNIEnv *env, jclass that, jobject dest, jint src)
+{
+ DECL_GLOB(pGlob)
+ if (dest) {
+ cacheGtkTargetEntryFids(env, dest, &PGLOB(GtkTargetEntryFc));
+ setGtkTargetEntryFields(env, dest, (GtkTargetEntry *)src, &PGLOB(GtkTargetEntryFc));
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkDragContext.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkDragContext.java
new file mode 100644
index 0000000..21f3e14
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkDragContext.java
@@ -0,0 +1,38 @@
+package org.eclipse.swt.internal.gtk;
+
+/*
+ * Copyright (c) IBM Corp. 2000, 2002. All rights reserved.
+ *
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt). The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html. If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ */
+
+public class GdkDragContext {
+
+ public int parent_instance$g_type_instance$g_class;
+ public int parent_instance$ref_count;
+ public int parent_instance$qdata;
+ public int protocol;
+ public boolean is_source;
+ public int source_window;
+ public int dest_window;
+ public int targets;
+ public int actions;
+ public int suggested_action;
+ public int action;
+ public int start_time;
+ public int windowing_data; //guint32
+
+ public GdkDragContext(){
+ }
+ public GdkDragContext(int ptr){
+ OS.memmove(this, ptr);
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GtkSelectionData.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GtkSelectionData.java
new file mode 100644
index 0000000..eac3f84
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GtkSelectionData.java
@@ -0,0 +1,29 @@
+package org.eclipse.swt.internal.gtk;
+
+/*
+ * Copyright (c) IBM Corp. 2000, 2001. All rights reserved.
+ *
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt). The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html. If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ */
+
+public class GtkSelectionData {
+ public int selection;
+ public int target;
+ public int type;
+ public int format;
+ public int data;
+ public int length;
+
+ public GtkSelectionData(){
+ }
+ public GtkSelectionData(int ptr){
+ OS.memmove(this, ptr);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GtkTargetEntry.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GtkTargetEntry.java
new file mode 100644
index 0000000..a060150
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GtkTargetEntry.java
@@ -0,0 +1,27 @@
+package org.eclipse.swt.internal.gtk;
+
+/*
+ * Copyright (c) IBM Corp. 2000, 2001. All rights reserved.
+ *
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt). The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html. If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ */
+
+public class GtkTargetEntry {
+ public int target;
+ public int flags;
+ public int info;
+ public static final int sizeof = 12;
+
+ public GtkTargetEntry(){
+ }
+ public GtkTargetEntry(int ptr){
+ OS.memmove(this, ptr);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
index 1bc82e5..1fb4b2a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
@@ -20,6 +20,40 @@
Library.loadLibrary("swt-pi");
}
+ /* DRAG DROP SUPPORT - MOVE TO APPROPRIATE PLACE LATER */
+// public static final native void gtk_drag_source_set(int widget, int start_button_mask, int targets, int n_targets, int actions);
+// public static final native void gtk_drag_source_unset(int widget);
+// public static final native void gtk_drag_dest_set(int widget, int flags, int targets, int n_targets, int actions);
+// public static final native void gtk_drag_dest_unset(int widget);
+// public static final native void gdk_drag_abort(int context, int time);
+// public static final native void gtk_drag_finish(int context, boolean sucess, boolean del, int time);
+// public static final native int gtk_drag_dest_find_target(int widget, int context, int target_list);
+// static final native void memmove(GdkDragContext dest, int src);
+// public static final native void memmove(int dest, GdkDragContext src);
+// public static final int GDK_ACTION_DEFAULT = 1 << 0;
+// public static final int GDK_ACTION_COPY = 1 << 1;
+// public static final int GDK_ACTION_MOVE = 1 << 2;
+// public static final int GDK_ACTION_LINK = 1 << 3;
+// public static final int GDK_ACTION_PRIVATE = 1 << 4;
+// public static final int GDK_ACTION_ASK = 1 << 5;
+// public static final int GTK_DEST_DEFAULT_MOTION = 1 << 0; /* respond to "drag_motion" */
+// public static final int GTK_DEST_DEFAULT_HIGHLIGHT = 1 << 1; /* auto-highlight */
+// public static final int GTK_DEST_DEFAULT_DROP = 1 << 2; /* respond to "drag_drop" */
+// public static final int GTK_DEST_DEFAULT_ALL = 0x07;
+
+
+ /* CLIPBOARD SUPPORT - MOVE TO APPROPRIATE PLACE LATER */
+ public static final native int gtk_clipboard_get( int selection );
+ public static final native boolean gtk_clipboard_set_with_data (int clipboard, int targets, int n_targets, int get_func, int clear_func, int user_data);
+ public static final native int gtk_clipboard_wait_for_contents (int clipboard, int target);
+ public static final native void gtk_selection_data_set(int selection_data, int type, int format, int data, int length);
+
+ public static final native int gtk_clipboard_clear( int clipboard );
+ public static final native int gtk_selection_data_free( int selection_data );
+ public static final native void memmove(int dest, GtkTargetEntry src);
+ public static final native void memmove(GtkTargetEntry dest, int src);
+ public static final native void memmove(GtkSelectionData dest, int src);
+ public static final native int GDK_POINTER_TO_ATOM(int ptr);
public static final int GDK_NONE = 0;