Bug 567257 - [GTK4] Get SWT Text snippets running

- Clean up createHandle spacing
- Use gtk_widget_get_clipboard rather than
GDK.gdk_display_get_clipboard(GDK.gdk_display_get_default())
- Moved GTK.GTK4 guard in Text constructor as in GTK4 there doesn't seem
to be a way to set the icons, therefore the style will always be
ICON_SEARCH | ICON_CANCEL
- Fixed spelling mistake in comment in Text constructor

Change-Id: Ia919c5843b5789b7b01ab89e7060ed59aa6fc909
Signed-off-by: Paul D'Pong <sdamrong@redhat.com>
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/182816
Tested-by: Platform Bot <platform-bot@eclipse.org>
Reviewed-by: Alexander Kurtakov <akurtako@redhat.com>
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 a996dc7..4b6d932 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
@@ -381,6 +381,18 @@
 }
 #endif
 
+#ifndef NO_gtk_1entry_1get_1text_1length
+JNIEXPORT jint JNICALL GTK4_NATIVE(gtk_1entry_1get_1text_1length)
+	(JNIEnv *env, jclass that, jlong arg0)
+{
+	jint rc = 0;
+	GTK4_NATIVE_ENTER(env, that, gtk_1entry_1get_1text_1length_FUNC);
+	rc = (jint)gtk_entry_get_text_length((GtkEntry *)arg0);
+	GTK4_NATIVE_EXIT(env, that, gtk_1entry_1get_1text_1length_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_gtk_1entry_1set_1buffer
 JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1entry_1set_1buffer)
 	(JNIEnv *env, jclass that, jlong arg0, jlong arg1)
@@ -1067,6 +1079,18 @@
 }
 #endif
 
