diff org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/dnd/ClipboardProxy.d @ 25:f713da8bc051

Added SWT Linux GTK
author Frank Benoit <benoit@tionex.de>
date Fri, 20 Mar 2009 23:03:58 +0100
parents
children ddbfe84d86df
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/dnd/ClipboardProxy.d	Fri Mar 20 23:03:58 2009 +0100
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module org.eclipse.swt.dnd.ClipboardProxy;
+
+import java.lang.all;
+
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.internal.gtk.OS;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.TransferData;
+
+static import tango.stdc.string;
+
+
+class ClipboardProxy {
+    /* Data is not flushed to the clipboard immediately.
+     * This class will remember the data and provide it when requested.
+     */
+    Object[] clipboardData;
+    Transfer[] clipboardDataTypes;
+    Object[] primaryClipboardData;
+    Transfer[] primaryClipboardDataTypes;
+
+    Display display;
+    Clipboard activeClipboard = null;
+    Clipboard activePrimaryClipboard = null;
+
+    static String ID = "CLIPBOARD PROXY OBJECT"; //$NON-NLS-1$
+
+static ClipboardProxy _getInstance(Display display) {
+    ClipboardProxy proxy = cast(ClipboardProxy) display.getData(ID);
+    if (proxy !is null) return proxy;
+    proxy = new ClipboardProxy(display);
+    display.setData(ID, proxy);
+    display.addListener(SWT.Dispose, new class( display ) Listener {
+        Display disp;
+        this( Display disp ){ this.disp = disp; }
+        public void handleEvent(Event event) {
+            ClipboardProxy clipbordProxy = cast(ClipboardProxy)disp.getData(ID);
+            if (clipbordProxy is null) return;
+            disp.setData(ID, null);
+            clipbordProxy.dispose();
+        }
+    });
+    return proxy;
+}
+
+this(Display display) {
+    this.display = display;
+}
+
+void clear (Clipboard owner, int clipboards) {
+    if ((clipboards & DND.CLIPBOARD) !is 0 && activeClipboard is owner) {
+        OS.gtk_clipboard_clear(Clipboard.GTKCLIPBOARD);
+    }
+    if ((clipboards & DND.SELECTION_CLIPBOARD) !is 0 && activePrimaryClipboard is owner) {
+        OS.gtk_clipboard_clear(Clipboard.GTKPRIMARYCLIPBOARD);
+    }
+}
+
+private static extern(C) void clearFuncFunc(GtkClipboard *clipboard, void* user_data_or_owner){
+    auto obj = cast(ClipboardProxy)user_data_or_owner;
+    obj.clearFunc( clipboard );
+}
+void clearFunc(GtkClipboard *clipboard ){
+    if (clipboard is Clipboard.GTKCLIPBOARD) {
+        activeClipboard = null;
+        clipboardData = null;
+        clipboardDataTypes = null;
+    }
+    if (clipboard is Clipboard.GTKPRIMARYCLIPBOARD) {
+        activePrimaryClipboard = null;
+        primaryClipboardData = null;
+        primaryClipboardDataTypes = null;
+    }
+}
+
+void dispose () {
+    if (display is null) return;
+    if (activeClipboard !is null) OS.gtk_clipboard_clear(Clipboard.GTKCLIPBOARD);
+    if (activePrimaryClipboard !is null) OS.gtk_clipboard_clear(Clipboard.GTKPRIMARYCLIPBOARD);
+    display = null;
+    clipboardData = null;
+    clipboardDataTypes = null;
+    primaryClipboardData = null;
+    primaryClipboardDataTypes = null;
+}
+
+private static extern(C) void getFuncFunc(
+    GtkClipboard *clipboard,
+    GtkSelectionData *selection_data,
+    uint info,
+    void* user_data_or_owner)
+{
+    auto obj = cast(ClipboardProxy)user_data_or_owner;
+    obj.getFunc( clipboard, selection_data, info );
+}
+/**
+ * This function provides the data to the clipboard on request.
+ * When this clipboard is disposed, the data will no longer be available.
+ */
+void getFunc(
+    GtkClipboard *clipboard,
+    GtkSelectionData *selectionData,
+    uint info)
+{
+    if (selectionData is null) return 0;
+    TransferData tdata = new TransferData();
+    tdata.type = selectionData.target;
+    Transfer[] types = (clipboard is Clipboard.GTKCLIPBOARD) ? clipboardDataTypes : primaryClipboardDataTypes;
+    int index = -1;
+    for (int i = 0; i < types.length; i++) {
+        if (types[i].isSupportedType(tdata)) {
+            index = i;
+            break;
+        }
+    }
+    if (index is -1) return 0;
+    Object[] data = (clipboard is Clipboard.GTKCLIPBOARD) ? clipboardData : primaryClipboardData;
+    types[index].javaToNative(data[index], tdata);
+    if (tdata.format < 8 || tdata.format % 8 !is 0) {
+        return 0;
+    }
+    OS.gtk_selection_data_set(selectionData, tdata.type, tdata.format, tdata.pValue, tdata.length);
+    OS.g_free(tdata.pValue);
+    return 1;
+}
+
+bool setData(Clipboard owner, Object[] data, Transfer[] dataTypes, int clipboards) { 
+    GtkTargetEntry*[] entries;
+    GtkTargetEntry* pTargetsList;
+    try {
+        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];
+                char* pName = cast(char*)OS.g_malloc(typeNames[j].length+1);
+                pName[ 0 .. typeNames[j].length ] = typeNames[j];
+                pName[ typeNames[j].length ] = '\0';
+                entry.target = pName;
+                GtkTargetEntry*[] tmp = new GtkTargetEntry*[entries.length + 1];
+                SimpleType!(GtkTargetEntry*).arraycopy(entries, 0, tmp, 0, entries.length);
+                tmp[entries.length] = entry;
+                entries = tmp;
+            }
+        }
+
+        pTargetsList = cast(GtkTargetEntry*)OS.g_malloc(GtkTargetEntry.sizeof * entries.length);
+        int offset = 0;
+        for (int i = 0; i < entries.length; i++) {
+            tango.stdc.string.memmove(pTargetsList + i, entries[i], GtkTargetEntry.sizeof);
+            offset += GtkTargetEntry.sizeof;
+        }
+        if ((clipboards & DND.CLIPBOARD) !is 0) {
+            if (activeClipboard !is null) OS.gtk_clipboard_clear(Clipboard.GTKCLIPBOARD);
+            clipboardData = data;
+            clipboardDataTypes = dataTypes;
+            if (!OS.gtk_clipboard_set_with_data(Clipboard.GTKCLIPBOARD, pTargetsList, entries.length, &getFuncFunc, &clearFuncFunc, cast(void*)this )) {
+                return false;
+            }
+            activeClipboard = owner;
+        }
+        if ((clipboards & DND.SELECTION_CLIPBOARD) !is 0) {
+            if (activePrimaryClipboard !is null) OS.gtk_clipboard_clear(Clipboard.GTKPRIMARYCLIPBOARD);
+            primaryClipboardData = data;
+            primaryClipboardDataTypes = dataTypes;
+            if (!OS.gtk_clipboard_set_with_data(Clipboard.GTKPRIMARYCLIPBOARD, pTargetsList, entries.length, &getFuncFunc, &clearFuncFunc, cast(void*)this )) {
+                return false;
+            }
+            activePrimaryClipboard = owner;
+        }
+        return true;
+    } finally {
+        for (int i = 0; i < entries.length; i++) {
+            GtkTargetEntry* entry = entries[i];
+            if( entry.target !is null) OS.g_free(entry.target);
+        }
+        if (pTargetsList !is null) OS.g_free(pTargetsList);
+    }
+}
+}