*** 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;