+#ifndef NO_gtk_1widget_1get_1clipboard
+JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1widget_1get_1clipboard)
+	(JNIEnv *env, jclass that, jlong arg0)
+{
+	jlong rc = 0;
+	GTK4_NATIVE_ENTER(env, that, gtk_1widget_1get_1clipboard_FUNC);
+	rc = (jlong)gtk_widget_get_clipboard((GtkWidget *)arg0);
+	GTK4_NATIVE_EXIT(env, that, gtk_1widget_1get_1clipboard_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_gtk_1widget_1get_1first_1child
 JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1widget_1get_1first_1child)
 	(JNIEnv *env, jclass that, jlong arg0)
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 637c3f2..64fcb82 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
@@ -53,6 +53,7 @@
 	"gtk_1editable_1get_1delegate",
 	"gtk_1editable_1get_1text",
 	"gtk_1entry_1get_1buffer",
+	"gtk_1entry_1get_1text_1length",
 	"gtk_1entry_1set_1buffer",
 	"gtk_1event_1controller_1focus_1new",
 	"gtk_1event_1controller_1get_1current_1event",
@@ -110,6 +111,7 @@
 	"gtk_1widget_1activate_1action",
 	"gtk_1widget_1add_1controller",
 	"gtk_1widget_1class_1add_1binding_1signal",
+	"gtk_1widget_1get_1clipboard",
 	"gtk_1widget_1get_1first_1child",
 	"gtk_1widget_1get_1last_1child",
 	"gtk_1widget_1get_1native",
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 9d16286..e557a2a 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
@@ -63,6 +63,7 @@
 	gtk_1editable_1get_1delegate_FUNC,
 	gtk_1editable_1get_1text_FUNC,
 	gtk_1entry_1get_1buffer_FUNC,
+	gtk_1entry_1get_1text_1length_FUNC,
 	gtk_1entry_1set_1buffer_FUNC,
 	gtk_1event_1controller_1focus_1new_FUNC,
 	gtk_1event_1controller_1get_1current_1event_FUNC,
@@ -120,6 +121,7 @@
 	gtk_1widget_1activate_1action_FUNC,
 	gtk_1widget_1add_1controller_FUNC,
 	gtk_1widget_1class_1add_1binding_1signal_FUNC,
+	gtk_1widget_1get_1clipboard_FUNC,
 	gtk_1widget_1get_1first_1child_FUNC,
 	gtk_1widget_1get_1last_1child_FUNC,
 	gtk_1widget_1get_1native_FUNC,
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 6ea1eb7..eceff5c 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
@@ -332,6 +332,8 @@
 	public static final native void gtk_entry_set_buffer(long entry, long buffer);
 	/** @param entry cast=(GtkEntry *) */
 	public static final native long gtk_entry_get_buffer(long entry);
+	/** @param entry cast=(GtkEntry *) */
+	public static final native int gtk_entry_get_text_length(long entry);
 
 	/* GtkExpander */
 	/**
@@ -434,6 +436,8 @@
 	 * @param focusable cast(gboolean)
 	 */
 	public static final native void gtk_widget_set_focusable(long widget, boolean focusable);
+	/** @param widget cast=(GtkWidget *) */
+	public static final native long gtk_widget_get_clipboard(long widget);
 
 	/* GtkComboBox */
 	/** @param combo_box cast=(GtkComboBox *) */
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
index 23ce2b7..732b98b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
@@ -4357,6 +4357,12 @@
  *
  */
 public boolean post (Event event) {
+	/*
+	 * GdkEvents are now strictly read-only
+	 * https://docs.gtk.org/gtk4/migrating-3to4.html#adapt-to-gdkevent-api-changes
+	 */
+	if (GTK.GTK4) return false;
+
 	synchronized (Device.class) {
 		if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
 		if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Text.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Text.java
index c47e512..e135279 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Text.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Text.java
@@ -159,7 +159,7 @@
 		 * Ensure that SWT.ICON_CANCEL and ICON_SEARCH are set.
 		 * NOTE: ICON_CANCEL has the same value as H_SCROLL and CON_SEARCH has the same value as V_SCROLL
 		 * so it is necessary to first clear these bits to avoid a scroll bar and then reset the
-		 * bit using the original style upplied by the programmer.
+		 * bit using the original style supplied by the programmer.
 		 *
 		 * NOTE2: Default GtkSearchEntry shows both "find" icon and "clear" icon.
 		 * "find" icon can be manually removed here while "clear" icon must be removed depending on text.
@@ -167,22 +167,20 @@
 		 */
 		this.style |= SWT.ICON_SEARCH | SWT.ICON_CANCEL;
 
-		if ((style & SWT.ICON_SEARCH) == 0) {
-			this.style &= ~SWT.ICON_SEARCH;
-			if (!GTK.GTK4) {
+		if (!GTK.GTK4) {
+			if ((style & SWT.ICON_SEARCH) == 0) {
+				this.style &= ~SWT.ICON_SEARCH;
 				GTK.gtk_entry_set_icon_from_icon_name(handle, GTK.GTK_ENTRY_ICON_PRIMARY, null);
-			}
-		} else {
-			// Default GtkSearchEntry always shows inactive "find" icon
-			// make it active and sensitive to be consistent with other platforms
-			if (!GTK.GTK4) {
+			} else {
+				// Default GtkSearchEntry always shows inactive "find" icon
+				// make it active and sensitive to be consistent with other platforms
 				GTK.gtk_entry_set_icon_activatable(handle, GTK.GTK_ENTRY_ICON_PRIMARY, true);
 				GTK.gtk_entry_set_icon_sensitive(handle, GTK.GTK_ENTRY_ICON_PRIMARY, true);
 			}
-		}
 
-		if ((style & SWT.ICON_CANCEL) == 0) {
-			this.style &= ~SWT.ICON_CANCEL;
+			if ((style & SWT.ICON_CANCEL) == 0) {
+				this.style &= ~SWT.ICON_CANCEL;
+			}
 		}
 	}
 }
@@ -247,7 +245,7 @@
 		}
 
 		GTK.gtk_editable_set_editable(handle, (style & SWT.READ_ONLY) == 0);
-		if(GTK.GTK4) {
+		if (GTK.GTK4) {
 			GTK4.gtk_text_set_visibility(textHandle, (style & SWT.PASSWORD) == 0);
 		} else {
 			GTK.gtk_entry_set_visibility(handle, (style & SWT.PASSWORD) == 0);
@@ -268,7 +266,7 @@
 		if ((style & SWT.CENTER) != 0) alignment = 0.5f;
 		if ((style & SWT.RIGHT) != 0) alignment = 1.0f;
 		if (alignment > 0.0f) {
-			GTK.gtk_entry_set_alignment (handle, alignment);
+			GTK.gtk_entry_set_alignment(handle, alignment);
 		}
 
 		if (DISABLE_EMOJI && GTK.GTK_VERSION >= OS.VERSION(3, 22, 20)) {
@@ -278,39 +276,44 @@
 		if (GTK.GTK4) {
 			scrolledHandle = GTK4.gtk_scrolled_window_new();
 		} else {
-			scrolledHandle = GTK3.gtk_scrolled_window_new (0, 0);
+			scrolledHandle = GTK3.gtk_scrolled_window_new(0, 0);
 		}
-		if (scrolledHandle == 0) error (SWT.ERROR_NO_HANDLES);
-		handle = GTK.gtk_text_view_new ();
-		if (handle == 0) error (SWT.ERROR_NO_HANDLES);
-		bufferHandle = GTK.gtk_text_view_get_buffer (handle);
-		if (bufferHandle == 0) error (SWT.ERROR_NO_HANDLES);
+		if (scrolledHandle == 0) error(SWT.ERROR_NO_HANDLES);
+
+		handle = GTK.gtk_text_view_new();
+		if (handle == 0) error(SWT.ERROR_NO_HANDLES);
+		bufferHandle = GTK.gtk_text_view_get_buffer(handle);
+		if (bufferHandle == 0) error(SWT.ERROR_NO_HANDLES);
 
 		if (GTK.GTK4) {
 			OS.swt_fixed_add(fixedHandle, scrolledHandle);
 			GTK4.gtk_scrolled_window_set_child(scrolledHandle, handle);
 		} else {
-			GTK3.gtk_container_add (fixedHandle, scrolledHandle);
-			GTK3.gtk_container_add (scrolledHandle, handle);
+			GTK3.gtk_container_add(fixedHandle, scrolledHandle);
+			GTK3.gtk_container_add(scrolledHandle, handle);
 		}
 
-		GTK.gtk_text_view_set_editable (handle, (style & SWT.READ_ONLY) == 0);
-		if ((style & SWT.WRAP) != 0) GTK.gtk_text_view_set_wrap_mode (handle, GTK.GTK_WRAP_WORD_CHAR);
+		GTK.gtk_text_view_set_editable(handle, (style & SWT.READ_ONLY) == 0);
+		if ((style & SWT.WRAP) != 0) GTK.gtk_text_view_set_wrap_mode(handle, GTK.GTK_WRAP_WORD_CHAR);
+
 		int hsp = (style & SWT.H_SCROLL) != 0 ? GTK.GTK_POLICY_ALWAYS : GTK.GTK_POLICY_NEVER;
 		int vsp = (style & SWT.V_SCROLL) != 0 ? GTK.GTK_POLICY_ALWAYS : GTK.GTK_POLICY_NEVER;
-		GTK.gtk_scrolled_window_set_policy (scrolledHandle, hsp, vsp);
+		GTK.gtk_scrolled_window_set_policy(scrolledHandle, hsp, vsp);
+
 		if ((style & SWT.BORDER) != 0) {
 			if (GTK.GTK4) {
 				GTK4.gtk_scrolled_window_set_has_frame(scrolledHandle, true);
 			} else {
-				GTK3.gtk_scrolled_window_set_shadow_type (scrolledHandle, GTK.GTK_SHADOW_ETCHED_IN);
+				GTK3.gtk_scrolled_window_set_shadow_type(scrolledHandle, GTK.GTK_SHADOW_ETCHED_IN);
 			}
 		}
-		int just = GTK.GTK_JUSTIFY_LEFT;
-		if ((style & SWT.CENTER) != 0) just = GTK.GTK_JUSTIFY_CENTER;
-		if ((style & SWT.RIGHT) != 0) just = GTK.GTK_JUSTIFY_RIGHT;
-		GTK.gtk_text_view_set_justification (handle, just);
+
+		int justification = GTK.GTK_JUSTIFY_LEFT;
+		if ((style & SWT.CENTER) != 0) justification = GTK.GTK_JUSTIFY_CENTER;
+		if ((style & SWT.RIGHT) != 0) justification = GTK.GTK_JUSTIFY_RIGHT;
+		GTK.gtk_text_view_set_justification(handle, justification);
 	}
+
 	imContext = OS.imContextLast();
 
 	// In GTK 3 font description is inherited from parent widget which is not how SWT has always worked,
@@ -531,7 +534,12 @@
 				separator [0] = segmentsChars [i];
 			}
 			byte [] buffer = Converter.wcsToMbcs (separator, false);
-			long ptr = GTK3.gtk_entry_get_text (handle);
+			long ptr;
+			if (GTK.GTK4) {
+				ptr = GTK.gtk_entry_buffer_get_text(bufferHandle);
+			} else {
+				ptr = GTK3.gtk_entry_get_text(handle);
+			}
 			pos [0] = (int)OS.g_utf16_offset_to_utf8_offset (ptr, pos [0]);
 			GTK.gtk_editable_insert_text (handle, buffer, buffer.length, pos);
 		}
@@ -568,7 +576,12 @@
 		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
 		if (applyText) {
 			OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
-			long ptr = GTK3.gtk_entry_get_text (handle);
+			long ptr;
+			if (GTK.GTK4) {
+				ptr = GTK.gtk_entry_buffer_get_text(bufferHandle);
+			} else {
+				ptr = GTK3.gtk_entry_get_text(handle);
+			}
 			int start, end;
 			for (int i = 0; i < nSegments; i++) {
 				start = (int)OS.g_utf16_offset_to_utf8_offset (ptr, segments[i]);
@@ -753,7 +766,7 @@
 			GTK3.gtk_editable_copy_clipboard(handle);
 		}
 	} else {
-		long clipboard = GTK.GTK4 ? GDK.gdk_display_get_clipboard(GDK.gdk_display_get_default()) : GTK3.gtk_clipboard_get (GDK.GDK_NONE);
+		long clipboard = GTK.GTK4 ? GTK4.gtk_widget_get_clipboard(handle) : GTK3.gtk_clipboard_get(GDK.GDK_NONE);
 		clearSegments (true);
 		GTK.gtk_text_buffer_copy_clipboard (bufferHandle, clipboard);
 		applySegments ();
@@ -781,7 +794,7 @@
 			GTK3.gtk_editable_cut_clipboard(handle);
 		}
 	} else {
-		long clipboard = GTK.GTK4 ? GDK.gdk_display_get_clipboard(GDK.gdk_display_get_default()) : GTK3.gtk_clipboard_get (GDK.GDK_NONE);
+		long clipboard = GTK.GTK4 ? GTK4.gtk_widget_get_clipboard(handle) : GTK3.gtk_clipboard_get(GDK.GDK_NONE);
 		clearSegments (true);
 		GTK.gtk_text_buffer_cut_clipboard (bufferHandle, clipboard, GTK.gtk_text_view_get_editable (handle));
 		applySegments ();
@@ -1023,13 +1036,12 @@
 	checkWidget ();
 	int result;
 	if ((style & SWT.SINGLE) != 0) {
-		long ptr;
 		if (GTK.GTK4) {
-			ptr = GTK4.gtk_editable_get_text(handle);
+			result = GTK4.gtk_entry_get_text_length(handle);
 		} else {
-			ptr = GTK3.gtk_entry_get_text (handle);
+			long str = GTK3.gtk_entry_get_text(handle);
+			result = (int)OS.g_utf16_strlen(str, -1);
 		}
-		result = (int)OS.g_utf16_strlen (ptr, -1);
 	} else {
 		byte [] startIter =  new byte [ITER_SIZEOF];
 		byte [] endIter =  new byte [ITER_SIZEOF];
@@ -1237,17 +1249,23 @@
  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  * </ul>
  */
-public Point getSelection () {
-	checkWidget ();
+public Point getSelection() {
+	checkWidget();
+
 	Point selection;
 	if ((style & SWT.SINGLE) != 0) {
-		int [] start = new int [1];
-		int [] end = new int [1];
-		GTK.gtk_editable_get_selection_bounds (handle, start, end);
-		long ptr = GTK3.gtk_entry_get_text (handle);
-		start[0] = (int)OS.g_utf8_offset_to_utf16_offset (ptr, start[0]);
-		end[0] = (int)OS.g_utf8_offset_to_utf16_offset (ptr, end[0]);
-		selection = new Point (start [0], end [0]);
+		int[] start = new int[1];
+		int[] end = new int[1];
+		GTK.gtk_editable_get_selection_bounds(handle, start, end);
+		long str;
+		if (GTK.GTK4) {
+			str = GTK.gtk_entry_buffer_get_text(GTK4.gtk_entry_get_buffer(handle));
+		} else {
+			str = GTK3.gtk_entry_get_text(handle);
+		}
+		start[0] = (int)OS.g_utf8_offset_to_utf16_offset(str, start[0]);
+		end[0] = (int)OS.g_utf8_offset_to_utf16_offset(str, end[0]);
+		selection = new Point(start[0], end[0]);
 	} else {
 		byte [] startIter =  new byte [ITER_SIZEOF];
 		byte [] endIter =  new byte [ITER_SIZEOF];
@@ -1260,8 +1278,9 @@
 		OS.g_free (ptr);
 		selection = new Point (start, end);
 	}
-	selection.x = untranslateOffset (selection.x);
-	selection.y = untranslateOffset (selection.y);
+
+	selection.x = untranslateOffset(selection.x);
+	selection.y = untranslateOffset(selection.y);
 	return selection;
 }
 
@@ -1291,10 +1310,11 @@
  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  * </ul>
  */
-public String getSelectionText () {
-	checkWidget ();
-	Point selection = getSelection ();
-	return getText ().substring(selection.x, selection.y);
+public String getSelectionText() {
+	checkWidget();
+
+	Point selection = getSelection();
+	return getText().substring(selection.x, selection.y);
 }
 
 /**
@@ -2123,7 +2143,7 @@
 			GTK3.gtk_editable_paste_clipboard (handle);
 		}
 	} else {
-		long clipboard = GTK.GTK4 ? GDK.gdk_display_get_clipboard(GDK.gdk_display_get_default()) : GTK3.gtk_clipboard_get (GDK.GDK_NONE);
+		long clipboard = GTK.GTK4 ? GTK4.gtk_widget_get_clipboard(handle) : GTK3.gtk_clipboard_get(GDK.GDK_NONE);
 		clearSegments (true);
 		GTK.gtk_text_buffer_paste_clipboard (bufferHandle, clipboard, null, GTK.gtk_text_view_get_editable (handle));
 		applySegments ();
@@ -2255,6 +2275,7 @@
  */
 public void selectAll () {
 	checkWidget ();
+
 	if ((style & SWT.SINGLE) != 0) {
 		GTK.gtk_editable_select_region (handle, 0, -1);
 	} else {
@@ -2383,11 +2404,11 @@
  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  * </ul>
  */
-public void setEchoChar (char echo) {
-	checkWidget ();
+public void setEchoChar(char echo) {
+	checkWidget();
 	if ((style & SWT.SINGLE) != 0) {
-		GTK.gtk_entry_set_visibility (handle, echo == '\0');
-		GTK.gtk_entry_set_invisible_char (handle, echo);
+		GTK.gtk_entry_set_visibility(handle, echo == '\0');
+		GTK.gtk_entry_set_invisible_char(handle, echo);
 	}
 }
 
@@ -2498,13 +2519,19 @@
  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  * </ul>
  */
-public void setSelection (int start) {
-	checkWidget ();
-	start = translateOffset (start);
+public void setSelection(int start) {
+	checkWidget();
+
+	start = translateOffset(start);
 	if ((style & SWT.SINGLE) != 0) {
-		long ptr = GTK3.gtk_entry_get_text (handle);
-		start = (int)OS.g_utf16_offset_to_utf8_offset (ptr, start);
-		GTK.gtk_editable_set_position (handle, start);
+		long str;
+		if (GTK.GTK4) {
+			str = GTK.gtk_entry_buffer_get_text(GTK4.gtk_entry_get_buffer(handle));
+		} else {
+			str = GTK3.gtk_entry_get_text(handle);
+		}
+		start = (int)OS.g_utf16_offset_to_utf8_offset(str, start);
+		GTK.gtk_editable_set_position(handle, start);
 	} else {
 		byte [] startIter =  new byte [ITER_SIZEOF];
 		byte [] endIter =  new byte [ITER_SIZEOF];