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
index 6cd70304a42..1412721c787 100644
--- 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
@@ -15,7 +15,6 @@
import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.internal.gtk3.*;
@@ -39,15 +38,24 @@ public class Clipboard {
static long GTKCLIPBOARD;
static long GTKPRIMARYCLIPBOARD;
+ /**
+ * GTK3 only
+ */
private static long TARGET;
static {
- GTKCLIPBOARD = GTK.GTK4 ? GDK.gdk_display_get_clipboard(GDK.gdk_display_get_default()) : GTK3.gtk_clipboard_get (GDK.GDK_NONE);
- byte[] buffer = Converter.wcsToMbcs("PRIMARY", true);
- long primary = GTK.GTK4 ? 0 : GDK.gdk_atom_intern(buffer, false);
- GTKPRIMARYCLIPBOARD = GTK.GTK4 ? GDK.gdk_display_get_primary_clipboard(GDK.gdk_display_get_default()) : GTK3.gtk_clipboard_get(primary);
- buffer = Converter.wcsToMbcs("TARGETS", true);
- TARGET = GTK.GTK4 ? 0 : GDK.gdk_atom_intern(buffer, false);
+ if (GTK.GTK4) {
+ GTKCLIPBOARD = GDK.gdk_display_get_clipboard(GDK.gdk_display_get_default());
+ GTKPRIMARYCLIPBOARD = GDK.gdk_display_get_primary_clipboard(GDK.gdk_display_get_default());
+ TARGET = 0;
+ } else {
+ GTKCLIPBOARD = GTK3.gtk_clipboard_get(GDK.GDK_NONE);
+ byte[] buffer = Converter.wcsToMbcs("PRIMARY", true);
+ long primary = GDK.gdk_atom_intern(buffer, false);
+ GTKPRIMARYCLIPBOARD = GTK3.gtk_clipboard_get(primary);
+ buffer = Converter.wcsToMbcs("TARGETS", true);
+ TARGET = GDK.gdk_atom_intern(buffer, false);
+ }
}
/**
@@ -188,8 +196,13 @@ public void clearContents() {
*/
public void clearContents(int clipboards) {
checkWidget();
- ClipboardProxy proxy = ClipboardProxy._getInstance(display);
- proxy.clear(this, clipboards);
+ if (GTK.GTK4) {
+ ClipboardProxyGTK4 proxy = ClipboardProxyGTK4._getInstance(display);
+ proxy.clear(this, clipboards);
+ } else {
+ ClipboardProxy proxy = ClipboardProxy._getInstance(display);
+ proxy.clear(this, clipboards);
+ }
}
/**
@@ -290,14 +303,12 @@ public Object getContents(Transfer transfer) {
* @since 3.1
*/
public Object getContents(Transfer transfer, int clipboards) {
- checkWidget();
- if (transfer == null) DND.error(SWT.ERROR_NULL_ARGUMENT);
-
- if(GTK.GTK4) {
- Object result = getContents_gtk4(transfer, clipboards);
- return result;
+ if (GTK.GTK4) {
+ return getContents_gtk4(transfer, clipboards);
}
+ checkWidget();
+ if (transfer == null) DND.error(SWT.ERROR_NULL_ARGUMENT);
long selection_data = 0;
int[] typeIds = transfer.getTypeIds();
boolean textTransfer = transfer.getTypeNames()[0].equals("UTF8_STRING");
@@ -327,65 +338,11 @@ public Object getContents(Transfer transfer, int clipboards) {
}
private Object getContents_gtk4(Transfer transfer, int clipboards) {
+ checkWidget();
+ if (transfer == null) DND.error(SWT.ERROR_NULL_ARGUMENT);
- long contents = GTK4.gdk_clipboard_get_content(Clipboard.GTKCLIPBOARD);
- if(contents == 0) return null;
- long value = OS.g_malloc (OS.GValue_sizeof ());
- C.memset (value, 0, OS.GValue_sizeof ());
-
- //Pasting of text (TextTransfer/RTFTransfer)
- if(transfer.getTypeNames()[0].equals("text/plain") || transfer.getTypeNames()[0].equals("text/rtf")) {
- OS.g_value_init(value, OS.G_TYPE_STRING());
- if (!GTK4.gdk_content_provider_get_value (contents, value, null)) return null;
- long cStr = OS.g_value_get_string(value);
- long [] items_written = new long [1];
- long utf16Ptr = OS.g_utf8_to_utf16(cStr, -1, null, items_written, null);
- OS.g_free(cStr);
- if (utf16Ptr == 0) return null;
- int length = (int)items_written[0];
- char[] buffer = new char[length];
- C.memmove(buffer, utf16Ptr, length * 2);
- OS.g_free(utf16Ptr);
- String str = new String(buffer);
- if(transfer.getTypeNames()[0].equals("text/rtf") && !str.contains("{\\rtf1")) {
- return null;
- }
- if(transfer.getTypeNames()[0].equals("text/plain") && str.contains("{\\rtf1")){
- return null;
- }
- return str;
- }
- //Pasting of Image
- if(transfer.getTypeIds()[0] == (int)GDK.GDK_TYPE_PIXBUF()) {
- ImageData imgData = null;
- OS.g_value_init(value, GDK.GDK_TYPE_PIXBUF());
- if (!GTK4.gdk_content_provider_get_value (contents, value, null)) return null;
- long pixbufObj = OS.g_value_get_object(value);
- if (pixbufObj != 0) {
- Image img = Image.gtk_new_from_pixbuf(Display.getCurrent(), SWT.BITMAP, pixbufObj);
- imgData = img.getImageData();
- img.dispose();
- }
- return imgData;
- }
- //Pasting of HTML
- if(transfer.getTypeNames()[0].equals("text/html")) {
- OS.g_value_init(value, OS.G_TYPE_STRING());
- if (!GTK4.gdk_content_provider_get_value (contents, value, null)) return null;
- long cStr = OS.g_value_get_string(value);
- long [] items_written = new long [1];
- long utf16Ptr = OS.g_utf8_to_utf16(cStr, -1, null, items_written, null);
- OS.g_free(cStr);
- if (utf16Ptr == 0) return null;
- int length = (int)items_written[0];
- char[] buffer = new char[length];
- C.memmove(buffer, utf16Ptr, length * 2);
- OS.g_free(utf16Ptr);
- String str = new String(buffer);
- return str;
- }
- //TODO: [GTK4] Other cases
- return null;
+ ClipboardProxyGTK4 proxy = ClipboardProxyGTK4._getInstance(display);
+ return proxy.getData(this, transfer, clipboards);
}
/**
@@ -525,9 +482,16 @@ public void setContents(Object[] data, Transfer[] dataTypes, int clipboards) {
DND.error(SWT.ERROR_INVALID_ARGUMENT);
}
}
- ClipboardProxy proxy = ClipboardProxy._getInstance(display);
- if (!proxy.setData(this, data, dataTypes, clipboards)) {
- DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD);
+ if (GTK.GTK4) {
+ ClipboardProxyGTK4 proxy = ClipboardProxyGTK4._getInstance(display);
+ if (!proxy.setData(this, data, dataTypes, clipboards)) {
+ DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD);
+ }
+ } else {
+ ClipboardProxy proxy = ClipboardProxy._getInstance(display);
+ if (!proxy.setData(this, data, dataTypes, clipboards)) {
+ DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD);
+ }
}
}
@@ -623,8 +587,10 @@ public TransferData[] getAvailableTypes(int clipboards) {
public String[] getAvailableTypeNames() {
checkWidget();
if(GTK.GTK4) {
+ // TODO make sure this code works with new GTK4 impl
long formatsCStr = GTK4.gdk_content_formats_to_string(GTK4.gdk_clipboard_get_formats(Clipboard.GTKCLIPBOARD));
String formatsStr = Converter.cCharPtrToJavaString(formatsCStr, true);
+ System.out.println(formatsStr);
String[] types = formatsStr.split(" ");
return types;
}
@@ -673,6 +639,7 @@ private int[] getAvailableClipboardTypes () {
return gtk3_getAvailableTypes(GTKCLIPBOARD);
}
+// TODO make sure this code works with new GTK4 impl
private int[] gtk4_getAvailableTypes(long clipboard) {
long formats = GTK4.gdk_clipboard_get_formats(clipboard);
long[] n_gtypes = new long[1];
@@ -723,4 +690,6 @@ long gtk_clipboard_wait_for_contents(long clipboard, long target) {
}
return selection_data;
}
+
+
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ClipboardProxy.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ClipboardProxy.java
index fd61b6c8eaa..92068b23c49 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ClipboardProxy.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ClipboardProxy.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -14,14 +14,15 @@
package org.eclipse.swt.dnd;
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.internal.gtk3.*;
-import org.eclipse.swt.internal.gtk4.*;
import org.eclipse.swt.widgets.*;
+/**
+ * Clipboard proxy used to copy data to the clipboard in GTK3 only
+ * @see ClipboardProxyGTK4 the GTK4 version
+ */
class ClipboardProxy {
/* Data is not flushed to the clipboard immediately.
* This class will remember the data and provide it when requested.
@@ -31,7 +32,7 @@ class ClipboardProxy {
Object[] primaryClipboardData;
Transfer[] primaryClipboardDataTypes;
- long clipboardOwner = GTK.GTK4 ? GTK4.gtk_window_new() : GTK3.gtk_window_new(GTK.GTK_WINDOW_TOPLEVEL);
+ long clipboardOwner = GTK3.gtk_window_new(GTK.GTK_WINDOW_TOPLEVEL);
Display display;
Clipboard activeClipboard = null;
@@ -42,6 +43,9 @@ class ClipboardProxy {
static String ID = "CLIPBOARD PROXY OBJECT"; //$NON-NLS-1$
static ClipboardProxy _getInstance(final Display display) {
+ if (GTK.GTK4) {
+ throw new UnsupportedOperationException("Illegal attempt to use GTK3 ClipboardProxy on GTK4");
+ }
ClipboardProxy proxy = (ClipboardProxy) display.getData(ID);
if (proxy != null) return proxy;
proxy = new ClipboardProxy(display);
@@ -55,7 +59,7 @@ static ClipboardProxy _getInstance(final Display display) {
return proxy;
}
-ClipboardProxy(Display display) {
+private ClipboardProxy(Display display) {
this.display = display;
getFunc = new Callback( this, "getFunc", 4); //$NON-NLS-1$
clearFunc = new Callback( this, "clearFunc", 2); //$NON-NLS-1$
@@ -71,11 +75,7 @@ void clear (Clipboard owner, int clipboards) {
}
void gtk_gdk_clipboard_clear(long clipboard) {
- if (GTK.GTK4) {
- GDK.gdk_clipboard_set_content(clipboard, 0);
- } else {
- GTK3.gtk_clipboard_clear(clipboard);
- }
+ GTK3.gtk_clipboard_clear(clipboard);
}
long clearFunc(long clipboard,long user_data_or_owner){
@@ -95,10 +95,10 @@ long clearFunc(long clipboard,long user_data_or_owner){
void dispose () {
if (display == null) return;
if (activeClipboard != null) {
- if(!GTK.GTK4) GTK3.gtk_clipboard_store(Clipboard.GTKCLIPBOARD);
+ GTK3.gtk_clipboard_store(Clipboard.GTKCLIPBOARD);
}
if (activePrimaryClipboard != null) {
- if(!GTK.GTK4) GTK3.gtk_clipboard_store(Clipboard.GTKPRIMARYCLIPBOARD);
+ GTK3.gtk_clipboard_store(Clipboard.GTKPRIMARYCLIPBOARD);
}
display = null;
if (getFunc != null ) getFunc.dispose();
@@ -110,11 +110,7 @@ void dispose () {
primaryClipboardData = null;
primaryClipboardDataTypes = null;
if (clipboardOwner != 0) {
- if (GTK.GTK4) {
- GTK4.gtk_window_destroy(clipboardOwner);
- } else {
- GTK3.gtk_widget_destroy(clipboardOwner);
- }
+ GTK3.gtk_widget_destroy(clipboardOwner);
}
clipboardOwner = 0;
}
@@ -148,9 +144,6 @@ long getFunc(long clipboard, long selection_data, long info, long user_data_or_o
}
boolean setData(Clipboard owner, Object[] data, Transfer[] dataTypes, int clipboards) {
-
- if(GTK.GTK4) return setData_gtk4(owner, data, dataTypes, clipboards);
-
GtkTargetEntry[] entries = new GtkTargetEntry [0];
long pTargetsList = 0;
try {
@@ -219,66 +212,4 @@ boolean setData(Clipboard owner, Object[] data, Transfer[] dataTypes, int clipbo
if (pTargetsList != 0) OS.g_free(pTargetsList);
}
}
-
-private boolean setData_gtk4(Clipboard owner, Object[] data, Transfer[] dataTypes, int clipboards) {
- boolean result = false;
- long [] providers = new long[0];
- for (int i = 0; i < dataTypes.length; i++) {
- Transfer transfer = dataTypes[i];
- String[] typeNames = transfer.getTypeNames();
- //Build the GdkContentProvider for each and store in array
- long provider = setProviderFromType(typeNames[0], data[i]);
- if(provider != 0) {
- long[] tmp = new long [providers.length + 1];
- System.arraycopy(providers, 0, tmp, 0, providers.length);
- tmp[providers.length] = provider;
- providers = tmp;
- }
- }
- //Build the GdkContentProvider Union
- if (providers.length == 0) return false;
- long union = GTK4.gdk_content_provider_new_union(providers, providers.length);
-
- if ((clipboards & DND.CLIPBOARD) != 0){
- clipboardData = data;
- clipboardDataTypes = dataTypes;
- result = GTK4.gdk_clipboard_set_content(Clipboard.GTKCLIPBOARD, union);
- activeClipboard = owner;
- }
- return result;
-}
-
-private long setProviderFromType(String string, Object data) {
- long provider = 0;
-
- if (data == null ) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- else {
- if(string.equals("text/plain") || string.equals("text/rtf")) {
- long value = OS.g_malloc (OS.GValue_sizeof());
- C.memset (value, 0, OS.GValue_sizeof ());
- OS.g_value_init(value, OS.G_TYPE_STRING());
- OS.g_value_set_string(value, Converter.javaStringToCString((String)data));
- provider = GTK4.gdk_content_provider_new_for_value(value);
- }
- if(string.equals("PIXBUF")) {
- if(!(data instanceof ImageData)) DND.error(DND.ERROR_INVALID_DATA);
- ImageData imgData = (ImageData)data;
- Image image = new Image(Display.getCurrent(), imgData);
- long pixbuf = ImageList.createPixbuf(image);
- if (pixbuf != 0) {
- provider = GTK4.gdk_content_provider_new_typed(GDK.GDK_TYPE_PIXBUF(), pixbuf);
- }
- image.dispose();
- }
- if(string.equals("text/html")) {
- long value = OS.g_malloc (OS.GValue_sizeof());
- C.memset (value, 0, OS.GValue_sizeof ());
- OS.g_value_init(value, OS.G_TYPE_STRING());
- OS.g_value_set_string(value, Converter.javaStringToCString((String)data));
- provider = GTK4.gdk_content_provider_new_for_value(value);
- }
-
- }
- return provider;
-}
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ClipboardProxyGTK4.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ClipboardProxyGTK4.java
new file mode 100644
index 00000000000..46ed9757674
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ClipboardProxyGTK4.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+import org.eclipse.swt.dnd.ContentProviders.*;
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.gtk.*;
+import org.eclipse.swt.internal.gtk4.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Clipboard proxy used to copy data to the clipboard in GTK4 only
+ *
+ * @see ClipboardProxy the GTK3 version
+ */
+class ClipboardProxyGTK4 {
+ private static String ID = "CLIPBOARD PROXY OBJECT"; //$NON-NLS-1$
+
+ private Display display;
+ private Clipboard activeClipboard = null;
+ private Clipboard activePrimaryClipboard = null;
+ private final ContentProviders contentProviders = ContentProviders.getInstance();
+
+ static ClipboardProxyGTK4 _getInstance(final Display display) {
+ if (!GTK.GTK4) {
+ throw new UnsupportedOperationException("Illegal attempt to use GTK4 ClipboardProxy on GTK3");
+ }
+ ClipboardProxyGTK4 proxy = (ClipboardProxyGTK4) display.getData(ID);
+ if (proxy != null)
+ return proxy;
+ proxy = new ClipboardProxyGTK4(display);
+ display.setData(ID, proxy);
+ display.disposeExec(() -> {
+ ClipboardProxyGTK4 clipbordProxy = (ClipboardProxyGTK4) display.getData(ID);
+ if (clipbordProxy == null)
+ return;
+ display.setData(ID, null);
+ clipbordProxy.dispose();
+ });
+ return proxy;
+ }
+
+ private ClipboardProxyGTK4(Display display) {
+ this.display = display;
+ }
+
+ void clear(Clipboard owner, int clipboards) {
+ if ((clipboards & DND.CLIPBOARD) != 0 && activeClipboard == owner) {
+ gtk_gdk_clipboard_clear(Clipboard.GTKCLIPBOARD);
+ }
+ if ((clipboards & DND.SELECTION_CLIPBOARD) != 0 && activePrimaryClipboard == owner) {
+ gtk_gdk_clipboard_clear(Clipboard.GTKPRIMARYCLIPBOARD);
+ }
+ }
+
+ private void gtk_gdk_clipboard_clear(long clipboard) {
+ // This only clears content if we were owner (i.e. when gdk_clipboard_is_local()
+ // == true)
+ GDK.gdk_clipboard_set_content(clipboard, 0);
+ }
+
+ void dispose() {
+ if (display == null) {
+ return;
+ }
+ // TODO - before completing disposal, consider storing data to global clipboard
+ // See
+ // https://github.com/eclipse-platform/eclipse.platform.swt/issues/2126#issuecomment-3312739514
+ display = null;
+
+ }
+
+ boolean setData(Clipboard owner, Object[] data, Transfer[] dataTypes, int clipboards) {
+ // TODO: free providers
+ long providers = contentProviders.createContentProviders(data, dataTypes,
+ CLIPBOARD_TYPE.fromDNDConstants(clipboards), display);
+ if (providers == 0) {
+ return false;
+ }
+
+ boolean result = false;
+ if ((clipboards & DND.CLIPBOARD) != 0) {
+ long clipboard = clipboards == DND.SELECTION_CLIPBOARD ? Clipboard.GTKPRIMARYCLIPBOARD
+ : Clipboard.GTKCLIPBOARD;
+ result = GTK4.gdk_clipboard_set_content(clipboard, providers);
+ if (clipboards == DND.SELECTION_CLIPBOARD) {
+ activePrimaryClipboard = owner;
+ } else {
+ activeClipboard = owner;
+ }
+ }
+ return result;
+
+ }
+
+ public Object getData(Clipboard owner, Transfer transfer, int clipboards) {
+
+ long clipboard = clipboards == DND.SELECTION_CLIPBOARD ? Clipboard.GTKPRIMARYCLIPBOARD : Clipboard.GTKCLIPBOARD;
+ long gType = contentProviders.getGType(transfer);
+
+ System.out.println("About to run gdk_clipboard_read_value_async");
+ Object value = new SyncFinishUtil<>().run(display, new SyncFinishCallback<>() {
+ @Override
+ public void async(long result) {
+ GTK4.gdk_clipboard_read_value_async(clipboard, gType, OS.G_PRIORITY_DEFAULT, 0, result, 0);
+ }
+
+ @Override
+ public Object await(long result) {
+ long gvalue = GTK4.gdk_clipboard_read_value_finish(clipboard, result, null);
+ if (gvalue == 0) {
+ return null;
+ }
+ return contentProviders.getObject(gvalue);
+ }
+ });
+
+ if (value == null) {
+ // nothing on clipboard, or nothing that can be mapped to transfer's type
+ return null;
+ }
+
+ return value;
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ContentProviders.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ContentProviders.java
new file mode 100644
index 00000000000..7fc9dfd8187
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ContentProviders.java
@@ -0,0 +1,366 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.gtk.*;
+import org.eclipse.swt.internal.gtk4.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Manages GdkContentProviders
+ * and the (de)serializers they rely on
+ */
+class ContentProviders {
+ public static enum CLIPBOARD_TYPE {
+ CLIPBOARD(1), PRIMARYCLIPBOARD(2), DRAG(3);
+
+ private final long sourceId;
+ private final Map data = new HashMap<>();
+ private Display display = null;
+
+ CLIPBOARD_TYPE(long id) {
+ this.sourceId = id;
+ }
+
+ /**
+ * Return the DESTINATION instance matching the clipboards using the constants
+ * {@link DND#CLIPBOARD} and {@link DND#SELECTION_CLIPBOARD}
+ */
+ public static CLIPBOARD_TYPE fromDNDConstants(int clipboards) {
+ if (clipboards == DND.CLIPBOARD)
+ return CLIPBOARD;
+ if (clipboards == DND.SELECTION_CLIPBOARD)
+ return PRIMARYCLIPBOARD;
+ // the clipboards should have been error checked for validity before entering
+ // this method
+ throw new RuntimeException("Error - invalid clipboards");
+ }
+
+ /**
+ * Returns the DESTINATION matching the given sourceId
+ */
+ public static CLIPBOARD_TYPE fromSourceId(long sourceId) {
+ CLIPBOARD_TYPE[] values = CLIPBOARD_TYPE.values();
+ for (CLIPBOARD_TYPE destination : values) {
+ if (destination.sourceId == sourceId) {
+ return destination;
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
+ * The life-time of the serializers in GTK4 (Gdk) are the life-time of the
+ * process so we use a singleton to store the mapping data that is needed.
+ */
+ private static ContentProviders instance = new ContentProviders();
+
+ /*
+ * The types registered with {@link #registerType(String)} on GTK4. Using
+ * TreeMap to make the maps sorted to ease debugging
+ */
+ final private Map ID_TO_CONTENTTYPE = new TreeMap<>();
+ final private Map CONTENTTYPE_TO_ID = new TreeMap<>();
+ // start at 1 because 0 is the null formatName
+ private int typeIndex = 1;
+
+ // These normally need disposal, but since this class is a singleton it isn't
+ // disposed.
+ Callback gdkContentSerializeFunc;
+ Callback gdkContentDeserializeFunc;
+
+ /**
+ * All transfers registered with the GTK serializers
+ *
+ * Key is the transfer obtained with {@link #transferKey(Transfer)}
+ */
+ private Map registeredTransfers = new TreeMap<>();
+
+ private Object lastDeserializedObject;
+
+ private ContentProviders() {
+ gdkContentSerializeFunc = new Callback(this, "gdkContentSerializeFunc", void.class, new Type[] { long.class }); //$NON-NLS-1$
+ gdkContentDeserializeFunc = new Callback(this, "gdkContentDeserializeFunc", void.class, //$NON-NLS-1$
+ new Type[] { long.class });
+ }
+
+ public static ContentProviders getInstance() {
+ return instance;
+ }
+
+ /**
+ * Called by {@link Transfer#registerType(String)} only
+ */
+ public int registerType(String formatName) {
+ if (formatName == null) {
+ return 0;
+ }
+ Integer id = CONTENTTYPE_TO_ID.get(formatName);
+ if (id == null) {
+ id = typeIndex++;
+ CONTENTTYPE_TO_ID.put(formatName, id);
+ ID_TO_CONTENTTYPE.put(id, formatName);
+ }
+ return id;
+ }
+
+ public long createContentProviders(Object[] data, Transfer[] transfers, CLIPBOARD_TYPE id, Display display) {
+ id.data.clear();
+ id.display = display;
+ long[] providers = new long[transfers.length];
+ for (int i = 0; i < transfers.length; i++) {
+ Transfer transfer = transfers[i];
+ registerTransfer(transfer);
+
+ // gvalue represents a data + transfer pair, with the
+ // gtype we can extract the transfer type, and that
+ // plus id can extract the data
+ long gvalue = OS.create_gvalue(transfer.gtype, id.sourceId);
+ // TODO free gvalue (probably when we free the union of providers, see TODO
+ // below)
+ providers[i] = GTK4.gdk_content_provider_new_for_value(gvalue);
+ id.data.put(transferKey(transfer), data[i]);
+ }
+
+ // TODO free union of providers (note that gdk_content_provider_new_union takes
+ // ownership of providers array)
+ return GTK4.gdk_content_provider_new_union(providers, providers.length);
+ }
+
+ void gdkContentSerializeFunc(long pSerializer) {
+ GdkContentSerializer serializer = new GdkContentSerializer(pSerializer);
+
+ Transfer transfer = getTransfer(serializer);
+ CLIPBOARD_TYPE fromSourceId = CLIPBOARD_TYPE.fromSourceId(serializer.source_id());
+ if (fromSourceId == null) {
+ // TODO failure here - where did this data come from? How are we asked to
+ // serialize data
+ // we didn't start with
+ // TODO make a GError like this??? or throw exception? Is this only a
+ // programming error?
+// GError *error = g_error_new (G_IO_ERROR,
+// G_IO_ERROR_NOT_FOUND,
+// "Could not convert data from %s to %s",
+// g_type_name (gdk_content_serializer_get_gtype (serializer)),
+// gdk_content_serializer_get_mime_type (serializer));
+// serializer.return_error(error);
+ throw new RuntimeException("this should be unreachable??? - see TODOs above this line");
+ }
+ Object object = fromSourceId.data.get(transferKey(transfer));
+ Display display = fromSourceId.display;
+ String mime_type = serializer.mime_type();
+ Integer typeObject = CONTENTTYPE_TO_ID.get(mime_type);
+ int type = typeObject == null ? 0 : typeObject;
+
+ // Convert the Java object to a C array...
+ TransferData transferData = new TransferData();
+ transferData.type = type;
+ transfer.javaToNative(object, transferData);
+
+ // ...write the C array to the output stream of the serializer
+ new AsyncFinishUtil().run(display, new AsyncReadyCallback() {
+ @Override
+ public void async(long result) {
+ OS.g_output_stream_write_all_async(serializer.output_stream(), transferData.pValue, transferData.length,
+ serializer.priority(), serializer.cancellable(), result, 0);
+ }
+
+ @Override
+ public long await(long result) {
+ long[] error = new long[1];
+ boolean finish = OS.g_output_stream_write_all_finish(serializer.output_stream(), result, null, error);
+ if (!finish) {
+ serializer.return_error(error[0]);
+ } else {
+ serializer.return_success();
+ }
+ OS.g_free(transferData.pValue);
+ return 0;
+ }
+ });
+ }
+
+ private Transfer getTransfer(GdkContentSerializer serializer) {
+ long gtype = serializer.gtype();
+ long namePtr = OS.g_type_name(gtype);
+ String transferName = Converter.cCharPtrToJavaString(namePtr, false);
+ Transfer transfer = registeredTransfers.get(transferName);
+ if (transfer == null) {
+// TODO make a GError like this??? or throw exception? Is this only a programming error?
+// GError *error = g_error_new (G_IO_ERROR,
+// G_IO_ERROR_NOT_FOUND,
+// "Could not convert data from %s to %s",
+// g_type_name (gdk_content_serializer_get_gtype (serializer)),
+// gdk_content_serializer_get_mime_type (serializer));
+// GTK4.gdk_content_serializer_return_error(serializer, namePtr);
+ throw new RuntimeException("Could not convert data because transfer of id " + transferName + " missing");
+ }
+ return transfer;
+ }
+
+ void gdkContentDeserializeFunc(long pDeserializer) {
+ System.out.println("gdkContentDeserializeFunc");
+ GdkContentDeserializer deserializer = new GdkContentDeserializer(pDeserializer);
+
+ Transfer transfer = getTransfer(deserializer);
+ String mime_type = deserializer.mime_type();
+ Integer typeObject = CONTENTTYPE_TO_ID.get(mime_type);
+ int type = typeObject == null ? 0 : typeObject;
+
+ Display display = Display.getCurrent(); // TODO where to get display from? Is this OK?
+
+ long memoryStream = OS.g_memory_output_stream_new_resizable();
+ System.out.println("About to run g_output_stream_splice_async");
+ new AsyncFinishUtil().run(display, new AsyncReadyCallback() {
+ @Override
+ public void async(long result) {
+ OS.g_output_stream_splice_async(memoryStream, deserializer.input_stream(),
+ OS.G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | OS.G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+ deserializer.priority(), deserializer.cancellable(), result, 0);
+ }
+
+ @Override
+ public long await(long result) {
+ long[] error = new long[1];
+ long spliced = OS.g_output_stream_splice_finish(memoryStream, result, null);
+ if (spliced < 0) {
+ // TODO save object better (see TODO where lastDeserializedObject is read)
+ ContentProviders.this.lastDeserializedObject = null;
+ deserializer.return_error(error[0]);
+ } else {
+ TransferData transferData = new TransferData();
+ transferData.type = type;
+ // TODO this downcast is probably ok, but an overflow error should be generated
+ // if someone tries to copy/paste > 2G of data
+ transferData.length = (int) OS.g_memory_output_stream_get_data_size(memoryStream);
+ transferData.pValue = OS.g_memory_output_stream_get_data(memoryStream);
+ transferData.format = 8;
+ Object object = transfer.nativeToJava(transferData);
+ // TODO save object better (see TODO where lastDeserializedObject is read)
+ System.out.println("Storing " + object);
+ ContentProviders.this.lastDeserializedObject = object;
+ deserializer.return_success();
+ }
+ return 0;
+ }
+ });
+ }
+
+ private Transfer getTransfer(GdkContentDeserializer deserializer) {
+ long gtype = deserializer.gtype();
+ long namePtr = OS.g_type_name(gtype);
+ String transferName = Converter.cCharPtrToJavaString(namePtr, false);
+ Transfer transfer = registeredTransfers.get(transferName);
+ if (transfer == null) {
+// TODO make a GError like this??? or throw exception? Is this only a programming error?
+// GError *error = g_error_new (G_IO_ERROR,
+// G_IO_ERROR_NOT_FOUND,
+// "Could not convert data from %s to %s",
+// g_type_name (gdk_content_serializer_get_gtype (serializer)),
+// gdk_content_serializer_get_mime_type (serializer));
+// GTK4.gdk_content_serializer_return_error(serializer, namePtr);
+ throw new RuntimeException("Could not convert data because transfer of id " + transferName + " missing");
+ }
+ return transfer;
+ }
+
+ private void registerTransfer(Transfer transfer) {
+ String name = transferKey(transfer);
+ if (registeredTransfers.containsKey(name)) {
+ return;
+ }
+ registeredTransfers.put(name, transfer);
+ transfer.gtype = OS.register_gtype_for_name(name);
+ String[] mimeTypes = transfer.getTypeNames();
+ for (int i = 0; i < mimeTypes.length; i++) {
+ String mimeType = mimeTypes[i];
+ GTK4.gdk_content_register_serializer(transfer.gtype, mimeType, gdkContentSerializeFunc.getAddress(), 0, 0);
+ GTK4.gdk_content_register_deserializer(mimeType, transfer.gtype, gdkContentDeserializeFunc.getAddress(), 0,
+ 0);
+ }
+ }
+
+ private String transferKey(Transfer transfer) {
+ // The value of the name here is used to help debugging the code.
+ // The only important thing is that the name is unique which is achieved by
+ // appending transfer.id
+ return "SWTTransfer_" + transfer.getClass().getSimpleName() + "_" + transfer.id;
+ }
+
+ public long getGType(Transfer transfer) {
+ registerTransfer(transfer);
+ return transfer.gtype;
+ }
+
+ public Object getObject(long gvalue) {
+
+ long namePtr = OS.G_VALUE_TYPE_NAME(gvalue);
+ String transferName = Converter.cCharPtrToJavaString(namePtr, false);
+ Transfer transfer = registeredTransfers.get(transferName);
+ if (transfer != null) {
+ long g_value_get_boxed = OS.g_value_get_boxed(gvalue);
+ CLIPBOARD_TYPE fromSourceId = CLIPBOARD_TYPE.fromSourceId(g_value_get_boxed);
+ if (fromSourceId != null) {
+ Object object = fromSourceId.data.get(transferKey(transfer));
+ return object;
+ }
+ }
+
+ // TODO support multiple deserialized objects - we should really be able to
+ // align a
+ // gvalue in GTK memory to a specific Java object here. For now return the last
+ // thing deserialized
+ return lastDeserializedObject;
+ }
+
+// private long setProviderFromType(String string, Object data) {
+// long provider = 0;
+//
+// if (data == null)
+// SWT.error(SWT.ERROR_NULL_ARGUMENT);
+// else {
+// if (string.equals("text/plain") || string.equals("text/rtf")) {
+// long value = OS.g_malloc(OS.GValue_sizeof());
+// C.memset(value, 0, OS.GValue_sizeof());
+// OS.g_value_init(value, OS.G_TYPE_STRING());
+// OS.g_value_set_string(value, Converter.javaStringToCString((String) data));
+// provider = GTK4.gdk_content_provider_new_for_value(value);
+// }
+// if (string.equals("PIXBUF")) {
+// if (!(data instanceof ImageData))
+// DND.error(DND.ERROR_INVALID_DATA);
+// ImageData imgData = (ImageData) data;
+// Image image = new Image(Display.getCurrent(), imgData);
+// long pixbuf = ImageList.createPixbuf(image);
+// if (pixbuf != 0) {
+// provider = GTK4.gdk_content_provider_new_typed(GDK.GDK_TYPE_PIXBUF(), pixbuf);
+// }
+// image.dispose();
+// }
+// if (string.equals("text/html")) {
+// long value = OS.g_malloc(OS.GValue_sizeof());
+// C.memset(value, 0, OS.GValue_sizeof());
+// OS.g_value_init(value, OS.G_TYPE_STRING());
+// OS.g_value_set_string(value, Converter.javaStringToCString((String) data));
+// provider = GTK4.gdk_content_provider_new_for_value(value);
+// }
+//
+// }
+// return provider;
+// }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/GdkContentDeserializer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/GdkContentDeserializer.java
new file mode 100644
index 00000000000..07d207a3682
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/GdkContentDeserializer.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.gtk4.*;
+
+/**
+ * Wrapper for GDK class GdkContentDeserializer with convenience methods to aid in
+ * writing {@link Transfer}s for GTK4
+ */
+class GdkContentDeserializer {
+
+ private long deserializer;
+
+ public GdkContentDeserializer(long deserializer) {
+ this.deserializer = deserializer;
+ }
+
+ public long gtype() {
+ return GTK4.gdk_content_deserializer_get_gtype(deserializer);
+ }
+
+ public String mime_type() {
+ return Converter.cCharPtrToJavaString(GTK4.gdk_content_deserializer_get_mime_type(deserializer), false);
+ }
+
+ public long input_stream() {
+ return GTK4.gdk_content_deserializer_get_input_stream(deserializer);
+
+ }
+
+ public int priority() {
+ return GTK4.gdk_content_deserializer_get_priority(deserializer);
+ }
+
+ public long cancellable() {
+ return GTK4.gdk_content_deserializer_get_cancellable(deserializer);
+ }
+
+ public void return_success() {
+ GTK4.gdk_content_deserializer_return_success(deserializer);
+ }
+
+ public void return_error(long error) {
+ GTK4.gdk_content_deserializer_return_error(deserializer, error);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/GdkContentSerializer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/GdkContentSerializer.java
new file mode 100644
index 00000000000..cbb70233caa
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/GdkContentSerializer.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.gtk.*;
+import org.eclipse.swt.internal.gtk4.*;
+
+/**
+ * Wrapper for GDK class GdkContentSerializer with convenience methods to aid in
+ * writing {@link Transfer}s for GTK4
+ */
+class GdkContentSerializer {
+ private long serializer;
+
+ public GdkContentSerializer(long serializer) {
+ this.serializer = serializer;
+ }
+
+ /**
+ * Return the unboxed value stored in the GValue
+ *
+ * This is only suitable for getting the source id when used with GValues
+ * created by {@link OS#create_gvalue(long, long)}
+ */
+ public long source_id() {
+ long gvalue = gvalue();
+ long source = OS.g_value_get_boxed(gvalue);
+ return source;
+ }
+
+ public String mime_type() {
+ return Converter.cCharPtrToJavaString(GTK4.gdk_content_serializer_get_mime_type(serializer), false);
+ }
+
+ public long gtype() {
+ return GTK4.gdk_content_serializer_get_gtype(serializer);
+ }
+
+ public long gvalue() {
+ return GTK4.gdk_content_serializer_get_value(serializer);
+ }
+
+ public long output_stream() {
+ return GTK4.gdk_content_serializer_get_output_stream(serializer);
+ }
+
+ public int priority() {
+ return GTK4.gdk_content_serializer_get_priority(serializer);
+ }
+
+ public long cancellable() {
+ return GTK4.gdk_content_serializer_get_cancellable(serializer);
+ }
+
+ public void return_success() {
+ GTK4.gdk_content_serializer_return_success(serializer);
+ }
+
+ public void return_error(long error) {
+ GTK4.gdk_content_serializer_return_error(serializer, error);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ImageTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ImageTransfer.java
index a58b0b35631..760fd13e269 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ImageTransfer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/ImageTransfer.java
@@ -40,27 +40,27 @@ public class ImageTransfer extends ByteArrayTransfer {
private static ImageTransfer _instance = new ImageTransfer();
private static final String JPEG = "image/jpeg"; //$NON-NLS-1$
- private static final int JPEG_ID = GTK.GTK4 ? 0: registerType(JPEG);
+ private static final int JPEG_ID = registerType(JPEG);
private static final String PNG = "image/png"; //$NON-NLS-1$
- private static final int PNG_ID = GTK.GTK4 ? 0:registerType(PNG);
+ private static final int PNG_ID = registerType(PNG);
private static final String BMP = "image/bmp"; //$NON-NLS-1$
- private static final int BMP_ID = GTK.GTK4 ? 0:registerType(BMP);
+ private static final int BMP_ID = registerType(BMP);
private static final String EPS = "image/eps"; //$NON-NLS-1$
- private static final int EPS_ID = GTK.GTK4 ? 0:registerType(EPS);
+ private static final int EPS_ID = registerType(EPS);
private static final String PCX = "image/pcx"; //$NON-NLS-1$
- private static final int PCX_ID = GTK.GTK4 ? 0:registerType(PCX);
+ private static final int PCX_ID = registerType(PCX);
private static final String PPM = "image/ppm"; //$NON-NLS-1$
- private static final int PPM_ID = GTK.GTK4 ? 0:registerType(PPM);
+ private static final int PPM_ID = registerType(PPM);
private static final String RGB = "image/ppm"; //$NON-NLS-1$
- private static final int RGB_ID = GTK.GTK4 ? 0:registerType(RGB);
+ private static final int RGB_ID = registerType(RGB);
private static final String TGA = "image/tga"; //$NON-NLS-1$
- private static final int TGA_ID = GTK.GTK4 ? 0:registerType(TGA);
+ private static final int TGA_ID = registerType(TGA);
private static final String XBM = "image/xbm"; //$NON-NLS-1$
- private static final int XBM_ID = GTK.GTK4 ? 0:registerType(XBM);
+ private static final int XBM_ID = registerType(XBM);
private static final String XPM = "image/xpm"; //$NON-NLS-1$
- private static final int XPM_ID = GTK.GTK4 ? 0:registerType(XPM);
+ private static final int XPM_ID = registerType(XPM);
private static final String XV = "image/xv"; //$NON-NLS-1$
- private static final int XV_ID = GTK.GTK4 ? 0:registerType(XV);
+ private static final int XV_ID = registerType(XV);
private ImageTransfer() {}
@@ -156,17 +156,11 @@ public Object nativeToJava(TransferData transferData) {
@Override
protected int[] getTypeIds(){
- if(GTK.GTK4) {
- return new int[] {(int) GDK.GDK_TYPE_PIXBUF()};
- }
return new int[]{PNG_ID, BMP_ID, EPS_ID, JPEG_ID, PCX_ID, PPM_ID, RGB_ID, TGA_ID, XBM_ID, XPM_ID, XV_ID};
}
@Override
protected String[] getTypeNames(){
- if(GTK.GTK4) {
- return new String[]{"PIXBUF"};
- }
return new String[]{PNG, BMP, EPS, JPEG, PCX, PPM, RGB, TGA, XBM, XPM, XV};
}
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
index 586ff586da7..8bac1243f79 100644
--- 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
@@ -63,6 +63,10 @@ public static RTFTransfer getInstance () {
*/
@Override
public void javaToNative (Object object, TransferData transferData){
+ if (GTK.GTK4) {
+ javaToNativeGTK4(object, transferData);
+ return;
+ }
transferData.result = 0;
if (!checkRTF(object) || !isSupportedType(transferData)) {
DND.error(DND.ERROR_INVALID_DATA);
@@ -78,6 +82,14 @@ public void javaToNative (Object object, TransferData transferData){
transferData.result = 1;
}
+
+private void javaToNativeGTK4(Object object, TransferData transferData) {
+ if (!checkRTF(object) || !isSupportedType(transferData)) {
+ DND.error(DND.ERROR_INVALID_DATA);
+ }
+ super.javaToNative(Converter.wcsToMbcs((String) object, false), transferData);
+}
+
/**
* This implementation of nativeToJava
converts a platform specific
* representation of RTF text to a java String
.
@@ -90,6 +102,8 @@ public void javaToNative (Object object, TransferData transferData){
*/
@Override
public Object nativeToJava(TransferData transferData){
+ if (GTK.GTK4) return nativeToJavaGTK4(transferData);
+
if ( !isSupportedType(transferData) || transferData.pValue == 0 ) return null;
int size = transferData.format * transferData.length / 8;
if (size == 0) return null;
@@ -101,6 +115,14 @@ public Object nativeToJava(TransferData transferData){
return (end == -1) ? string : string.substring(0, end);
}
+private Object nativeToJavaGTK4(TransferData transferData) {
+ Object buffer = super.nativeToJava(transferData);
+ if (buffer instanceof byte[] bytes) {
+ return new String(Converter.mbcsToWcs(bytes));
+ }
+ return null;
+}
+
@Override
protected int[] getTypeIds() {
if(GTK.GTK4) {
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
index a745aa13026..ff24259e540 100644
--- 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
@@ -42,11 +42,13 @@ public class TextTransfer extends ByteArrayTransfer {
private static final String COMPOUND_TEXT = "COMPOUND_TEXT"; //$NON-NLS-1$
private static final String UTF8_STRING = "UTF8_STRING"; //$NON-NLS-1$
private static final String STRING = "STRING"; //$NON-NLS-1$
+ private static final String TEXT_PLAIN = "text/plain"; //RFC-1341
private static final String TEXT_PLAIN_UTF8 = "text/plain;charset=utf-8"; //RFC-1341
- private static final int COMPOUND_TEXT_ID = GTK.GTK4 ? 0 : registerType(COMPOUND_TEXT);
- private static final int UTF8_STRING_ID = GTK.GTK4 ? 0 : registerType(UTF8_STRING);
- private static final int STRING_ID = GTK.GTK4 ? 0 : registerType(STRING);
- private static final int TEXT_PLAIN_UTF8_ID = GTK.GTK4 ? 0 : registerType(TEXT_PLAIN_UTF8);
+ private static final int COMPOUND_TEXT_ID = registerType(COMPOUND_TEXT);
+ private static final int UTF8_STRING_ID = registerType(UTF8_STRING);
+ private static final int STRING_ID = registerType(STRING);
+ private static final int TEXT_PLAIN_ID = registerType(TEXT_PLAIN);
+ private static final int TEXT_PLAIN_UTF8_ID = registerType(TEXT_PLAIN_UTF8);
private TextTransfer() {}
@@ -71,6 +73,10 @@ public static TextTransfer getInstance () {
*/
@Override
public void javaToNative (Object object, TransferData transferData) {
+ if (GTK.GTK4) {
+ javaToNativeGTK4(object, transferData);
+ return;
+ }
transferData.result = 0;
if (!checkText(object) || !isSupportedType(transferData)) {
DND.error(DND.ERROR_INVALID_DATA);
@@ -111,6 +117,13 @@ public void javaToNative (Object object, TransferData transferData) {
}
+private void javaToNativeGTK4(Object object, TransferData transferData) {
+ if (!checkText(object) || !isSupportedType(transferData)) {
+ DND.error(DND.ERROR_INVALID_DATA);
+ }
+ super.javaToNative(Converter.wcsToMbcs((String) object, false), transferData);
+}
+
/**
* This implementation of nativeToJava
converts a platform specific
* representation of plain text to a java String
.
@@ -122,6 +135,8 @@ public void javaToNative (Object object, TransferData transferData) {
*/
@Override
public Object nativeToJava(TransferData transferData){
+ if (GTK.GTK4) return nativeToJavaGTK4(transferData);
+
if (!isSupportedType(transferData) || transferData.pValue == 0) return null;
long [] list = new long [1];
int count = GDK.gdk_text_property_to_utf8_list_for_display(GDK.gdk_display_get_default(), transferData.type, transferData.format, transferData.pValue, transferData.length, list);
@@ -139,10 +154,18 @@ public Object nativeToJava(TransferData transferData){
return (end == -1) ? string : string.substring(0, end);
}
+private Object nativeToJavaGTK4(TransferData transferData) {
+ Object buffer = super.nativeToJava(transferData);
+ if (buffer instanceof byte[] bytes) {
+ return new String(Converter.mbcsToWcs(bytes));
+ }
+ return null;
+}
+
@Override
protected int[] getTypeIds() {
if(GTK.GTK4) {
- return new int[] {(int) OS.G_TYPE_STRING()};
+ return new int[] {TEXT_PLAIN_UTF8_ID, TEXT_PLAIN_ID, STRING_ID};
}
if (OS.isX11()) {
return new int[] {UTF8_STRING_ID, COMPOUND_TEXT_ID, STRING_ID};
@@ -153,7 +176,7 @@ protected int[] getTypeIds() {
@Override
protected String[] getTypeNames() {
if(GTK.GTK4) {
- return new String[] {"text/plain", STRING};
+ return new String[] {TEXT_PLAIN_UTF8, TEXT_PLAIN, STRING};
}
if (OS.isX11()) {
return new String[] {UTF8_STRING, COMPOUND_TEXT, STRING};
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
index 5cf4b739982..0f74f298983 100644
--- 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
@@ -34,6 +34,22 @@
*/
public abstract class Transfer {
+private static int nextId = 1;
+/**
+ * Unique id of the transfer type. Used by GTK4 implementation to map
+ * data in the C/GTK side back to Java.
+ */
+/* package */ final int id;
+/**
+ * GType registered with GDK for this transfer. Every Transfer type
+ * is associated with a GType so that SWT knows which transfer to use
+ */
+/* package */ long gtype;
+
+public Transfer() {
+ id = nextId++;
+}
+
/**
* Returns a list of the platform specific data types that can be converted using
* this transfer agent.
@@ -133,6 +149,10 @@ public abstract class Transfer {
* @return the unique identifier associated with this data type
*/
public static int registerType(String formatName){
+ if (GTK.GTK4) {
+ return ContentProviders.getInstance().registerType(formatName);
+ }
+
if (formatName == null) return GDK.GDK_NONE;
byte[] buffer = Converter.wcsToMbcs(formatName, true);
return (int)GDK.gdk_atom_intern(buffer, false);
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
index 3ff822475e1..e806ce5813c 100644
--- 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
@@ -13,7 +13,6 @@
*******************************************************************************/
package org.eclipse.swt.dnd;
-
/**
* The TransferData
class is a platform specific data structure for
* describing the type and the contents of data being converted by a transfer agent.
@@ -71,7 +70,7 @@ public class TransferData {
* platforms and should never be accessed from application code.
*
*
- * This is most commonly 8 bits.
+ * This is most commonly 8 bits, and on GTK4 is always 8 bits.
*
* @noreference This field is not intended to be referenced by clients.
*/
@@ -107,5 +106,4 @@ public class TransferData {
* @noreference This field is not intended to be referenced by clients.
*/
public int result;
-
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/atk.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/atk.c
index 5780bf4fe31..053bd0c722f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/atk.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/atk.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2022 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2025 IBM Corporation and others. 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
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
index 3ebcddc354a..71a2db65a1f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
@@ -50,6 +50,77 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1clipboard_1get_1formats)
}
#endif
+#ifndef NO_gdk_1clipboard_1is_1local
+JNIEXPORT jboolean JNICALL GTK4_NATIVE(gdk_1clipboard_1is_1local)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jboolean rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1clipboard_1is_1local_FUNC);
+ rc = (jboolean)gdk_clipboard_is_local((GdkClipboard*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1clipboard_1is_1local_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1clipboard_1read_1async
+JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1clipboard_1read_1async)
+ (JNIEnv *env, jclass that, jlong arg0, jobjectArray arg1, jint arg2, jlong arg3, jlong arg4, jlong arg5)
+{
+ char **lparg1=NULL
+ GTK4_NATIVE_ENTER(env, that, gdk_1clipboard_1read_1async_FUNC);
+ if (arg1) if ((lparg1 = swt_getArrayOfStringsUTF(env, arg1)) == NULL) goto fail;
+ gdk_clipboard_read_async((GdkClipboard*)arg0, (const char **)lparg1, (int)arg2, (GCancellable *)arg3, (GAsyncReadyCallback)arg4, (gpointer)arg5);
+fail:
+ if (arg1 && lparg1) swt_releaseArrayOfStringsUTF(env, arg1, lparg1);
+ GTK4_NATIVE_EXIT(env, that, gdk_1clipboard_1read_1async_FUNC);
+}
+#endif
+
+#ifndef NO_gdk_1clipboard_1read_1finish
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1clipboard_1read_1finish)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2, jlongArray arg3)
+{
+ jlong *lparg2=NULL;
+ jlong *lparg3=NULL;
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1clipboard_1read_1finish_FUNC);
+ if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
+ if (arg3) if ((lparg3 = (*env)->GetLongArrayElements(env, arg3, NULL)) == NULL) goto fail;
+ rc = (jlong)gdk_clipboard_read_finish((GdkClipboard*)arg0, (GAsyncResult *)arg1, (const char**)lparg2, (GError **)lparg3);
+fail:
+ if (arg3 && lparg3) (*env)->ReleaseLongArrayElements(env, arg3, lparg3, 0);
+ if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1clipboard_1read_1finish_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1clipboard_1read_1value_1async
+JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1clipboard_1read_1value_1async)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jint arg2, jlong arg3, jlong arg4, jlong arg5)
+{
+ GTK4_NATIVE_ENTER(env, that, gdk_1clipboard_1read_1value_1async_FUNC);
+ gdk_clipboard_read_value_async((GdkClipboard*)arg0, (GType)arg1, (int)arg2, (GCancellable *)arg3, (GAsyncReadyCallback)arg4, (gpointer)arg5);
+ GTK4_NATIVE_EXIT(env, that, gdk_1clipboard_1read_1value_1async_FUNC);
+}
+#endif
+
+#ifndef NO_gdk_1clipboard_1read_1value_1finish
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1clipboard_1read_1value_1finish)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2)
+{
+ jlong *lparg2=NULL;
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1clipboard_1read_1value_1finish_FUNC);
+ if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
+ rc = (jlong)gdk_clipboard_read_value_finish((GdkClipboard*)arg0, (GAsyncResult *)arg1, (GError **)lparg2);
+fail:
+ if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1clipboard_1read_1value_1finish_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_gdk_1clipboard_1set
JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1clipboard_1set)
(JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2)
@@ -86,6 +157,132 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1clipboard_1set_1text)
}
#endif
+#ifndef NO_gdk_1content_1deserializer_1get_1cancellable
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1deserializer_1get_1cancellable)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1deserializer_1get_1cancellable_FUNC);
+ rc = (jlong)gdk_content_deserializer_get_cancellable((GdkContentDeserializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1deserializer_1get_1cancellable_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1deserializer_1get_1gtype
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1deserializer_1get_1gtype)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1deserializer_1get_1gtype_FUNC);
+ rc = (jlong)gdk_content_deserializer_get_gtype((GdkContentDeserializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1deserializer_1get_1gtype_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1deserializer_1get_1input_1stream
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1deserializer_1get_1input_1stream)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1deserializer_1get_1input_1stream_FUNC);
+ rc = (jlong)gdk_content_deserializer_get_input_stream((GdkContentDeserializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1deserializer_1get_1input_1stream_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1deserializer_1get_1mime_1type
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1deserializer_1get_1mime_1type)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1deserializer_1get_1mime_1type_FUNC);
+ rc = (jlong)gdk_content_deserializer_get_mime_type((GdkContentDeserializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1deserializer_1get_1mime_1type_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1deserializer_1get_1priority
+JNIEXPORT jint JNICALL GTK4_NATIVE(gdk_1content_1deserializer_1get_1priority)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jint rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1deserializer_1get_1priority_FUNC);
+ rc = (jint)gdk_content_deserializer_get_priority((GdkContentDeserializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1deserializer_1get_1priority_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1deserializer_1get_1task_1data
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1deserializer_1get_1task_1data)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1deserializer_1get_1task_1data_FUNC);
+ rc = (jlong)gdk_content_deserializer_get_task_data((GdkContentDeserializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1deserializer_1get_1task_1data_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1deserializer_1get_1user_1data
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1deserializer_1get_1user_1data)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1deserializer_1get_1user_1data_FUNC);
+ rc = (jlong)gdk_content_deserializer_get_user_data((GdkContentDeserializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1deserializer_1get_1user_1data_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1deserializer_1get_1value
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1deserializer_1get_1value)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1deserializer_1get_1value_FUNC);
+ rc = (jlong)gdk_content_deserializer_get_value((GdkContentDeserializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1deserializer_1get_1value_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1deserializer_1return_1error
+JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1deserializer_1return_1error)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1)
+{
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1deserializer_1return_1error_FUNC);
+ gdk_content_deserializer_return_error((GdkContentDeserializer*)arg0, (GError*)arg1);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1deserializer_1return_1error_FUNC);
+}
+#endif
+
+#ifndef NO_gdk_1content_1deserializer_1return_1success
+JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1deserializer_1return_1success)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1deserializer_1return_1success_FUNC);
+ gdk_content_deserializer_return_success((GdkContentDeserializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1deserializer_1return_1success_FUNC);
+}
+#endif
+
+#ifndef NO_gdk_1content_1deserializer_1set_1task_1data
+JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1deserializer_1set_1task_1data)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2)
+{
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1deserializer_1set_1task_1data_FUNC);
+ gdk_content_deserializer_set_task_data((GdkContentDeserializer*)arg0, (gpointer)arg1, (GDestroyNotify)arg2);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1deserializer_1set_1task_1data_FUNC);
+}
+#endif
+
#ifndef NO_gdk_1content_1formats_1builder_1add_1mime_1type
JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1formats_1builder_1add_1mime_1type)
(JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1)
@@ -208,6 +405,160 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1provider_1new_1union)
}
#endif
+#ifndef NO_gdk_1content_1register_1deserializer
+JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1register_1deserializer)
+ (JNIEnv *env, jclass that, jstring arg0, jlong arg1, jlong arg2, jlong arg3, jlong arg4)
+{
+ const char *lparg0= NULL;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1register_1deserializer_FUNC);
+ if (arg0) if ((lparg0 = (*env)->GetStringUTFChars(env, arg0, NULL)) == NULL) goto fail;
+ gdk_content_register_deserializer((const char*)lparg0, (GType)arg1, (GdkContentDeserializeFunc)arg2, (gpointer)arg3, (GDestroyNotify)arg4);
+fail:
+ if (arg0 && lparg0) (*env)->ReleaseStringUTFChars(env, arg0, lparg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1register_1deserializer_FUNC);
+}
+#endif
+
+#ifndef NO_gdk_1content_1register_1serializer
+JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1register_1serializer)
+ (JNIEnv *env, jclass that, jlong arg0, jstring arg1, jlong arg2, jlong arg3, jlong arg4)
+{
+ const char *lparg1= NULL;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1register_1serializer_FUNC);
+ if (arg1) if ((lparg1 = (*env)->GetStringUTFChars(env, arg1, NULL)) == NULL) goto fail;
+ gdk_content_register_serializer((GType)arg0, (const char*)lparg1, (GdkContentSerializeFunc)arg2, (gpointer)arg3, (GDestroyNotify)arg4);
+fail:
+ if (arg1 && lparg1) (*env)->ReleaseStringUTFChars(env, arg1, lparg1);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1register_1serializer_FUNC);
+}
+#endif
+
+#ifndef NO_gdk_1content_1serializer_1get_1cancellable
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1serializer_1get_1cancellable)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1serializer_1get_1cancellable_FUNC);
+ rc = (jlong)gdk_content_serializer_get_cancellable((GdkContentSerializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1serializer_1get_1cancellable_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1serializer_1get_1gtype
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1serializer_1get_1gtype)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1serializer_1get_1gtype_FUNC);
+ rc = (jlong)gdk_content_serializer_get_gtype((GdkContentSerializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1serializer_1get_1gtype_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1serializer_1get_1mime_1type
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1serializer_1get_1mime_1type)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1serializer_1get_1mime_1type_FUNC);
+ rc = (jlong)gdk_content_serializer_get_mime_type((GdkContentSerializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1serializer_1get_1mime_1type_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1serializer_1get_1output_1stream
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1serializer_1get_1output_1stream)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1serializer_1get_1output_1stream_FUNC);
+ rc = (jlong)gdk_content_serializer_get_output_stream((GdkContentSerializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1serializer_1get_1output_1stream_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1serializer_1get_1priority
+JNIEXPORT jint JNICALL GTK4_NATIVE(gdk_1content_1serializer_1get_1priority)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jint rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1serializer_1get_1priority_FUNC);
+ rc = (jint)gdk_content_serializer_get_priority((GdkContentSerializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1serializer_1get_1priority_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1serializer_1get_1task_1data
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1serializer_1get_1task_1data)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1serializer_1get_1task_1data_FUNC);
+ rc = (jlong)gdk_content_serializer_get_task_data((GdkContentSerializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1serializer_1get_1task_1data_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1serializer_1get_1user_1data
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1serializer_1get_1user_1data)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1serializer_1get_1user_1data_FUNC);
+ rc = (jlong)gdk_content_serializer_get_user_data((GdkContentSerializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1serializer_1get_1user_1data_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1serializer_1get_1value
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1serializer_1get_1value)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1serializer_1get_1value_FUNC);
+ rc = (jlong)gdk_content_serializer_get_value((GdkContentSerializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1serializer_1get_1value_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_gdk_1content_1serializer_1return_1error
+JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1serializer_1return_1error)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1)
+{
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1serializer_1return_1error_FUNC);
+ gdk_content_serializer_return_error((GdkContentSerializer*)arg0, (GError*)arg1);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1serializer_1return_1error_FUNC);
+}
+#endif
+
+#ifndef NO_gdk_1content_1serializer_1return_1success
+JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1serializer_1return_1success)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1serializer_1return_1success_FUNC);
+ gdk_content_serializer_return_success((GdkContentSerializer*)arg0);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1serializer_1return_1success_FUNC);
+}
+#endif
+
+#ifndef NO_gdk_1content_1serializer_1set_1task_1data
+JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1serializer_1set_1task_1data)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2)
+{
+ GTK4_NATIVE_ENTER(env, that, gdk_1content_1serializer_1set_1task_1data_FUNC);
+ gdk_content_serializer_set_task_data((GdkContentSerializer*)arg0, (gpointer)arg1, (GDestroyNotify)arg2);
+ GTK4_NATIVE_EXIT(env, that, gdk_1content_1serializer_1set_1task_1data_FUNC);
+}
+#endif
+
#ifndef NO_gdk_1toplevel_1focus
JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1toplevel_1focus)
(JNIEnv *env, jclass that, jlong arg0, jint arg1)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
index 39dc470cb09..4cd87e8840f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
@@ -22,9 +22,25 @@
typedef enum {
gdk_1clipboard_1get_1content_FUNC,
gdk_1clipboard_1get_1formats_FUNC,
+ gdk_1clipboard_1is_1local_FUNC,
+ gdk_1clipboard_1read_1async_FUNC,
+ gdk_1clipboard_1read_1finish_FUNC,
+ gdk_1clipboard_1read_1value_1async_FUNC,
+ gdk_1clipboard_1read_1value_1finish_FUNC,
gdk_1clipboard_1set_FUNC,
gdk_1clipboard_1set_1content_FUNC,
gdk_1clipboard_1set_1text_FUNC,
+ gdk_1content_1deserializer_1get_1cancellable_FUNC,
+ gdk_1content_1deserializer_1get_1gtype_FUNC,
+ gdk_1content_1deserializer_1get_1input_1stream_FUNC,
+ gdk_1content_1deserializer_1get_1mime_1type_FUNC,
+ gdk_1content_1deserializer_1get_1priority_FUNC,
+ gdk_1content_1deserializer_1get_1task_1data_FUNC,
+ gdk_1content_1deserializer_1get_1user_1data_FUNC,
+ gdk_1content_1deserializer_1get_1value_FUNC,
+ gdk_1content_1deserializer_1return_1error_FUNC,
+ gdk_1content_1deserializer_1return_1success_FUNC,
+ gdk_1content_1deserializer_1set_1task_1data_FUNC,
gdk_1content_1formats_1builder_1add_1mime_1type_FUNC,
gdk_1content_1formats_1builder_1free_1to_1formats_FUNC,
gdk_1content_1formats_1builder_1new_FUNC,
@@ -34,6 +50,19 @@ typedef enum {
gdk_1content_1provider_1new_1for_1value_FUNC,
gdk_1content_1provider_1new_1typed_FUNC,
gdk_1content_1provider_1new_1union_FUNC,
+ gdk_1content_1register_1deserializer_FUNC,
+ gdk_1content_1register_1serializer_FUNC,
+ gdk_1content_1serializer_1get_1cancellable_FUNC,
+ gdk_1content_1serializer_1get_1gtype_FUNC,
+ gdk_1content_1serializer_1get_1mime_1type_FUNC,
+ gdk_1content_1serializer_1get_1output_1stream_FUNC,
+ gdk_1content_1serializer_1get_1priority_FUNC,
+ gdk_1content_1serializer_1get_1task_1data_FUNC,
+ gdk_1content_1serializer_1get_1user_1data_FUNC,
+ gdk_1content_1serializer_1get_1value_FUNC,
+ gdk_1content_1serializer_1return_1error_FUNC,
+ gdk_1content_1serializer_1return_1success_FUNC,
+ gdk_1content_1serializer_1set_1task_1data_FUNC,
gdk_1toplevel_1focus_FUNC,
gdk_1toplevel_1get_1state_FUNC,
gdk_1toplevel_1lower_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
index 57579f46e21..ae7076efac8 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
@@ -10079,6 +10079,18 @@ JNIEXPORT jint JNICALL OS_NATIVE(GValue_1sizeof)
}
#endif
+#ifndef NO_G_1IS_1VALUE
+JNIEXPORT jboolean JNICALL OS_NATIVE(G_1IS_1VALUE)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jboolean rc = 0;
+ OS_NATIVE_ENTER(env, that, G_1IS_1VALUE_FUNC);
+ rc = (jboolean)G_IS_VALUE(arg0);
+ OS_NATIVE_EXIT(env, that, G_1IS_1VALUE_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_G_1OBJECT_1CLASS_1CONSTRUCTOR
JNIEXPORT jlong JNICALL OS_NATIVE(G_1OBJECT_1CLASS_1CONSTRUCTOR)
(JNIEnv *env, jclass that, jlong arg0)
@@ -10233,6 +10245,18 @@ JNIEXPORT jlong JNICALL OS_NATIVE(G_1VALUE_1TYPE)
}
#endif
+#ifndef NO_G_1VALUE_1TYPE_1NAME
+JNIEXPORT jlong JNICALL OS_NATIVE(G_1VALUE_1TYPE_1NAME)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, G_1VALUE_1TYPE_1NAME_FUNC);
+ rc = (jlong)G_VALUE_TYPE_NAME(arg0);
+ OS_NATIVE_EXIT(env, that, G_1VALUE_1TYPE_1NAME_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_PANGO_1PIXELS
JNIEXPORT jint JNICALL OS_NATIVE(PANGO_1PIXELS)
(JNIEnv *env, jclass that, jint arg0)
@@ -11478,6 +11502,18 @@ JNIEXPORT jint JNICALL OS_NATIVE(g_1idle_1add)
}
#endif
+#ifndef NO_g_1io_1error_1quark
+JNIEXPORT jint JNICALL OS_NATIVE(g_1io_1error_1quark)
+ (JNIEnv *env, jclass that)
+{
+ jint rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1io_1error_1quark_FUNC);
+ rc = (jint)g_io_error_quark();
+ OS_NATIVE_EXIT(env, that, g_1io_1error_1quark_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_g_1list_1append
JNIEXPORT jlong JNICALL OS_NATIVE(g_1list_1append)
(JNIEnv *env, jclass that, jlong arg0, jlong arg1)
@@ -11794,6 +11830,78 @@ JNIEXPORT jlong JNICALL OS_NATIVE(g_1memory_1input_1stream_1new_1from_1data)
}
#endif
+#ifndef NO_g_1memory_1output_1stream_1get_1data
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1memory_1output_1stream_1get_1data)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1memory_1output_1stream_1get_1data_FUNC);
+ rc = (jlong)g_memory_output_stream_get_data((GMemoryOutputStream*)arg0);
+ OS_NATIVE_EXIT(env, that, g_1memory_1output_1stream_1get_1data_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_g_1memory_1output_1stream_1get_1data_1size
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1memory_1output_1stream_1get_1data_1size)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1memory_1output_1stream_1get_1data_1size_FUNC);
+ rc = (jlong)g_memory_output_stream_get_data_size((GMemoryOutputStream*)arg0);
+ OS_NATIVE_EXIT(env, that, g_1memory_1output_1stream_1get_1data_1size_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_g_1memory_1output_1stream_1get_1size
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1memory_1output_1stream_1get_1size)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1memory_1output_1stream_1get_1size_FUNC);
+ rc = (jlong)g_memory_output_stream_get_size((GMemoryOutputStream*)arg0);
+ OS_NATIVE_EXIT(env, that, g_1memory_1output_1stream_1get_1size_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_g_1memory_1output_1stream_1new_1resizable
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1memory_1output_1stream_1new_1resizable)
+ (JNIEnv *env, jclass that)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1memory_1output_1stream_1new_1resizable_FUNC);
+ rc = (jlong)g_memory_output_stream_new_resizable();
+ OS_NATIVE_EXIT(env, that, g_1memory_1output_1stream_1new_1resizable_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_g_1memory_1output_1stream_1steal_1as_1bytes
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1memory_1output_1stream_1steal_1as_1bytes)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1memory_1output_1stream_1steal_1as_1bytes_FUNC);
+ rc = (jlong)g_memory_output_stream_steal_as_bytes((GMemoryOutputStream*)arg0);
+ OS_NATIVE_EXIT(env, that, g_1memory_1output_1stream_1steal_1as_1bytes_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_g_1memory_1output_1stream_1steal_1data
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1memory_1output_1stream_1steal_1data)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1memory_1output_1stream_1steal_1data_FUNC);
+ rc = (jlong)g_memory_output_stream_steal_data((GMemoryOutputStream*)arg0);
+ OS_NATIVE_EXIT(env, that, g_1memory_1output_1stream_1steal_1data_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_g_1menu_1insert_1item
JNIEXPORT void JNICALL OS_NATIVE(g_1menu_1insert_1item)
(JNIEnv *env, jclass that, jlong arg0, jint arg1, jlong arg2)
@@ -12124,6 +12232,80 @@ JNIEXPORT void JNICALL OS_NATIVE(g_1object_1unref)
}
#endif
+#ifndef NO_g_1output_1stream_1splice_1async
+JNIEXPORT void JNICALL OS_NATIVE(g_1output_1stream_1splice_1async)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jint arg2, jint arg3, jlong arg4, jlong arg5, jlong arg6)
+{
+ OS_NATIVE_ENTER(env, that, g_1output_1stream_1splice_1async_FUNC);
+ g_output_stream_splice_async((GOutputStream*)arg0, (GInputStream *)arg1, (GOutputStreamSpliceFlags)arg2, (int)arg3, (GCancellable *)arg4, (GAsyncReadyCallback)arg5, (gpointer)arg6);
+ OS_NATIVE_EXIT(env, that, g_1output_1stream_1splice_1async_FUNC);
+}
+#endif
+
+#ifndef NO_g_1output_1stream_1splice_1finish
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1output_1stream_1splice_1finish)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2)
+{
+ jlong *lparg2=NULL;
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1output_1stream_1splice_1finish_FUNC);
+ if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
+ rc = (jlong)g_output_stream_splice_finish((GOutputStream*)arg0, (GAsyncResult*)arg1, (GError**)lparg2);
+fail:
+ if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0);
+ OS_NATIVE_EXIT(env, that, g_1output_1stream_1splice_1finish_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_g_1output_1stream_1write_1all
+JNIEXPORT jboolean JNICALL OS_NATIVE(g_1output_1stream_1write_1all)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jlongArray arg3, jlong arg4, jlongArray arg5)
+{
+ jlong *lparg3=NULL;
+ jlong *lparg5=NULL;
+ jboolean rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1output_1stream_1write_1all_FUNC);
+ if (arg3) if ((lparg3 = (*env)->GetLongArrayElements(env, arg3, NULL)) == NULL) goto fail;
+ if (arg5) if ((lparg5 = (*env)->GetLongArrayElements(env, arg5, NULL)) == NULL) goto fail;
+ rc = (jboolean)g_output_stream_write_all((GOutputStream*)arg0, (void*)arg1, (gsize)arg2, (gsize*)lparg3, (GCancellable*)arg4, (GError**)lparg5);
+fail:
+ if (arg5 && lparg5) (*env)->ReleaseLongArrayElements(env, arg5, lparg5, 0);
+ if (arg3 && lparg3) (*env)->ReleaseLongArrayElements(env, arg3, lparg3, 0);
+ OS_NATIVE_EXIT(env, that, g_1output_1stream_1write_1all_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_g_1output_1stream_1write_1all_1async
+JNIEXPORT void JNICALL OS_NATIVE(g_1output_1stream_1write_1all_1async)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jint arg3, jlong arg4, jlong arg5, jlong arg6)
+{
+ OS_NATIVE_ENTER(env, that, g_1output_1stream_1write_1all_1async_FUNC);
+ g_output_stream_write_all_async((GOutputStream*)arg0, (void*)arg1, (gsize)arg2, (int)arg3, (GCancellable*)arg4, (GAsyncReadyCallback)arg5, (gpointer)arg6);
+ OS_NATIVE_EXIT(env, that, g_1output_1stream_1write_1all_1async_FUNC);
+}
+#endif
+
+#ifndef NO_g_1output_1stream_1write_1all_1finish
+JNIEXPORT jboolean JNICALL OS_NATIVE(g_1output_1stream_1write_1all_1finish)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2, jlongArray arg3)
+{
+ jlong *lparg2=NULL;
+ jlong *lparg3=NULL;
+ jboolean rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1output_1stream_1write_1all_1finish_FUNC);
+ if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
+ if (arg3) if ((lparg3 = (*env)->GetLongArrayElements(env, arg3, NULL)) == NULL) goto fail;
+ rc = (jboolean)g_output_stream_write_all_finish((GOutputStream*)arg0, (GAsyncResult*)arg1, (gsize*)lparg2, (GError**)lparg3);
+fail:
+ if (arg3 && lparg3) (*env)->ReleaseLongArrayElements(env, arg3, lparg3, 0);
+ if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0);
+ OS_NATIVE_EXIT(env, that, g_1output_1stream_1write_1all_1finish_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_g_1quark_1from_1string
JNIEXPORT jint JNICALL OS_NATIVE(g_1quark_1from_1string)
(JNIEnv *env, jclass that, jbyteArray arg0)
@@ -12626,6 +12808,18 @@ JNIEXPORT jboolean JNICALL OS_NATIVE(g_1type_1is_1a)
}
#endif
+#ifndef NO_g_1type_1name
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1type_1name)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1type_1name_FUNC);
+ rc = (jlong)g_type_name((GType)arg0);
+ OS_NATIVE_EXIT(env, that, g_1type_1name_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_g_1type_1parent
JNIEXPORT jlong JNICALL OS_NATIVE(g_1type_1parent)
(JNIEnv *env, jclass that, jlong arg0)
@@ -12851,6 +13045,18 @@ JNIEXPORT jlong JNICALL OS_NATIVE(g_1utf8_1to_1utf16___3BJ_3J_3J_3J)
}
#endif
+#ifndef NO_g_1value_1get_1boxed
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1value_1get_1boxed)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1value_1get_1boxed_FUNC);
+ rc = (jlong)g_value_get_boxed((const GValue *)arg0);
+ OS_NATIVE_EXIT(env, that, g_1value_1get_1boxed_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_g_1value_1get_1double
JNIEXPORT jdouble JNICALL OS_NATIVE(g_1value_1get_1double)
(JNIEnv *env, jclass that, jlong arg0)
@@ -12875,6 +13081,18 @@ JNIEXPORT jfloat JNICALL OS_NATIVE(g_1value_1get_1float)
}
#endif
+#ifndef NO_g_1value_1get_1gtype
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1value_1get_1gtype)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1value_1get_1gtype_FUNC);
+ rc = (jlong)g_value_get_gtype((const GValue *)arg0);
+ OS_NATIVE_EXIT(env, that, g_1value_1get_1gtype_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_g_1value_1get_1int
JNIEXPORT jint JNICALL OS_NATIVE(g_1value_1get_1int)
(JNIEnv *env, jclass that, jlong arg0)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c
index 2b26e5a7ff7..e92dd85a90f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c
@@ -2232,3 +2232,34 @@ swt_releaseArrayOfStringsUTF(JNIEnv *env, jobjectArray javaArray, char **cString
}
free(cStrings);
}
+
+static void *string_boxed_copy(void *ptr) {
+ return ptr;
+}
+
+static void string_boxed_free(void *ptr) {
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(register_1gtype_1for_1name)
+ (JNIEnv *env, jclass that, jstring name)
+{
+ long rc;
+ const char *lpname = NULL;
+ OS_NATIVE_ENTER(env, that, register_1gtype_1for_1name_FUNC)
+ if (name) lpname= (const char *) (*env)->GetStringUTFChars(env, name, NULL);
+ rc = g_boxed_type_register_static(lpname, string_boxed_copy, string_boxed_free);
+ if (name && lpname) (*env)->ReleaseStringUTFChars(env, name, lpname);
+ OS_NATIVE_EXIT(env, that, register_1gtype_1for_1name_FUNC)
+ return rc;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(create_1gvalue)
+ (JNIEnv *env, jclass that, jlong gtype, jlong value)
+{
+ OS_NATIVE_ENTER(env, that, create_1gvalue_FUNC)
+ GValue *v = g_new0 (GValue, 1);
+ g_value_init(v, (GType)gtype);
+ g_value_take_boxed(v, (void *)value);
+ OS_NATIVE_EXIT(env, that, create_1gvalue_FUNC)
+ return (jlong)v;
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
index a83c778d8ee..b83d217a8fe 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
@@ -824,6 +824,7 @@ typedef enum {
GPollFD_1sizeof_FUNC,
GTypeInfo_1sizeof_FUNC,
GValue_1sizeof_FUNC,
+ G_1IS_1VALUE_FUNC,
G_1OBJECT_1CLASS_1CONSTRUCTOR_FUNC,
G_1OBJECT_1CLASS_1SET_1CONSTRUCTOR_FUNC,
G_1OBJECT_1GET_1CLASS_FUNC,
@@ -837,6 +838,7 @@ typedef enum {
G_1TYPE_1LONG_FUNC,
G_1TYPE_1STRING_FUNC,
G_1VALUE_1TYPE_FUNC,
+ G_1VALUE_1TYPE_1NAME_FUNC,
PANGO_1PIXELS_FUNC,
PANGO_1TYPE_1FONT_1DESCRIPTION_FUNC,
PANGO_1TYPE_1FONT_1FACE_FUNC,
@@ -870,6 +872,7 @@ typedef enum {
call__JJJJJ_FUNC,
call__JJJJJJJ_FUNC,
call__JJJJJJJJ_FUNC,
+ create_1gvalue_FUNC,
g_1action_1get_1enabled_FUNC,
g_1action_1get_1state_FUNC,
g_1action_1map_1add_1action_FUNC,
@@ -928,6 +931,7 @@ typedef enum {
g_1icon_1new_1for_1string_FUNC,
g_1icon_1to_1string_FUNC,
g_1idle_1add_FUNC,
+ g_1io_1error_1quark_FUNC,
g_1list_1append_FUNC,
g_1list_1data_FUNC,
g_1list_1free_FUNC,
@@ -954,6 +958,12 @@ typedef enum {
g_1main_1context_1wakeup_FUNC,
g_1malloc_FUNC,
g_1memory_1input_1stream_1new_1from_1data_FUNC,
+ g_1memory_1output_1stream_1get_1data_FUNC,
+ g_1memory_1output_1stream_1get_1data_1size_FUNC,
+ g_1memory_1output_1stream_1get_1size_FUNC,
+ g_1memory_1output_1stream_1new_1resizable_FUNC,
+ g_1memory_1output_1stream_1steal_1as_1bytes_FUNC,
+ g_1memory_1output_1stream_1steal_1data_FUNC,
g_1menu_1insert_1item_FUNC,
g_1menu_1item_1new_FUNC,
g_1menu_1item_1new_1section_FUNC,
@@ -978,6 +988,11 @@ typedef enum {
g_1object_1set__J_3B_3BJ_FUNC,
g_1object_1set_1qdata_FUNC,
g_1object_1unref_FUNC,
+ g_1output_1stream_1splice_1async_FUNC,
+ g_1output_1stream_1splice_1finish_FUNC,
+ g_1output_1stream_1write_1all_FUNC,
+ g_1output_1stream_1write_1all_1async_FUNC,
+ g_1output_1stream_1write_1all_1finish_FUNC,
g_1quark_1from_1string_FUNC,
g_1set_1prgname_FUNC,
g_1signal_1add_1emission_1hook_FUNC,
@@ -1017,6 +1032,7 @@ typedef enum {
g_1type_1class_1unref_FUNC,
g_1type_1interface_1peek_1parent_FUNC,
g_1type_1is_1a_FUNC,
+ g_1type_1name_FUNC,
g_1type_1parent_FUNC,
g_1type_1register_1static_FUNC,
g_1unsetenv_FUNC,
@@ -1031,8 +1047,10 @@ typedef enum {
g_1utf8_1strlen_FUNC,
g_1utf8_1to_1utf16__JJ_3J_3J_3J_FUNC,
g_1utf8_1to_1utf16___3BJ_3J_3J_3J_FUNC,
+ g_1value_1get_1boxed_FUNC,
g_1value_1get_1double_FUNC,
g_1value_1get_1float_FUNC,
+ g_1value_1get_1gtype_FUNC,
g_1value_1get_1int_FUNC,
g_1value_1get_1int64_FUNC,
g_1value_1get_1object_FUNC,
@@ -1203,6 +1221,7 @@ typedef enum {
pango_1version_FUNC,
printerOptionWidgetNewProc_1CALLBACK_FUNC,
realpath_FUNC,
+ register_1gtype_1for_1name_FUNC,
strcmp_FUNC,
swt_1debug_1on_1fatal_1warnings_FUNC,
swt_1fixed_1accessible_1get_1type_FUNC,
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 c319bbac70b..2731e4e83bb 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
@@ -155,7 +155,85 @@ public static String getEnvironmentalVariable (String envVarName) {
}
/** Constants */
+ /* enum GFileError */
+ public static final int G_FILE_ERROR_EXIST = 0;
+ public static final int G_FILE_ERROR_ISDIR = 1;
+ public static final int G_FILE_ERROR_ACCES = 2;
+ public static final int G_FILE_ERROR_NAMETOOLONG = 3;
+ public static final int G_FILE_ERROR_NOENT = 4;
+ public static final int G_FILE_ERROR_NOTDIR = 5;
+ public static final int G_FILE_ERROR_NXIO = 6;
+ public static final int G_FILE_ERROR_NODEV = 7;
+ public static final int G_FILE_ERROR_ROFS = 8;
+ public static final int G_FILE_ERROR_TXTBSY = 9;
+ public static final int G_FILE_ERROR_FAULT = 10;
+ public static final int G_FILE_ERROR_LOOP = 11;
+ public static final int G_FILE_ERROR_NOSPC = 12;
+ public static final int G_FILE_ERROR_NOMEM = 13;
+ public static final int G_FILE_ERROR_MFILE = 14;
+ public static final int G_FILE_ERROR_NFILE = 15;
+ public static final int G_FILE_ERROR_BADF = 16;
+ public static final int G_FILE_ERROR_INVAL = 17;
+ public static final int G_FILE_ERROR_PIPE = 18;
+ public static final int G_FILE_ERROR_AGAIN = 19;
+ public static final int G_FILE_ERROR_INTR = 20;
public static final int G_FILE_ERROR_IO = 21;
+ public static final int G_FILE_ERROR_PERM = 22;
+ public static final int G_FILE_ERROR_NOSYS = 23;
+ public static final int G_FILE_ERROR_FAILED = 24;
+
+ /* enum GIOErrorEnum */
+ public static final int G_IO_ERROR_FAILED = 0;
+ public static final int G_IO_ERROR_NOT_FOUND = 1;
+ public static final int G_IO_ERROR_EXISTS = 2;
+ public static final int G_IO_ERROR_IS_DIRECTORY = 3;
+ public static final int G_IO_ERROR_NOT_DIRECTORY = 4;
+ public static final int G_IO_ERROR_NOT_EMPTY = 5;
+ public static final int G_IO_ERROR_NOT_REGULAR_FILE = 6;
+ public static final int G_IO_ERROR_NOT_SYMBOLIC_LINK = 7;
+ public static final int G_IO_ERROR_NOT_MOUNTABLE_FILE = 8;
+ public static final int G_IO_ERROR_FILENAME_TOO_LONG = 9;
+ public static final int G_IO_ERROR_INVALID_FILENAME = 10;
+ public static final int G_IO_ERROR_TOO_MANY_LINKS = 11;
+ public static final int G_IO_ERROR_NO_SPACE = 12;
+ public static final int G_IO_ERROR_INVALID_ARGUMENT = 13;
+ public static final int G_IO_ERROR_PERMISSION_DENIED = 14;
+ public static final int G_IO_ERROR_NOT_SUPPORTED = 15;
+ public static final int G_IO_ERROR_NOT_MOUNTED = 16;
+ public static final int G_IO_ERROR_ALREADY_MOUNTED = 17;
+ public static final int G_IO_ERROR_CLOSED = 18;
+ public static final int G_IO_ERROR_CANCELLED = 19;
+ public static final int G_IO_ERROR_PENDING = 20;
+ public static final int G_IO_ERROR_READ_ONLY = 21;
+ public static final int G_IO_ERROR_CANT_CREATE_BACKUP = 22;
+ public static final int G_IO_ERROR_WRONG_ETAG = 23;
+ public static final int G_IO_ERROR_TIMED_OUT = 24;
+ public static final int G_IO_ERROR_WOULD_RECURSE = 25;
+ public static final int G_IO_ERROR_BUSY = 26;
+ public static final int G_IO_ERROR_WOULD_BLOCK = 27;
+ public static final int G_IO_ERROR_HOST_NOT_FOUND = 28;
+ public static final int G_IO_ERROR_WOULD_MERGE = 29;
+ public static final int G_IO_ERROR_FAILED_HANDLED = 30;
+ public static final int G_IO_ERROR_TOO_MANY_OPEN_FILES = 31;
+ public static final int G_IO_ERROR_NOT_INITIALIZED = 32;
+ public static final int G_IO_ERROR_ADDRESS_IN_USE = 33;
+ public static final int G_IO_ERROR_PARTIAL_INPUT = 34;
+ public static final int G_IO_ERROR_INVALID_DATA = 35;
+ public static final int G_IO_ERROR_DBUS_ERROR = 36;
+ public static final int G_IO_ERROR_HOST_UNREACHABLE = 37;
+ public static final int G_IO_ERROR_NETWORK_UNREACHABLE = 38;
+ public static final int G_IO_ERROR_CONNECTION_REFUSED = 39;
+ public static final int G_IO_ERROR_PROXY_FAILED = 40;
+ public static final int G_IO_ERROR_PROXY_AUTH_FAILED = 41;
+ public static final int G_IO_ERROR_PROXY_NEED_AUTH = 42;
+ public static final int G_IO_ERROR_PROXY_NOT_ALLOWED = 43;
+ public static final int G_IO_ERROR_BROKEN_PIPE = 44;
+ public static final int G_IO_ERROR_CONNECTION_CLOSED = G_IO_ERROR_BROKEN_PIPE;
+ public static final int G_IO_ERROR_NOT_CONNECTED = 45;
+ public static final int G_IO_ERROR_MESSAGE_TOO_LARGE = 46;
+ public static final int G_IO_ERROR_NO_SUCH_DEVICE = 47;
+ public static final int G_IO_ERROR_DESTINATION_UNSET = 48;
+
public static final int G_FILE_TEST_IS_DIR = 1 << 2;
public static final int G_FILE_TEST_IS_EXECUTABLE = 1 << 3;
public static final int G_SIGNAL_MATCH_DATA = 1 << 4;
@@ -165,6 +243,10 @@ public static String getEnvironmentalVariable (String envVarName) {
public static final int G_LOG_LEVEL_MASK = 0xfffffffc;
public static final int G_APP_INFO_CREATE_NONE = 0;
public static final int G_APP_INFO_CREATE_SUPPORTS_URIS = (1 << 1);
+ public static final int G_OUTPUT_STREAM_SPLICE_NONE = 0;
+ public static final int G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE = (1 << 0);
+ public static final int G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET = (1 << 1);
+ public static final int G_PRIORITY_DEFAULT = 0;
public static final int GTK_TYPE_TEXT_BUFFER = 21;
public static final int PANGO_ALIGN_LEFT = 0;
public static final int PANGO_ALIGN_CENTER = 1;
@@ -567,6 +649,33 @@ public static String getEnvironmentalVariable (String envVarName) {
/* custom version of g_utf8 for 16 bit */
public static final native long g_utf16_offset_to_utf8_offset(long str, long offset);
+ /**
+ * Creates a GType for the given name. The name must be unique for the lifetime
+ * of the process.
+ *
+ * This gives a unique GType to register in GTK4's serializers.
+ *
+ * @param name The name of the type - must be unique
+ * @return the new GType - the data is owned by GTK and must not be freed
+ * @method flags=no_gen
+ * @category custom
+ */
+ // TODO this is too generic a name - this method is only for use with ContentProvider
+ public static final native long register_gtype_for_name(String name);
+
+ /**
+ * Creates a GValue for the given GType, when that GType was created by
+ * {@link #register_gtype_for_name(String)}
+ *
+ * @param gtype the type created with {@link #register_gtype_for_name(String)}
+ * @param value a non-zero value to store in the gvalue of type gtype
+ * @return the new GValue - the data is owned by the caller of the method
+ * @method flags=no_gen
+ * @category custom
+ */
+ // TODO this is too generic a name - this method is only for use with ContentProvider
+ public static final native long create_gvalue(long gtype, long value);
+
/** CUSTOM_CODE END */
/**
@@ -847,6 +956,8 @@ public static boolean isX11 () {
/** @method flags=const */
public static final native long G_TYPE_INT64();
public static final native long G_VALUE_TYPE(long value);
+public static final native long G_VALUE_TYPE_NAME(long value);
+public static final native boolean G_IS_VALUE(long value);
public static final native long G_OBJECT_TYPE(long instance);
/** @method flags=const */
public static final native long G_TYPE_STRING();
@@ -932,6 +1043,7 @@ public static boolean isX11 () {
*/
public static final native boolean g_content_type_is_a(long type, byte[] supertype);
public static final native int g_file_error_quark();
+public static final native int g_io_error_quark();
/**
* @param info cast=(GFileInfo *)
*/
@@ -1332,6 +1444,11 @@ public static boolean isX11 () {
public static final native void g_type_class_unref(long g_class);
/** @param iface cast=(gpointer) */
public static final native long g_type_interface_peek_parent(long iface);
+/**
+ * @param g_type cast=(GType)
+ * @return char * that must be freed
+ */
+public static final native long g_type_name(long g_type);
/**
* @param type cast=(GType)
* @param is_a_type cast=(GType)
@@ -1410,6 +1527,11 @@ public static boolean isX11 () {
public static final native void g_value_unset (long value);
/** @param value cast=(const GValue *) */
public static final native long g_value_peek_pointer(long value);
+/** @param value cast=(const GValue *) */
+public static final native long g_value_get_boxed(long value);
+/** @param value cast=(const GValue *) */
+public static final native long g_value_get_gtype(long value);
+
/**
* @param variable cast=(const gchar *),flags=no_out
*/
@@ -2331,4 +2453,71 @@ public static final native long g_dbus_proxy_new_for_bus_sync(int bus_type, int
*/
public static final native long g_memory_input_stream_new_from_data(long data, long len, long destroy);
+/**
+ * @param stream cast=(GOutputStream*)
+ * @param source cast=(GInputStream *)
+ * @param flags cast=(GOutputStreamSpliceFlags)
+ * @param io_priority cast=(int)
+ * @param cancellable cast=(GCancellable *)
+ * @param callback cast=(GAsyncReadyCallback)
+ * @param user_data cast=(gpointer)
+ */
+public static final native void g_output_stream_splice_async(long stream, long source, int flags, int io_priority, long cancellable, long callback, long user_data);
+/**
+ * @param stream cast=(GOutputStream*)
+ * @param result cast=(GAsyncResult*)
+ * @param error cast=(GError**)
+ */
+public static final native long g_output_stream_splice_finish(long stream, long result, long[] error);
+/**
+ *
+ */
+public static final native long g_memory_output_stream_new_resizable();
+/**
+ * @param ostream cast=(GMemoryOutputStream*)
+ */
+public static final native long g_memory_output_stream_get_data(long ostream);
+/**
+ * @param ostream cast=(GMemoryOutputStream*)
+ */
+public static final native long g_memory_output_stream_get_size(long ostream);
+/**
+ * @param ostream cast=(GMemoryOutputStream*)
+ */
+public static final native long g_memory_output_stream_get_data_size(long ostream);
+/**
+ * @param ostream cast=(GMemoryOutputStream*)
+ */
+public static final native long g_memory_output_stream_steal_data(long ostream);
+/**
+ * @param ostream cast=(GMemoryOutputStream*)
+ */
+public static final native long g_memory_output_stream_steal_as_bytes(long ostream);
+/**
+ * @param stream cast=(GOutputStream*)
+ * @param buffer cast=(void*)
+ * @param count cast=(gsize)
+ * @param bytes_written cast=(gsize*)
+ * @param cancellable cast=(GCancellable*)
+ * @param error cast=(GError**)
+ */
+public static final native boolean g_output_stream_write_all(long stream, long buffer, long count, long[] bytes_written, long cancellable, long[] error);
+/**
+ * @param stream cast=(GOutputStream*)
+ * @param buffer cast=(void*)
+ * @param count cast=(gsize)
+ * @param io_priority cast=(int)
+ * @param cancellable cast=(GCancellable*)
+ * @param callback cast=(GAsyncReadyCallback)
+ * @param user_data cast=(gpointer)
+ */
+public static final native void g_output_stream_write_all_async(long stream, long buffer, long count, int io_priority, long cancellable, long callback, long user_data);
+/**
+ *
+ * @param stream cast=(GOutputStream*)
+ * @param result cast=(GAsyncResult*)
+ * @param bytes_written cast=(gsize*)
+ * @param error cast=(GError**)
+ */
+public static final native boolean g_output_stream_write_all_finish(long stream, long result, long[] bytes_written, long[] error);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
index 48ceb120d5c..6fb27115481 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
@@ -838,6 +838,42 @@ public class GTK4 {
* @param clipboard cast=(GdkClipboard*)
*/
public static final native long gdk_clipboard_get_content(long clipboard);
+ /**
+ * @param clipboard cast=(GdkClipboard*)
+ * @param type cast=(GType)
+ * @param io_priority cast=(int)
+ * @param cancellable cast=(GCancellable *)
+ * @param callback cast=(GAsyncReadyCallback)
+ * @param user_data cast=(gpointer)
+ */
+ public static final native void gdk_clipboard_read_value_async(long clipboard, long type, int io_priority, long cancellable, long callback, long user_data);
+ /**
+ * @param clipboard cast=(GdkClipboard*)
+ * @param result cast=(GAsyncResult *)
+ * @param error cast=(GError **)
+ */
+ public static final native long gdk_clipboard_read_value_finish(long clipboard, long result, long[] error);
+ /**
+ * @param clipboard cast=(GdkClipboard*)
+ * @param mime_types cast=(const char **)
+ * @param io_priority cast=(int)
+ * @param cancellable cast=(GCancellable *)
+ * @param callback cast=(GAsyncReadyCallback)
+ * @param user_data cast=(gpointer)
+ */
+ public static final native void gdk_clipboard_read_async(long clipboard, String[] mime_types, int io_priority, long cancellable, long callback, long user_data);
+ /**
+ * @param clipboard cast=(GdkClipboard*)
+ * @param result cast=(GAsyncResult *)
+ * @param out_mime_type cast=(const char**)
+ * @param error cast=(GError **)
+ */
+ public static final native long gdk_clipboard_read_finish(long clipboard, long result, long[] out_mime_type, long[] error);
+ /**
+ * @param clipboard cast=(GdkClipboard*)
+ */
+ public static final native boolean gdk_clipboard_is_local(long clipboard);
+
/**
* @param provider cast=(GdkContentProvider *)
* @param value cast=(GValue *)
@@ -865,6 +901,118 @@ public class GTK4 {
*/
public static final native long gdk_content_formats_get_gtypes(long formats, long[] n_gtypes);
+ /**
+ * @param type cast=(GType)
+ * @param mime_type cast=(const char*)
+ * @param serialize cast=(GdkContentSerializeFunc)
+ * @param data cast=(gpointer)
+ * @param notify cast=(GDestroyNotify)
+ */
+ public static final native void gdk_content_register_serializer(long type, String mime_type, long serialize, long data, long notify);
+ /**
+ * @param serializer cast=(GdkContentSerializer*)
+ */
+ public static final native long gdk_content_serializer_get_cancellable(long serializer);
+ /**
+ * @param serializer cast=(GdkContentSerializer*)
+ */
+ public static final native long gdk_content_serializer_get_gtype(long serializer);
+ /**
+ * @param serializer cast=(GdkContentSerializer*)
+ */
+ public static final native long gdk_content_serializer_get_mime_type(long serializer);
+ /**
+ * @param serializer cast=(GdkContentSerializer*)
+ */
+ public static final native long gdk_content_serializer_get_output_stream(long serializer);
+ /**
+ * @param serializer cast=(GdkContentSerializer*)
+ */
+ public static final native int gdk_content_serializer_get_priority(long serializer);
+ /**
+ * @param serializer cast=(GdkContentSerializer*)
+ */
+ public static final native long gdk_content_serializer_get_task_data(long serializer);
+ /**
+ * @param serializer cast=(GdkContentSerializer*)
+ */
+ public static final native long gdk_content_serializer_get_user_data(long serializer);
+ /**
+ * @param serializer cast=(GdkContentSerializer*)
+ */
+ public static final native long gdk_content_serializer_get_value(long serializer);
+ /**
+ * @param serializer cast=(GdkContentSerializer*)
+ * @param error cast=(GError*)
+ */
+ public static final native void gdk_content_serializer_return_error(long serializer, long error);
+ /**
+ * @param serializer cast=(GdkContentSerializer*)
+ */
+ public static final native void gdk_content_serializer_return_success(long serializer);
+ /**
+ * @param serializer cast=(GdkContentSerializer*)
+ * @param data cast=(gpointer)
+ * @param notify cast=(GDestroyNotify)
+ */
+ public static final native void gdk_content_serializer_set_task_data(long serializer, long data, long notify);
+ /**
+ * @param mime_type cast=(const char*)
+ * @param type cast=(GType)
+ * @param deserialize cast=(GdkContentDeserializeFunc)
+ * @param data cast=(gpointer)
+ * @param notify cast=(GDestroyNotify)
+ */
+ public static final native void gdk_content_register_deserializer(String mime_type, long type, long deserialize, long data, long notify);
+ /**
+ * @param deserializer cast=(GdkContentDeserializer*)
+ */
+ public static final native long gdk_content_deserializer_get_cancellable(long deserializer);
+ /**
+ * @param deserializer cast=(GdkContentDeserializer*)
+ */
+ public static final native long gdk_content_deserializer_get_gtype(long deserializer);
+ /**
+ * @param deserializer cast=(GdkContentDeserializer*)
+ */
+ public static final native long gdk_content_deserializer_get_input_stream(long deserializer);
+ /**
+ * @param deserializer cast=(GdkContentDeserializer*)
+ */
+ public static final native long gdk_content_deserializer_get_mime_type(long deserializer);
+ /**
+ * @param deserializer cast=(GdkContentDeserializer*)
+ */
+ public static final native int gdk_content_deserializer_get_priority(long deserializer);
+ /**
+ * @param deserializer cast=(GdkContentDeserializer*)
+ */
+ public static final native long gdk_content_deserializer_get_task_data(long deserializer);
+ /**
+ * @param deserializer cast=(GdkContentDeserializer*)
+ */
+ public static final native long gdk_content_deserializer_get_user_data(long deserializer);
+ /**
+ * @param deserializer cast=(GdkContentDeserializer*)
+ */
+ public static final native long gdk_content_deserializer_get_value(long deserializer);
+ /**
+ * @param deserializer cast=(GdkContentDeserializer*)
+ * @param error cast=(GError*)
+ */
+ public static final native void gdk_content_deserializer_return_error(long deserializer, long error);
+ /**
+ * @param deserializer cast=(GdkContentDeserializer*)
+ */
+ public static final native void gdk_content_deserializer_return_success(long deserializer);
+ /**
+ * @param deserializer cast=(GdkContentDeserializer*)
+ * @param data cast=(gpointer)
+ * @param notify cast=(GDestroyNotify)
+ */
+ public static final native void gdk_content_deserializer_set_task_data(long deserializer, long data, long notify);
+
+
public static final native long gtk_gesture_rotate_new();
public static final native long gtk_gesture_zoom_new();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/AsyncFinishUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/AsyncFinishUtil.java
new file mode 100644
index 00000000000..eb6ef6c9adf
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/AsyncFinishUtil.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2020, 2025 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.swt.internal;
+
+import java.lang.reflect.*;
+import java.util.function.*;
+
+import org.eclipse.swt.widgets.*;
+
+/**
+ * This class is an internal class based on {@link SyncDialogUtil} for the
+ * non-UI and reentrant parts of GTK4, such as the clipboard.
+ *
+ * The run method is non-blocking here!
+ */
+
+public class AsyncFinishUtil {
+ private Callback dialogResponseCallback;
+ private Function dialogAsyncFinish;
+ private Long dialogAsyncValue;
+
+ /**
+ * TODO: Write new javadoc here
+ */
+ public void run(Display display, AsyncReadyCallback callback) {
+ initializeResponseCallback();
+
+ dialogAsyncFinish = callback::await;
+ callback.async(dialogResponseCallback.getAddress());
+ }
+
+ /**
+ * Returns null until await (aka finish) method is called.
+ * Once await is finished, will have non-null return value from finish method
+ */
+ public Long getDialogAsyncValue() {
+ return dialogAsyncValue;
+ }
+
+ /**
+ * Initializes the response callback and resets the responseID of the dialog to
+ * the default value. This function should be called before connect the dialog
+ * to the "response" signal, as this sets up the callback.
+ */
+ private void initializeResponseCallback() {
+ dialogResponseCallback = new Callback(this, "dialogResponseProc", void.class,
+ new Type[] { long.class, long.class, long.class });
+ dialogAsyncValue = null;
+ }
+
+ private void disposeResponseCallback() {
+ dialogResponseCallback.dispose();
+ dialogResponseCallback = null;
+ dialogAsyncFinish = null;
+ }
+
+ void dialogResponseProc(long dialog, long response, long user_data) {
+ if (dialogAsyncFinish != null) {
+ dialogAsyncValue = dialogAsyncFinish.apply(response);
+ }
+ disposeResponseCallback();
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/SyncFinishCallback.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/SyncFinishCallback.java
new file mode 100644
index 00000000000..fd4b56e508d
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/SyncFinishCallback.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Patrick Ziegler and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Patrick Ziegler - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal;
+
+/**
+ * This class implements the GIO AsyncReadyCallback type and is used to
+ * transform an asynchronous {@code async} and synchronous {@code await}
+ * operation into a single synchronous {@code run} operation.
+ */
+public interface SyncFinishCallback {
+ /**
+ * This method is responsible for initializes the asynchronous operation
+ *
+ * @param callback The callback address to execute when the operation is
+ * complete.
+ */
+ void async(long callback);
+
+ /**
+ * This method is called from within the callback function in order to
+ * finish the executed operation and to return the result.
+ *
+ * @param result The generic, asynchronous function result.
+ * @return The specific result of the operation.
+ */
+ T await(long result);
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/SyncFinishUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/SyncFinishUtil.java
new file mode 100644
index 00000000000..f069ef32c53
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/SyncFinishUtil.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2020, 2025 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.swt.internal;
+
+import java.lang.reflect.*;
+import java.util.function.*;
+
+import org.eclipse.swt.widgets.*;
+
+/**
+ * This class is an internal class based on {@link SyncDialogUtil} for the
+ * non-UI and reentrant parts of GTK4, such as the clipboard.
+ *
+ * TODO should "org.eclipse.swt.internal.gtk.dispatchEvent" be set on display so
+ * that (very?) unrelated events aren't processed until we are done here? We
+ * need to process some unrelated events because one async operation could be
+ * writing to a stream another is reading from and they both need to run
+ * "simultaneously" for the operation to succeed.
+ */
+
+public class SyncFinishUtil {
+ private Callback dialogResponseCallback;
+ private Function dialogAsyncFinish;
+ private T dialogAsyncValue;
+ private boolean dialogAsyncValueSet;
+
+ /**
+ * This method implements the {@code AsyncReadyCallback} mechanism that is used
+ * in GTK4. Most operations within GTK4 are executed asynchronously, where the
+ * user is given the option to respond to the completion of such an operation
+ * via a callback method, in order to e.g. process the result or to apply
+ * additional cleanup tasks.
+ * When calling this method, the asynchronous operation is initiated via the
+ * {code asyncOpen} parameter. Callers have to ensure that the callback address
+ * is used as argument for the {@code AsyncReadyCallback} parameter. From within
+ * the callback routine, the {@code asyncFinish} function is called, receiving
+ * the {@code AsyncResult} of the callback as argument and returning the
+ * {@code long} value of the callback function.
+ * This method blocks until the callback method has been called. It is therefore
+ * essential that callers use the address of the {@link Callback} as address for
+ * the {@code AsyncReadyCallback} object.
+ */
+ public T run(Display display, SyncFinishCallback callback) {
+ System.out.println("Running SyncFinishUtil " + this.hashCode());
+ initializeResponseCallback();
+
+ dialogAsyncFinish = callback::await;
+ System.out.println("Running SyncFinishUtil await " + this.hashCode());
+ callback.async(dialogResponseCallback.getAddress());
+
+ System.out.println("Running SyncFinishUtil readAndDispatch " + this.hashCode());
+ while (!display.isDisposed()) {
+ if (dialogAsyncValueSet) {
+ break;
+ }
+ display.readAndDispatch();
+ }
+
+ disposeResponseCallback();
+ System.out.println("Running SyncFinishUtil FINISHED " + this.hashCode());
+ return dialogAsyncValue;
+ }
+
+ /**
+ * Initializes the response callback and resets the responseID of the dialog to
+ * the default value. This function should be called before connect the dialog
+ * to the "response" signal, as this sets up the callback.
+ */
+ private void initializeResponseCallback() {
+ dialogResponseCallback = new Callback(this, "dialogResponseProc", void.class,
+ new Type[] { long.class, long.class, long.class });
+ dialogAsyncValue = null;
+ dialogAsyncValueSet = false;
+ }
+
+ private void disposeResponseCallback() {
+ dialogResponseCallback.dispose();
+ dialogResponseCallback = null;
+ dialogAsyncFinish = null;
+ }
+
+ /**
+ * Callback function for the "response" signal in GtkDialog widgets.
+ * Responsibility of destroying the dialog is the owner of the dialog handle.
+ *
+ * Note: Native dialogs are platform dialogs that don't use GtkDialog or
+ * GtkWindow.
+ */
+ void dialogResponseProc(long dialog, long response, long user_data) {
+ System.out.println("Running SyncFinishUtil dialogResponseProc " + this.hashCode());
+ if (dialogAsyncFinish != null) {
+ System.out.println("Running SyncFinishUtil apply " + this.hashCode());
+ dialogAsyncValue = dialogAsyncFinish.apply(response);
+ System.out.println("Running SyncFinishUtil dialogAsyncValueSet " + this.hashCode());
+ dialogAsyncValueSet = true;
+ }
+ }
+}
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/ClipboardSwingTester.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/ClipboardSwingTester.java
new file mode 100644
index 00000000000..7d6478c7830
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/ClipboardSwingTester.java
@@ -0,0 +1,10 @@
+package org.eclipse.swt.tests.junit;
+
+public class ClipboardSwingTester {
+
+ public static void main(String[] args) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_dnd_Clipboard.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_dnd_Clipboard.java
index 0cbdcd8a667..afdf6e51258 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_dnd_Clipboard.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_dnd_Clipboard.java
@@ -15,6 +15,7 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import java.io.BufferedReader;
@@ -57,7 +58,7 @@
public class Test_org_eclipse_swt_dnd_Clipboard {
private static final int DEFAULT_TIMEOUT_MS = 10000;
- static int uniqueId = 1;
+ private static int uniqueId = 1;
private Display display;
private Shell shell;
private Clipboard clipboard;
@@ -79,18 +80,6 @@ public void setUp() {
rtfTransfer = RTFTransfer.getInstance();
}
- private void sleep() throws InterruptedException {
- if (SwtTestUtil.isGTK4) {
- /**
- * TODO remove all uses of sleep and change them to processEvents with the
- * suitable conditional, or entirely remove them
- */
- SwtTestUtil.processEvents(100, null);
- } else {
- SwtTestUtil.processEvents();
- }
- }
-
/**
* Note: Wayland backend does not allow access to system clipboard from
* non-focussed windows. So we have to create/open and focus a window here so
@@ -100,7 +89,12 @@ private void openAndFocusShell() throws InterruptedException {
shell = new Shell(display);
shell.open();
shell.setFocus();
- sleep();
+ // A single "processEvents" iteration is insufficient, therefore we run for
+ // 100ms.
+ // As best as I can tell, once window manager gets focus (at least on wayland)
+ // additional events can arrive that need to be processed before the clipboard
+ // contents can be set.
+ SwtTestUtil.processEvents(100, null);
}
/**
@@ -112,12 +106,10 @@ private void openAndFocusRemote() throws Exception {
startRemoteClipboardCommands();
remote.setFocus();
remote.waitUntilReady();
- sleep();
}
@AfterEach
public void tearDown() throws Exception {
- sleep();
try {
stopRemoteClipboardCommands();
} finally {
@@ -337,14 +329,13 @@ public void test_LocalClipboard() throws Exception {
assertEquals(helloWorldRtf, clipboard.getContents(rtfTransfer));
}
- @Test
+ @RepeatedTest(value = 5)
public void test_setContents() throws Exception {
try {
openAndFocusShell();
String helloWorld = getUniqueTestString();
clipboard.setContents(new Object[] { helloWorld }, new Transfer[] { textTransfer });
- sleep();
openAndFocusRemote();
SwtTestUtil.processEvents(1000, () -> helloWorld.equals(runOperationInThread(remote::getStringContents)));
@@ -352,9 +343,12 @@ public void test_setContents() throws Exception {
assertEquals(helloWorld, result);
} catch (Exception | AssertionError e) {
if (SwtTestUtil.isGTK4 && !SwtTestUtil.isX11) {
- // TODO make the code + test stable
- throw new RuntimeException(
- "This test is really unstable on wayland backend, at least with Ubuntu 25.04", e);
+ // If this fails consistently
+ fail("""
+ Wayland + GTK probably didn't know that the the shell had sufficient focus to copy to clipboard.
+ Consider increasing how long processEvents is run for in openAndFocusShell
+ """,
+ e);
}
throw e;
}
diff --git a/tests/org.eclipse.swt.tests/data/clipboard/ClipboardCommandsImpl.java b/tests/org.eclipse.swt.tests/data/clipboard/ClipboardCommandsImpl.java
index 28123f10fa6..d88b436fe25 100644
--- a/tests/org.eclipse.swt.tests/data/clipboard/ClipboardCommandsImpl.java
+++ b/tests/org.eclipse.swt.tests/data/clipboard/ClipboardCommandsImpl.java
@@ -102,4 +102,4 @@ private void invokeAndWait(Runnable run) throws RemoteException {
}
}
-}
\ No newline at end of file
+}