25
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2000, 2005 IBM Corporation and others.
|
|
3 * All rights reserved. This program and the accompanying materials
|
|
4 * are made available under the terms of the Eclipse Public License v1.0
|
|
5 * which accompanies this distribution, and is available at
|
|
6 * http://www.eclipse.org/legal/epl-v10.html
|
|
7 *
|
|
8 * Contributors:
|
|
9 * IBM Corporation - initial API and implementation
|
|
10 * Port to the D programming language:
|
|
11 * Frank Benoit <benoit@tionex.de>
|
|
12 *******************************************************************************/
|
|
13 module org.eclipse.swt.dnd.ClipboardProxy;
|
|
14
|
|
15 import java.lang.all;
|
|
16
|
|
17
|
|
18
|
|
19 import org.eclipse.swt.SWT;
|
|
20 import org.eclipse.swt.internal.gtk.OS;
|
|
21 import org.eclipse.swt.widgets.Display;
|
|
22 import org.eclipse.swt.widgets.Event;
|
|
23 import org.eclipse.swt.widgets.Listener;
|
|
24 import org.eclipse.swt.dnd.Transfer;
|
|
25 import org.eclipse.swt.dnd.Clipboard;
|
|
26 import org.eclipse.swt.dnd.DND;
|
|
27 import org.eclipse.swt.dnd.TransferData;
|
|
28
|
48
|
29 version(Tango){
|
25
|
30 static import tango.stdc.string;
|
48
|
31 } else { // Phobos
|
|
32 }
|
25
|
33
|
|
34
|
|
35 class ClipboardProxy {
|
|
36 /* Data is not flushed to the clipboard immediately.
|
|
37 * This class will remember the data and provide it when requested.
|
|
38 */
|
|
39 Object[] clipboardData;
|
|
40 Transfer[] clipboardDataTypes;
|
|
41 Object[] primaryClipboardData;
|
|
42 Transfer[] primaryClipboardDataTypes;
|
|
43
|
|
44 Display display;
|
|
45 Clipboard activeClipboard = null;
|
|
46 Clipboard activePrimaryClipboard = null;
|
|
47
|
|
48 static String ID = "CLIPBOARD PROXY OBJECT"; //$NON-NLS-1$
|
|
49
|
|
50 static ClipboardProxy _getInstance(Display display) {
|
|
51 ClipboardProxy proxy = cast(ClipboardProxy) display.getData(ID);
|
|
52 if (proxy !is null) return proxy;
|
|
53 proxy = new ClipboardProxy(display);
|
|
54 display.setData(ID, proxy);
|
|
55 display.addListener(SWT.Dispose, new class( display ) Listener {
|
|
56 Display disp;
|
|
57 this( Display disp ){ this.disp = disp; }
|
|
58 public void handleEvent(Event event) {
|
|
59 ClipboardProxy clipbordProxy = cast(ClipboardProxy)disp.getData(ID);
|
|
60 if (clipbordProxy is null) return;
|
|
61 disp.setData(ID, null);
|
|
62 clipbordProxy.dispose();
|
|
63 }
|
|
64 });
|
|
65 return proxy;
|
|
66 }
|
|
67
|
|
68 this(Display display) {
|
|
69 this.display = display;
|
|
70 }
|
|
71
|
|
72 void clear (Clipboard owner, int clipboards) {
|
|
73 if ((clipboards & DND.CLIPBOARD) !is 0 && activeClipboard is owner) {
|
|
74 OS.gtk_clipboard_clear(Clipboard.GTKCLIPBOARD);
|
|
75 }
|
|
76 if ((clipboards & DND.SELECTION_CLIPBOARD) !is 0 && activePrimaryClipboard is owner) {
|
|
77 OS.gtk_clipboard_clear(Clipboard.GTKPRIMARYCLIPBOARD);
|
|
78 }
|
|
79 }
|
|
80
|
|
81 private static extern(C) void clearFuncFunc(GtkClipboard *clipboard, void* user_data_or_owner){
|
|
82 auto obj = cast(ClipboardProxy)user_data_or_owner;
|
|
83 obj.clearFunc( clipboard );
|
|
84 }
|
|
85 void clearFunc(GtkClipboard *clipboard ){
|
|
86 if (clipboard is Clipboard.GTKCLIPBOARD) {
|
|
87 activeClipboard = null;
|
|
88 clipboardData = null;
|
|
89 clipboardDataTypes = null;
|
|
90 }
|
|
91 if (clipboard is Clipboard.GTKPRIMARYCLIPBOARD) {
|
|
92 activePrimaryClipboard = null;
|
|
93 primaryClipboardData = null;
|
|
94 primaryClipboardDataTypes = null;
|
|
95 }
|
|
96 }
|
|
97
|
|
98 void dispose () {
|
|
99 if (display is null) return;
|
|
100 if (activeClipboard !is null) OS.gtk_clipboard_clear(Clipboard.GTKCLIPBOARD);
|
|
101 if (activePrimaryClipboard !is null) OS.gtk_clipboard_clear(Clipboard.GTKPRIMARYCLIPBOARD);
|
|
102 display = null;
|
|
103 clipboardData = null;
|
|
104 clipboardDataTypes = null;
|
|
105 primaryClipboardData = null;
|
|
106 primaryClipboardDataTypes = null;
|
|
107 }
|
|
108
|
|
109 private static extern(C) void getFuncFunc(
|
|
110 GtkClipboard *clipboard,
|
|
111 GtkSelectionData *selection_data,
|
|
112 uint info,
|
|
113 void* user_data_or_owner)
|
|
114 {
|
|
115 auto obj = cast(ClipboardProxy)user_data_or_owner;
|
|
116 obj.getFunc( clipboard, selection_data, info );
|
|
117 }
|
|
118 /**
|
|
119 * This function provides the data to the clipboard on request.
|
|
120 * When this clipboard is disposed, the data will no longer be available.
|
|
121 */
|
|
122 void getFunc(
|
|
123 GtkClipboard *clipboard,
|
|
124 GtkSelectionData *selectionData,
|
|
125 uint info)
|
|
126 {
|
|
127 if (selectionData is null) return 0;
|
|
128 TransferData tdata = new TransferData();
|
|
129 tdata.type = selectionData.target;
|
|
130 Transfer[] types = (clipboard is Clipboard.GTKCLIPBOARD) ? clipboardDataTypes : primaryClipboardDataTypes;
|
|
131 int index = -1;
|
|
132 for (int i = 0; i < types.length; i++) {
|
|
133 if (types[i].isSupportedType(tdata)) {
|
|
134 index = i;
|
|
135 break;
|
|
136 }
|
|
137 }
|
|
138 if (index is -1) return 0;
|
|
139 Object[] data = (clipboard is Clipboard.GTKCLIPBOARD) ? clipboardData : primaryClipboardData;
|
|
140 types[index].javaToNative(data[index], tdata);
|
|
141 if (tdata.format < 8 || tdata.format % 8 !is 0) {
|
|
142 return 0;
|
|
143 }
|
|
144 OS.gtk_selection_data_set(selectionData, tdata.type, tdata.format, tdata.pValue, tdata.length);
|
|
145 OS.g_free(tdata.pValue);
|
|
146 return 1;
|
|
147 }
|
|
148
|
|
149 bool setData(Clipboard owner, Object[] data, Transfer[] dataTypes, int clipboards) {
|
|
150 GtkTargetEntry*[] entries;
|
|
151 GtkTargetEntry* pTargetsList;
|
|
152 try {
|
|
153 for (int i = 0; i < dataTypes.length; i++) {
|
|
154 Transfer transfer = dataTypes[i];
|
|
155 int[] typeIds = transfer.getTypeIds();
|
|
156 String[] typeNames = transfer.getTypeNames();
|
|
157 for (int j = 0; j < typeIds.length; j++) {
|
|
158 GtkTargetEntry* entry = new GtkTargetEntry();
|
|
159 entry.info = typeIds[j];
|
|
160 char* pName = cast(char*)OS.g_malloc(typeNames[j].length+1);
|
|
161 pName[ 0 .. typeNames[j].length ] = typeNames[j];
|
|
162 pName[ typeNames[j].length ] = '\0';
|
|
163 entry.target = pName;
|
|
164 GtkTargetEntry*[] tmp = new GtkTargetEntry*[entries.length + 1];
|
|
165 SimpleType!(GtkTargetEntry*).arraycopy(entries, 0, tmp, 0, entries.length);
|
|
166 tmp[entries.length] = entry;
|
|
167 entries = tmp;
|
|
168 }
|
|
169 }
|
|
170
|
|
171 pTargetsList = cast(GtkTargetEntry*)OS.g_malloc(GtkTargetEntry.sizeof * entries.length);
|
|
172 int offset = 0;
|
|
173 for (int i = 0; i < entries.length; i++) {
|
53
|
174 OS.memmove(pTargetsList + i, entries[i], GtkTargetEntry.sizeof);
|
25
|
175 offset += GtkTargetEntry.sizeof;
|
|
176 }
|
|
177 if ((clipboards & DND.CLIPBOARD) !is 0) {
|
|
178 if (activeClipboard !is null) OS.gtk_clipboard_clear(Clipboard.GTKCLIPBOARD);
|
|
179 clipboardData = data;
|
|
180 clipboardDataTypes = dataTypes;
|
|
181 if (!OS.gtk_clipboard_set_with_data(Clipboard.GTKCLIPBOARD, pTargetsList, entries.length, &getFuncFunc, &clearFuncFunc, cast(void*)this )) {
|
|
182 return false;
|
|
183 }
|
|
184 activeClipboard = owner;
|
|
185 }
|
|
186 if ((clipboards & DND.SELECTION_CLIPBOARD) !is 0) {
|
|
187 if (activePrimaryClipboard !is null) OS.gtk_clipboard_clear(Clipboard.GTKPRIMARYCLIPBOARD);
|
|
188 primaryClipboardData = data;
|
|
189 primaryClipboardDataTypes = dataTypes;
|
|
190 if (!OS.gtk_clipboard_set_with_data(Clipboard.GTKPRIMARYCLIPBOARD, pTargetsList, entries.length, &getFuncFunc, &clearFuncFunc, cast(void*)this )) {
|
|
191 return false;
|
|
192 }
|
|
193 activePrimaryClipboard = owner;
|
|
194 }
|
|
195 return true;
|
|
196 } finally {
|
|
197 for (int i = 0; i < entries.length; i++) {
|
|
198 GtkTargetEntry* entry = entries[i];
|
|
199 if( entry.target !is null) OS.g_free(entry.target);
|
|
200 }
|
|
201 if (pTargetsList !is null) OS.g_free(pTargetsList);
|
|
202 }
|
|
203 }
|
|
204 }
|