blob: e33c6a0b48cfc7d0a18a745868a52a97c63716da [file] [log] [blame]
package org.eclipse.swt.dnd;
/*
* Copyright (c) 2000, 2002 IBM Corp. All rights reserved.
* This file is made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*/
import org.eclipse.swt.SWT;
import org.eclipse.swt.internal.Callback;
import org.eclipse.swt.internal.Converter;
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.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
class ClipboardProxy {
/* Data is not flushed to the clipboard immediately.
* This class will remember the data and provide it when requested.
*/
Object[] data;
Transfer[] dataTypes;
Display display;
int pGtkClipboard;
int pGtkPrimary;
boolean onPrimary = false;
boolean onClipboard = false;
Callback getFunc;
Callback clearFunc;
static String ID = "CLIPBOARD PROXY OBJECT";
static ClipboardProxy _getInstance(Display display) {
ClipboardProxy proxy = (ClipboardProxy) display.getData(ID);
if (proxy != null) return proxy;
proxy = new ClipboardProxy(display);
display.setData(ID, proxy);
display.addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
Display display = event.display;
ClipboardProxy proxy = (ClipboardProxy)display.getData(ID);
if (proxy == null) return;
display.setData(ID, null);
proxy.dispose();
}
});
return proxy;
}
private ClipboardProxy(Display display) {
this.display = display;
getFunc = new Callback( this, "getFunc", 4);
clearFunc = new Callback( this, "clearFunc", 2);
pGtkClipboard = OS.gtk_clipboard_get(OS.GDK_NONE);
byte[] buffer = Converter.wcsToMbcs(null, "PRIMARY", true);
int primary = OS.gdk_atom_intern(buffer, false);
pGtkPrimary = OS.gtk_clipboard_get(primary);
}
private int clearFunc(int clipboard,int user_data_or_owner){
if (clipboard == pGtkClipboard) {
onClipboard = false;
}
if (clipboard == pGtkPrimary) {
onPrimary = false;
}
if (!onClipboard && !onPrimary) {
data = null;
dataTypes = null;
}
return 1;
}
private void dispose () {
if (pGtkClipboard == 0) return;
if (onPrimary) OS.gtk_clipboard_clear(pGtkPrimary);
if (onClipboard) OS.gtk_clipboard_clear(pGtkClipboard);
pGtkClipboard = 0;
pGtkPrimary = 0;
display = null;
if (getFunc != null ) getFunc.dispose();
getFunc = null;
if (clearFunc != null) clearFunc.dispose();
clearFunc = null;
data = null;
dataTypes = null;
}
/**
* This function provides the data to the clipboard on request.
* When this clipboard is disposed, the data will no longer be available.
*/
private int getFunc( int clipboard, int selection_data, int info, int user_data_or_owner){
if (selection_data == 0) return 0;
GtkSelectionData selectionData = new GtkSelectionData();
OS.memmove(selectionData, selection_data, GtkSelectionData.sizeof);
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;
}
boolean setData(Object[] data, Transfer[] dataTypes) {
if (onClipboard) {
OS.gtk_clipboard_clear(pGtkClipboard);
}
if (onPrimary) {
OS.gtk_clipboard_clear(pGtkPrimary);
}
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], GtkTargetEntry.sizeof);
offset += GtkTargetEntry.sizeof;
}
this.data = data;
this.dataTypes = dataTypes;
onPrimary = OS.gtk_clipboard_set_with_data(pGtkPrimary, pTargetsList, entries.length, getFunc.getAddress(), clearFunc.getAddress(), 0);
onClipboard = OS.gtk_clipboard_set_with_data(pGtkClipboard, pTargetsList, entries.length, getFunc.getAddress(), clearFunc.getAddress(), 0);
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);
return (onClipboard && onPrimary);
}
}