From 5884030f32204fbebb6122138ea4b290ad8f0aee Mon Sep 17 00:00:00 2001 From: Joel Majano Date: Fri, 8 Apr 2022 15:04:26 -0400 Subject: [PATCH 1/2] [GTK4] Initial clipboard port fixes + TextTransfer fix --- .../gtk/org/eclipse/swt/dnd/Clipboard.java | 45 +++++++++++++++- .../org/eclipse/swt/dnd/ClipboardProxy.java | 37 ++++++++++++- .../gtk/org/eclipse/swt/dnd/TextTransfer.java | 7 +++ .../Eclipse SWT PI/gtk/library/gtk4.c | 52 +++++++++++++++++++ .../Eclipse SWT PI/gtk/library/gtk4_stats.c | 4 ++ .../Eclipse SWT PI/gtk/library/gtk4_stats.h | 4 ++ .../Eclipse SWT PI/gtk/library/os.c | 22 ++++++++ .../Eclipse SWT PI/gtk/library/os_stats.c | 2 + .../Eclipse SWT PI/gtk/library/os_stats.h | 2 + .../gtk/org/eclipse/swt/internal/gtk/OS.java | 6 +++ .../org/eclipse/swt/internal/gtk4/GTK4.java | 21 ++++++++ 11 files changed, 198 insertions(+), 4 deletions(-) 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 b5e9e18194c..c0765bec0d7 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 @@ -18,6 +18,7 @@ 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.*; /** @@ -42,10 +43,10 @@ public class Clipboard { 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 = GDK.gdk_atom_intern(buffer, false); + 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 = GDK.gdk_atom_intern(buffer, false); + TARGET = GTK.GTK4 ? 0 : GDK.gdk_atom_intern(buffer, false); } /** @@ -290,6 +291,12 @@ public Object getContents(Transfer transfer) { 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; + } + long selection_data = 0; int[] typeIds = transfer.getTypeIds(); for (int i = 0; i < typeIds.length; i++) { @@ -312,6 +319,33 @@ public Object getContents(Transfer transfer, int clipboards) { return result; } +private Object getContents_gtk4(Transfer transfer, int clipboards) { + + long contents = GTK4.gdk_clipboard_get_content(Clipboard.GTKCLIPBOARD); + long value = OS.g_malloc (OS.GValue_sizeof ()); + C.memset (value, 0, OS.GValue_sizeof ()); + + //Pasting of text (TextTransfer) + if(transfer.getTypeNames()[0] == "STRING") { + 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; +} + /** * Returns true if the clipboard has been disposed, * and false otherwise. @@ -596,6 +630,13 @@ private int[] getAvailablePrimaryTypes() { return types; } private int[] getAvailableClipboardTypes () { + + if(GTK.GTK4) { + /*TODO: can use gdk_clipboard_get_formats and gdk_content_formats_to_string + *Then from the comma separated list of formats find their respective IDs + */ + } + int[] types = new int[0]; long selection_data = gtk_clipboard_wait_for_contents(GTKCLIPBOARD, TARGET); if (selection_data != 0) { 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 75de07e91a7..ced2d57bdf9 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 @@ -93,10 +93,10 @@ long clearFunc(long clipboard,long user_data_or_owner){ void dispose () { if (display == null) return; if (activeClipboard != null) { - GTK3.gtk_clipboard_store(Clipboard.GTKCLIPBOARD); + if(!GTK.GTK4) GTK3.gtk_clipboard_store(Clipboard.GTKCLIPBOARD); } if (activePrimaryClipboard != null) { - GTK3.gtk_clipboard_store(Clipboard.GTKPRIMARYCLIPBOARD); + if(!GTK.GTK4) GTK3.gtk_clipboard_store(Clipboard.GTKPRIMARYCLIPBOARD); } display = null; if (getFunc != null ) getFunc.dispose(); @@ -146,6 +146,9 @@ 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 { @@ -214,4 +217,34 @@ 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; + + //Handle the text transfer case first + for (int i = 0; i < dataTypes.length; i++) { + Transfer transfer = dataTypes[i]; + String[] typeNames = transfer.getTypeNames(); + if ((clipboards & DND.CLIPBOARD) != 0){ + clipboardData = data; + clipboardDataTypes = dataTypes; + result = setContentFromType(Clipboard.GTKCLIPBOARD, typeNames[0], data[i]); + activeClipboard = owner; + } + } + //TODO: [GTK4] Other cases for setting data + return result; +} + +private boolean setContentFromType(long clipboard, String string, Object data) { + + //TextTransfer + if(data.getClass() == String.class) { + GTK4.gdk_clipboard_set_text(clipboard, Converter.javaStringToCString((String)data)); + return true; + } + + + return false; +} } 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 1b152d4960b..4ece87edf35 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 @@ -142,6 +142,9 @@ protected int[] getTypeIds() { if (OS.isX11()) { return new int[] {UTF8_STRING_ID, COMPOUND_TEXT_ID, STRING_ID}; } + if(GTK.GTK4) { + return new int[] {(int) OS.G_TYPE_STRING()}; + } return new int[] {UTF8_STRING_ID, STRING_ID}; } @@ -150,6 +153,10 @@ protected String[] getTypeNames() { if (OS.isX11()) { return new String[] {UTF8_STRING, COMPOUND_TEXT, STRING}; } + if(GTK.GTK4) { + return new String[] {STRING}; + } + return new String[] {UTF8_STRING, STRING}; } 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 2e23672cf5c..9b9bcc3a097 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 @@ -24,6 +24,42 @@ #define GTK4_NATIVE(func) Java_org_eclipse_swt_internal_gtk4_GTK4_##func #endif +#ifndef NO_gdk_1clipboard_1get_1content +JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1clipboard_1get_1content) + (JNIEnv *env, jclass that, jlong arg0) +{ + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gdk_1clipboard_1get_1content_FUNC); + rc = (jlong)gdk_clipboard_get_content((GdkClipboard*)arg0); + GTK4_NATIVE_EXIT(env, that, gdk_1clipboard_1get_1content_FUNC); + return rc; +} +#endif + +#ifndef NO_gdk_1clipboard_1get_1formats +JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1clipboard_1get_1formats) + (JNIEnv *env, jclass that, jlong arg0) +{ + GTK4_NATIVE_ENTER(env, that, gdk_1clipboard_1get_1formats_FUNC); + gdk_clipboard_get_formats((GdkClipboard*)arg0); + GTK4_NATIVE_EXIT(env, that, gdk_1clipboard_1get_1formats_FUNC); +} +#endif + +#ifndef NO_gdk_1clipboard_1set_1text +JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1clipboard_1set_1text) + (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1) +{ + jbyte *lparg1=NULL; + GTK4_NATIVE_ENTER(env, that, gdk_1clipboard_1set_1text_FUNC); + if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail; + gdk_clipboard_set_text((GdkClipboard*)arg0, (const char *)lparg1); +fail: + if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0); + GTK4_NATIVE_EXIT(env, that, gdk_1clipboard_1set_1text_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) @@ -62,6 +98,22 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1formats_1builder_1new) } #endif +#ifndef NO_gdk_1content_1provider_1get_1value +JNIEXPORT jboolean JNICALL GTK4_NATIVE(gdk_1content_1provider_1get_1value) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2) +{ + jlong *lparg2=NULL; + jboolean rc = 0; + GTK4_NATIVE_ENTER(env, that, gdk_1content_1provider_1get_1value_FUNC); + if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail; + rc = (jboolean)gdk_content_provider_get_value((GdkContentProvider *)arg0, (GValue *)arg1, (GError **)lparg2); +fail: + if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0); + GTK4_NATIVE_EXIT(env, that, gdk_1content_1provider_1get_1value_FUNC); + return rc; +} +#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.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c index 7047c84989b..3075de06b5e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c @@ -21,9 +21,13 @@ #ifdef NATIVE_STATS char * GTK4_nativeFunctionNames[] = { + "gdk_1clipboard_1get_1content", + "gdk_1clipboard_1get_1formats", + "gdk_1clipboard_1set_1text", "gdk_1content_1formats_1builder_1add_1mime_1type", "gdk_1content_1formats_1builder_1free_1to_1formats", "gdk_1content_1formats_1builder_1new", + "gdk_1content_1provider_1get_1value", "gdk_1toplevel_1focus", "gdk_1toplevel_1get_1state", "gdk_1toplevel_1lower", 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 23bc1ce531a..eef4b6bc4de 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 @@ -31,9 +31,13 @@ extern char* GTK4_nativeFunctionNames[]; #endif typedef enum { + gdk_1clipboard_1get_1content_FUNC, + gdk_1clipboard_1get_1formats_FUNC, + gdk_1clipboard_1set_1text_FUNC, gdk_1content_1formats_1builder_1add_1mime_1type_FUNC, gdk_1content_1formats_1builder_1free_1to_1formats_FUNC, gdk_1content_1formats_1builder_1new_FUNC, + gdk_1content_1provider_1get_1value_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 cea7169846e..ef2e30e6f1c 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 @@ -13088,6 +13088,18 @@ JNIEXPORT jlong JNICALL OS_NATIVE(g_1value_1get_1int64) } #endif +#ifndef NO_g_1value_1get_1string +JNIEXPORT jlong JNICALL OS_NATIVE(g_1value_1get_1string) + (JNIEnv *env, jclass that, jlong arg0) +{ + jlong rc = 0; + OS_NATIVE_ENTER(env, that, g_1value_1get_1string_FUNC); + rc = (jlong)g_value_get_string((GValue *)arg0); + OS_NATIVE_EXIT(env, that, g_1value_1get_1string_FUNC); + return rc; +} +#endif + #ifndef NO_g_1value_1init JNIEXPORT jlong JNICALL OS_NATIVE(g_1value_1init) (JNIEnv *env, jclass that, jlong arg0, jlong arg1) @@ -13152,6 +13164,16 @@ JNIEXPORT void JNICALL OS_NATIVE(g_1value_1set_1int64) } #endif +#ifndef NO_g_1value_1set_1string +JNIEXPORT void JNICALL OS_NATIVE(g_1value_1set_1string) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1) +{ + OS_NATIVE_ENTER(env, that, g_1value_1set_1string_FUNC); + g_value_set_string((GValue *)arg0, (const gchar *)arg1); + OS_NATIVE_EXIT(env, that, g_1value_1set_1string_FUNC); +} +#endif + #ifndef NO_g_1value_1unset JNIEXPORT void JNICALL OS_NATIVE(g_1value_1unset) (JNIEnv *env, jclass that, jlong arg0) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c index 0ab5dc85d2e..e671e536ed8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c @@ -1101,12 +1101,14 @@ char * OS_nativeFunctionNames[] = { "g_1value_1get_1float", "g_1value_1get_1int", "g_1value_1get_1int64", + "g_1value_1get_1string", "g_1value_1init", "g_1value_1peek_1pointer", "g_1value_1set_1double", "g_1value_1set_1float", "g_1value_1set_1int", "g_1value_1set_1int64", + "g_1value_1set_1string", "g_1value_1unset", "g_1variant_1builder_1add_1value", "g_1variant_1builder_1end", 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 057048bff8c..f64560bd948 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 @@ -1075,12 +1075,14 @@ typedef enum { g_1value_1get_1float_FUNC, g_1value_1get_1int_FUNC, g_1value_1get_1int64_FUNC, + g_1value_1get_1string_FUNC, g_1value_1init_FUNC, g_1value_1peek_1pointer_FUNC, g_1value_1set_1double_FUNC, g_1value_1set_1float_FUNC, g_1value_1set_1int_FUNC, g_1value_1set_1int64_FUNC, + g_1value_1set_1string_FUNC, g_1value_1unset_FUNC, g_1variant_1builder_1add_1value_FUNC, g_1variant_1builder_1end_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 64d9ac9fba1..2af32a7ba49 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 @@ -1374,6 +1374,12 @@ public static boolean isX11 () { public static final native long g_value_get_int64 (long value); /** @param value cast=(GValue *) */ public static final native void g_value_set_int64 (long value, long v); +/** @param value cast=(GValue *) + * @param v_string cast =(const gchar *) + * */ +public static final native void g_value_set_string (long value, long v_string); +/** @param value cast=(GValue *) */ +public static final native long g_value_get_string (long value); /** @param value cast=(GValue *) */ public static final native void g_value_unset (long value); /** @param value cast=(const GValue *) */ 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 ecff340801b..d24843f97ab 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 @@ -559,5 +559,26 @@ public class GTK4 { */ public static final native void gdk_toplevel_size_set_size(long size, int width, int height); + /* GdkClipboard */ + /** + * @param clipboard cast=(GdkClipboard*) + * @param text cast=(const char *) + */ + public static final native void gdk_clipboard_set_text(long clipboard, byte[] text); + /** + * @param clipboard cast=(GdkClipboard*) + */ + public static final native void gdk_clipboard_get_formats(long clipboard); + /** + * @param clipboard cast=(GdkClipboard*) + */ + public static final native long gdk_clipboard_get_content(long clipboard); + /** + * @param provider cast=(GdkContentProvider *) + * @param value cast=(GValue *) + * @param error cast=(GError **) + */ + public static final native boolean gdk_content_provider_get_value(long provider, long value, long[] error); + } From 8b75cfedc63feb103588cee9b712810012a48aa1 Mon Sep 17 00:00:00 2001 From: Joel Majano Date: Wed, 20 Apr 2022 11:14:24 -0400 Subject: [PATCH 2/2] Use equals() instead of == for string comparison --- .../gtk/org/eclipse/swt/dnd/Clipboard.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c0765bec0d7..531f27f3799 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 @@ -326,7 +326,7 @@ private Object getContents_gtk4(Transfer transfer, int clipboards) { C.memset (value, 0, OS.GValue_sizeof ()); //Pasting of text (TextTransfer) - if(transfer.getTypeNames()[0] == "STRING") { + if(transfer.getTypeNames()[0].equals("STRING")) { OS.g_value_init(value, OS.G_TYPE_STRING()); if (!GTK4.gdk_content_provider_get_value (contents, value, null)) return null;