Bug 564809 - [GTK4] Adapt to GdkEvent API changes

Multiple functions have been renamed and their signatures changed.
Converted them accordingly and placed platform filter checks. Grouped
the gdk event functions together in GDK.java for readability and so it
will be easier to remove GTK3 function in the future.

Functions changed:
gdk_event_get_button -> gdk_button_event_get_button
gdk_event_get_crossing_mode -> gdk_crossing_event_get_mode
gdk_event_get_focus_in -> gdk_focus_event_get_in
gdk_event_get_keycode -> gdk_key_event_get_keycode
gdk_event_get_keyval -> gdk_key_event_get_keyval
gdk_event_get_scroll_deltas -> gdk_scroll_event_get_deltas
gdk_event_get_scroll_direction -> gdk_scroll_event_get_direction
gdk_event_get_state -> gdk_event_get_modifier_state

Added:
gdk_event_ref
gdk_event_unref
gdk_key_event_get_layout to replace gdk_event_get_key_group
gdk_keyval_name to replace getting the string directly from GtkKeyEvent

Change-Id: If461539f1301d5008be3c8f843b9326c3c8b0800
Signed-off-by: Paul D'Pong <sdamrong@redhat.com>
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 420e93c..bed8d4a 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
@@ -264,6 +264,18 @@
 }
 #endif
 
+#ifndef NO_gdk_1button_1event_1get_1button
+JNIEXPORT jint JNICALL GDK_NATIVE(gdk_1button_1event_1get_1button)
+	(JNIEnv *env, jclass that, jlong arg0)
+{
+	jint rc = 0;
+	GDK_NATIVE_ENTER(env, that, gdk_1button_1event_1get_1button_FUNC);
+	rc = (jint)gdk_button_event_get_button((GdkEvent *)arg0);
+	GDK_NATIVE_EXIT(env, that, gdk_1button_1event_1get_1button_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_gdk_1cairo_1create
 JNIEXPORT jlong JNICALL GDK_NATIVE(gdk_1cairo_1create)
 	(JNIEnv *env, jclass that, jlong arg0)
@@ -368,6 +380,18 @@
 }
 #endif
 
+#ifndef NO_gdk_1crossing_1event_1get_1mode
+JNIEXPORT jint JNICALL GDK_NATIVE(gdk_1crossing_1event_1get_1mode)
+	(JNIEnv *env, jclass that, jlong arg0)
+{
+	jint rc = 0;
+	GDK_NATIVE_ENTER(env, that, gdk_1crossing_1event_1get_1mode_FUNC);
+	rc = (jint)gdk_crossing_event_get_mode((GdkEvent *)arg0);
+	GDK_NATIVE_EXIT(env, that, gdk_1crossing_1event_1get_1mode_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_gdk_1cursor_1new_1from_1name__JLjava_lang_String_2
 JNIEXPORT jlong JNICALL GDK_NATIVE(gdk_1cursor_1new_1from_1name__JLjava_lang_String_2)
 	(JNIEnv *env, jclass that, jlong arg0, jstring arg1)
@@ -760,7 +784,7 @@
 	(JNIEnv *env, jclass that, jlong arg0, jlong arg1)
 {
 	GDK_NATIVE_ENTER(env, that, gdk_1display_1put_1event_FUNC);
-	gdk_display_put_event((GdkDisplay *)arg0, (const GdkEvent *)arg1);
+	gdk_display_put_event((GdkDisplay *)arg0, (GdkEvent *)arg1);
 	GDK_NATIVE_EXIT(env, that, gdk_1display_1put_1event_FUNC);
 }
 #endif
@@ -920,22 +944,6 @@
 }
 #endif
 
-#ifndef NO_gdk_1event_1get_1crossing_1mode
-JNIEXPORT jboolean JNICALL GDK_NATIVE(gdk_1event_1get_1crossing_1mode)
-	(JNIEnv *env, jclass that, jlong arg0, jintArray arg1)
-{
-	jint *lparg1=NULL;
-	jboolean rc = 0;
-	GDK_NATIVE_ENTER(env, that, gdk_1event_1get_1crossing_1mode_FUNC);
-	if (arg1) if ((lparg1 = (*env)->GetIntArrayElements(env, arg1, NULL)) == NULL) goto fail;
-	rc = (jboolean)gdk_event_get_crossing_mode((GdkEvent *)arg0, (GdkCrossingMode *)lparg1);
-fail:
-	if (arg1 && lparg1) (*env)->ReleaseIntArrayElements(env, arg1, lparg1, 0);
-	GDK_NATIVE_EXIT(env, that, gdk_1event_1get_1crossing_1mode_FUNC);
-	return rc;
-}
-#endif
-
 #ifndef NO_gdk_1event_1get_1event_1type
 JNIEXPORT jint JNICALL GDK_NATIVE(gdk_1event_1get_1event_1type)
 	(JNIEnv *env, jclass that, jlong arg0)
@@ -956,54 +964,6 @@
 }
 #endif
 
-#ifndef NO_gdk_1event_1get_1focus_1in
-JNIEXPORT jboolean JNICALL GDK_NATIVE(gdk_1event_1get_1focus_1in)
-	(JNIEnv *env, jclass that, jlong arg0, jbooleanArray arg1)
-{
-	jboolean *lparg1=NULL;
-	jboolean rc = 0;
-	GDK_NATIVE_ENTER(env, that, gdk_1event_1get_1focus_1in_FUNC);
-	if (arg1) if ((lparg1 = (*env)->GetBooleanArrayElements(env, arg1, NULL)) == NULL) goto fail;
-	rc = (jboolean)gdk_event_get_focus_in((GdkEvent *)arg0, (gboolean *)lparg1);
-fail:
-	if (arg1 && lparg1) (*env)->ReleaseBooleanArrayElements(env, arg1, lparg1, 0);
-	GDK_NATIVE_EXIT(env, that, gdk_1event_1get_1focus_1in_FUNC);
-	return rc;
-}
-#endif
-
-#ifndef NO_gdk_1event_1get_1key_1group
-JNIEXPORT jboolean JNICALL GDK_NATIVE(gdk_1event_1get_1key_1group)
-	(JNIEnv *env, jclass that, jlong arg0, jintArray arg1)
-{
-	jint *lparg1=NULL;
-	jboolean rc = 0;
-	GDK_NATIVE_ENTER(env, that, gdk_1event_1get_1key_1group_FUNC);
-	if (arg1) if ((lparg1 = (*env)->GetIntArrayElements(env, arg1, NULL)) == NULL) goto fail;
-	rc = (jboolean)gdk_event_get_key_group((GdkEvent *)arg0, (guint *)lparg1);
-fail:
-	if (arg1 && lparg1) (*env)->ReleaseIntArrayElements(env, arg1, lparg1, 0);
-	GDK_NATIVE_EXIT(env, that, gdk_1event_1get_1key_1group_FUNC);
-	return rc;
-}
-#endif
-
-#ifndef NO_gdk_1event_1get_1keycode
-JNIEXPORT jboolean JNICALL GDK_NATIVE(gdk_1event_1get_1keycode)
-	(JNIEnv *env, jclass that, jlong arg0, jshortArray arg1)
-{
-	jshort *lparg1=NULL;
-	jboolean rc = 0;
-	GDK_NATIVE_ENTER(env, that, gdk_1event_1get_1keycode_FUNC);
-	if (arg1) if ((lparg1 = (*env)->GetShortArrayElements(env, arg1, NULL)) == NULL) goto fail;
-	rc = (jboolean)gdk_event_get_keycode((GdkEvent *)arg0, (guint16 *)lparg1);
-fail:
-	if (arg1 && lparg1) (*env)->ReleaseShortArrayElements(env, arg1, lparg1, 0);
-	GDK_NATIVE_EXIT(env, that, gdk_1event_1get_1keycode_FUNC);
-	return rc;
-}
-#endif
-
 #ifndef NO_gdk_1event_1get_1keyval
 JNIEXPORT jboolean JNICALL GDK_NATIVE(gdk_1event_1get_1keyval)
 	(JNIEnv *env, jclass that, jlong arg0, jintArray arg1)
@@ -1020,6 +980,37 @@
 }
 #endif
 
+#ifndef NO_gdk_1event_1get_1modifier_1state
+JNIEXPORT jint JNICALL GDK_NATIVE(gdk_1event_1get_1modifier_1state)
+	(JNIEnv *env, jclass that, jlong arg0)
+{
+	jint rc = 0;
+	GDK_NATIVE_ENTER(env, that, gdk_1event_1get_1modifier_1state_FUNC);
+	rc = (jint)gdk_event_get_modifier_state((GdkEvent *)arg0);
+	GDK_NATIVE_EXIT(env, that, gdk_1event_1get_1modifier_1state_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_gdk_1event_1get_1position
+JNIEXPORT jboolean JNICALL GDK_NATIVE(gdk_1event_1get_1position)
+	(JNIEnv *env, jclass that, jlong arg0, jdoubleArray arg1, jdoubleArray arg2)
+{
+	jdouble *lparg1=NULL;
+	jdouble *lparg2=NULL;
+	jboolean rc = 0;
+	GDK_NATIVE_ENTER(env, that, gdk_1event_1get_1position_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetDoubleArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	if (arg2) if ((lparg2 = (*env)->GetDoubleArrayElements(env, arg2, NULL)) == NULL) goto fail;
+	rc = (jboolean)gdk_event_get_position((GdkEvent *)arg0, (gdouble *)lparg1, (gdouble *)lparg2);
+fail:
+	if (arg2 && lparg2) (*env)->ReleaseDoubleArrayElements(env, arg2, lparg2, 0);
+	if (arg1 && lparg1) (*env)->ReleaseDoubleArrayElements(env, arg1, lparg1, 0);
+	GDK_NATIVE_EXIT(env, that, gdk_1event_1get_1position_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_gdk_1event_1get_1root_1coords
 JNIEXPORT jboolean JNICALL GDK_NATIVE(gdk_1event_1get_1root_1coords)
 	(JNIEnv *env, jclass that, jlong arg0, jdoubleArray arg1, jdoubleArray arg2)
@@ -1110,22 +1101,6 @@
 }
 #endif
 
-#ifndef NO_gdk_1event_1get_1string
-JNIEXPORT jboolean JNICALL GDK_NATIVE(gdk_1event_1get_1string)
-	(JNIEnv *env, jclass that, jlong arg0, jlongArray arg1)
-{
-	jlong *lparg1=NULL;
-	jboolean rc = 0;
-	GDK_NATIVE_ENTER(env, that, gdk_1event_1get_1string_FUNC);
-	if (arg1) if ((lparg1 = (*env)->GetLongArrayElements(env, arg1, NULL)) == NULL) goto fail;
-	rc = (jboolean)gdk_event_get_string((GdkEvent *)arg0, (const char **)lparg1);
-fail:
-	if (arg1 && lparg1) (*env)->ReleaseLongArrayElements(env, arg1, lparg1, 0);
-	GDK_NATIVE_EXIT(env, that, gdk_1event_1get_1string_FUNC);
-	return rc;
-}
-#endif
-
 #ifndef NO_gdk_1event_1get_1surface
 JNIEXPORT jlong JNICALL GDK_NATIVE(gdk_1event_1get_1surface)
 	(JNIEnv *env, jclass that, jlong arg0)
@@ -1214,6 +1189,18 @@
 }
 #endif
 
+#ifndef NO_gdk_1event_1ref
+JNIEXPORT jlong JNICALL GDK_NATIVE(gdk_1event_1ref)
+	(JNIEnv *env, jclass that, jlong arg0)
+{
+	jlong rc = 0;
+	GDK_NATIVE_ENTER(env, that, gdk_1event_1ref_FUNC);
+	rc = (jlong)gdk_event_ref((GdkEvent *)arg0);
+	GDK_NATIVE_EXIT(env, that, gdk_1event_1ref_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_gdk_1event_1set_1device
 JNIEXPORT void JNICALL GDK_NATIVE(gdk_1event_1set_1device)
 	(JNIEnv *env, jclass that, jlong arg0, jlong arg1)
@@ -1224,6 +1211,28 @@
 }
 #endif
 
+#ifndef NO_gdk_1event_1unref
+JNIEXPORT void JNICALL GDK_NATIVE(gdk_1event_1unref)
+	(JNIEnv *env, jclass that, jlong arg0)
+{
+	GDK_NATIVE_ENTER(env, that, gdk_1event_1unref_FUNC);
+	gdk_event_unref((GdkEvent *)arg0);
+	GDK_NATIVE_EXIT(env, that, gdk_1event_1unref_FUNC);
+}
+#endif
+
+#ifndef NO_gdk_1focus_1event_1get_1in
+JNIEXPORT jboolean JNICALL GDK_NATIVE(gdk_1focus_1event_1get_1in)
+	(JNIEnv *env, jclass that, jlong arg0)
+{
+	jboolean rc = 0;
+	GDK_NATIVE_ENTER(env, that, gdk_1focus_1event_1get_1in_FUNC);
+	rc = (jboolean)gdk_focus_event_get_in((GdkEvent *)arg0);
+	GDK_NATIVE_EXIT(env, that, gdk_1focus_1event_1get_1in_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_gdk_1get_1default_1root_1window
 JNIEXPORT jlong JNICALL GDK_NATIVE(gdk_1get_1default_1root_1window)
 	(JNIEnv *env, jclass that)
@@ -1236,6 +1245,30 @@
 }
 #endif
 
+#ifndef NO_gdk_1key_1event_1get_1keyval
+JNIEXPORT jint JNICALL GDK_NATIVE(gdk_1key_1event_1get_1keyval)
+	(JNIEnv *env, jclass that, jlong arg0)
+{
+	jint rc = 0;
+	GDK_NATIVE_ENTER(env, that, gdk_1key_1event_1get_1keyval_FUNC);
+	rc = (jint)gdk_key_event_get_keyval((GdkEvent *)arg0);
+	GDK_NATIVE_EXIT(env, that, gdk_1key_1event_1get_1keyval_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_gdk_1key_1event_1get_1layout
+JNIEXPORT jint JNICALL GDK_NATIVE(gdk_1key_1event_1get_1layout)
+	(JNIEnv *env, jclass that, jlong arg0)
+{
+	jint rc = 0;
+	GDK_NATIVE_ENTER(env, that, gdk_1key_1event_1get_1layout_FUNC);
+	rc = (jint)gdk_key_event_get_layout((GdkEvent *)arg0);
+	GDK_NATIVE_EXIT(env, that, gdk_1key_1event_1get_1layout_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_gdk_1keymap_1get_1entries_1for_1keyval
 JNIEXPORT jboolean JNICALL GDK_NATIVE(gdk_1keymap_1get_1entries_1for_1keyval)
 	(JNIEnv *env, jclass that, jlong arg0, jint arg1, jlongArray arg2, jintArray arg3)
@@ -1316,6 +1349,18 @@
 }
 #endif
 
+#ifndef NO_gdk_1keyval_1name
+JNIEXPORT jlong JNICALL GDK_NATIVE(gdk_1keyval_1name)
+	(JNIEnv *env, jclass that, jint arg0)
+{
+	jlong rc = 0;
+	GDK_NATIVE_ENTER(env, that, gdk_1keyval_1name_FUNC);
+	rc = (jlong)gdk_keyval_name((guint)arg0);
+	GDK_NATIVE_EXIT(env, that, gdk_1keyval_1name_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_gdk_1keyval_1to_1lower
 JNIEXPORT jlong JNICALL GDK_NATIVE(gdk_1keyval_1to_1lower)
 	(JNIEnv *env, jclass that, jlong arg0)
@@ -2110,6 +2155,35 @@
 }
 #endif
 
+#ifndef NO_gdk_1scroll_1event_1get_1deltas
+JNIEXPORT void JNICALL GDK_NATIVE(gdk_1scroll_1event_1get_1deltas)
+	(JNIEnv *env, jclass that, jlong arg0, jdoubleArray arg1, jdoubleArray arg2)
+{
+	jdouble *lparg1=NULL;
+	jdouble *lparg2=NULL;
+	GDK_NATIVE_ENTER(env, that, gdk_1scroll_1event_1get_1deltas_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetDoubleArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	if (arg2) if ((lparg2 = (*env)->GetDoubleArrayElements(env, arg2, NULL)) == NULL) goto fail;
+	gdk_scroll_event_get_deltas((GdkEvent *)arg0, lparg1, lparg2);
+fail:
+	if (arg2 && lparg2) (*env)->ReleaseDoubleArrayElements(env, arg2, lparg2, 0);
+	if (arg1 && lparg1) (*env)->ReleaseDoubleArrayElements(env, arg1, lparg1, 0);
+	GDK_NATIVE_EXIT(env, that, gdk_1scroll_1event_1get_1deltas_FUNC);
+}
+#endif
+
+#ifndef NO_gdk_1scroll_1event_1get_1direction
+JNIEXPORT jint JNICALL GDK_NATIVE(gdk_1scroll_1event_1get_1direction)
+	(JNIEnv *env, jclass that, jlong arg0)
+{
+	jint rc = 0;
+	GDK_NATIVE_ENTER(env, that, gdk_1scroll_1event_1get_1direction_FUNC);
+	rc = (jint)gdk_scroll_event_get_direction((GdkEvent *)arg0);
+	GDK_NATIVE_EXIT(env, that, gdk_1scroll_1event_1get_1direction_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_gdk_1seat_1get_1keyboard
 JNIEXPORT jlong JNICALL GDK_NATIVE(gdk_1seat_1get_1keyboard)
 	(JNIEnv *env, jclass that, jlong arg0)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h
index 0026439..b8e3387 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h
@@ -356,10 +356,18 @@
 #define NO_gtk_1tree_1view_1get_1bin_1window
 
 // Event related functions removed in GTK4
+#define NO_gdk_1event_1copy
 #define NO_gdk_1event_1free
 #define NO_gdk_1event_1get
 #define NO_gdk_1event_1peek
 #define NO_gdk_1event_1put
+#define NO_gdk_1event_1get_1button
+#define NO_gdk_1event_1get_1coords
+#define NO_gdk_1event_1get_1root_1coords
+#define NO_gdk_1event_1get_1keyval
+#define NO_gdk_1event_1get_1scroll_1deltas
+#define NO_gdk_1event_1get_1scroll_1direction
+#define NO_gdk_1event_1get_1state
 #define NO_GDK_1EVENT_1TYPE
 #define NO_GDK_1EVENT_1WINDOW
 
@@ -465,10 +473,17 @@
 #define NO_gtk_1widget_1add_1controller
 
 // GdkEvent functions which do not exist on GTK3
-#define NO_gdk_1event_1get_1focus_1in
-#define NO_gdk_1event_1get_1string
-#define NO_gdk_1event_1get_1key_1group
-#define NO_gdk_1event_1get_1crossing_1mode
+#define NO_gdk_1focus_1event_1get_1in
+#define NO_gdk_1crossing_1event_1get_1mode
+#define NO_gdk_1button_1event_1get_1button
+#define NO_gdk_1event_1get_1position
+#define NO_gdk_1key_1event_1get_1keyval
+#define NO_gdk_1scroll_1event_1get_1deltas
+#define NO_gdk_1scroll_1event_1get_1direction
+#define NO_gdk_1event_1get_1modifier_1state
+#define NO_gdk_1key_1event_1get_1layout
+#define NO_gdk_1event_1ref
+#define NO_gdk_1event_1unref
 
 // GdkCursor API changes
 #define NO_gdk_1cursor_1new_1from_1name__Ljava_lang_String_2J
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 ca23100..cdfd403 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
@@ -41,6 +41,7 @@
 	"GdkWindowAttr_1sizeof",
 	"gdk_1atom_1intern",
 	"gdk_1atom_1name",
+	"gdk_1button_1event_1get_1button",
 	"gdk_1cairo_1create",
 	"gdk_1cairo_1get_1clip_1rectangle",
 	"gdk_1cairo_1region",
@@ -49,6 +50,7 @@
 	"gdk_1cairo_1set_1source_1rgba",
 	"gdk_1cairo_1set_1source_1window",
 	"gdk_1clipboard_1set_1content",
+	"gdk_1crossing_1event_1get_1mode",
 	"gdk_1cursor_1new_1from_1name__JLjava_lang_String_2",
 	"gdk_1cursor_1new_1from_1name__Ljava_lang_String_2J",
 	"gdk_1cursor_1new_1from_1pixbuf",
@@ -86,18 +88,15 @@
 	"gdk_1event_1get",
 	"gdk_1event_1get_1button",
 	"gdk_1event_1get_1coords",
-	"gdk_1event_1get_1crossing_1mode",
 	"gdk_1event_1get_1event_1type",
-	"gdk_1event_1get_1focus_1in",
-	"gdk_1event_1get_1key_1group",
-	"gdk_1event_1get_1keycode",
 	"gdk_1event_1get_1keyval",
+	"gdk_1event_1get_1modifier_1state",
+	"gdk_1event_1get_1position",
 	"gdk_1event_1get_1root_1coords",
 	"gdk_1event_1get_1scroll_1deltas",
 	"gdk_1event_1get_1scroll_1direction",
 	"gdk_1event_1get_1seat",
 	"gdk_1event_1get_1state",
-	"gdk_1event_1get_1string",
 	"gdk_1event_1get_1surface",
 	"gdk_1event_1get_1time",
 	"gdk_1event_1get_1window",
@@ -105,11 +104,17 @@
 	"gdk_1event_1new",
 	"gdk_1event_1peek",
 	"gdk_1event_1put",
+	"gdk_1event_1ref",
 	"gdk_1event_1set_1device",
+	"gdk_1event_1unref",
+	"gdk_1focus_1event_1get_1in",
 	"gdk_1get_1default_1root_1window",
+	"gdk_1key_1event_1get_1keyval",
+	"gdk_1key_1event_1get_1layout",
 	"gdk_1keymap_1get_1entries_1for_1keyval",
 	"gdk_1keymap_1get_1for_1display",
 	"gdk_1keymap_1translate_1keyboard_1state",
+	"gdk_1keyval_1name",
 	"gdk_1keyval_1to_1lower",
 	"gdk_1keyval_1to_1unicode",
 	"gdk_1monitor_1get_1geometry",
@@ -162,6 +167,8 @@
 	"gdk_1screen_1height",
 	"gdk_1screen_1is_1composited",
 	"gdk_1screen_1width",
+	"gdk_1scroll_1event_1get_1deltas",
+	"gdk_1scroll_1event_1get_1direction",
 	"gdk_1seat_1get_1keyboard",
 	"gdk_1seat_1get_1pointer",
 	"gdk_1seat_1grab",
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 33306da..c96cccc 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
@@ -51,6 +51,7 @@
 	GdkWindowAttr_1sizeof_FUNC,
 	gdk_1atom_1intern_FUNC,
 	gdk_1atom_1name_FUNC,
+	gdk_1button_1event_1get_1button_FUNC,
 	gdk_1cairo_1create_FUNC,
 	gdk_1cairo_1get_1clip_1rectangle_FUNC,
 	gdk_1cairo_1region_FUNC,
@@ -59,6 +60,7 @@
 	gdk_1cairo_1set_1source_1rgba_FUNC,
 	gdk_1cairo_1set_1source_1window_FUNC,
 	gdk_1clipboard_1set_1content_FUNC,
+	gdk_1crossing_1event_1get_1mode_FUNC,
 	gdk_1cursor_1new_1from_1name__JLjava_lang_String_2_FUNC,
 	gdk_1cursor_1new_1from_1name__Ljava_lang_String_2J_FUNC,
 	gdk_1cursor_1new_1from_1pixbuf_FUNC,
@@ -96,18 +98,15 @@
 	gdk_1event_1get_FUNC,
 	gdk_1event_1get_1button_FUNC,
 	gdk_1event_1get_1coords_FUNC,
-	gdk_1event_1get_1crossing_1mode_FUNC,
 	gdk_1event_1get_1event_1type_FUNC,
-	gdk_1event_1get_1focus_1in_FUNC,
-	gdk_1event_1get_1key_1group_FUNC,
-	gdk_1event_1get_1keycode_FUNC,
 	gdk_1event_1get_1keyval_FUNC,
+	gdk_1event_1get_1modifier_1state_FUNC,
+	gdk_1event_1get_1position_FUNC,
 	gdk_1event_1get_1root_1coords_FUNC,
 	gdk_1event_1get_1scroll_1deltas_FUNC,
 	gdk_1event_1get_1scroll_1direction_FUNC,
 	gdk_1event_1get_1seat_FUNC,
 	gdk_1event_1get_1state_FUNC,
-	gdk_1event_1get_1string_FUNC,
 	gdk_1event_1get_1surface_FUNC,
 	gdk_1event_1get_1time_FUNC,
 	gdk_1event_1get_1window_FUNC,
@@ -115,11 +114,17 @@
 	gdk_1event_1new_FUNC,
 	gdk_1event_1peek_FUNC,
 	gdk_1event_1put_FUNC,
+	gdk_1event_1ref_FUNC,
 	gdk_1event_1set_1device_FUNC,
+	gdk_1event_1unref_FUNC,
+	gdk_1focus_1event_1get_1in_FUNC,
 	gdk_1get_1default_1root_1window_FUNC,
+	gdk_1key_1event_1get_1keyval_FUNC,
+	gdk_1key_1event_1get_1layout_FUNC,
 	gdk_1keymap_1get_1entries_1for_1keyval_FUNC,
 	gdk_1keymap_1get_1for_1display_FUNC,
 	gdk_1keymap_1translate_1keyboard_1state_FUNC,
+	gdk_1keyval_1name_FUNC,
 	gdk_1keyval_1to_1lower_FUNC,
 	gdk_1keyval_1to_1unicode_FUNC,
 	gdk_1monitor_1get_1geometry_FUNC,
@@ -172,6 +177,8 @@
 	gdk_1screen_1height_FUNC,
 	gdk_1screen_1is_1composited_FUNC,
 	gdk_1screen_1width_FUNC,
+	gdk_1scroll_1event_1get_1deltas_FUNC,
+	gdk_1scroll_1event_1get_1direction_FUNC,
 	gdk_1seat_1get_1keyboard_FUNC,
 	gdk_1seat_1get_1pointer_FUNC,
 	gdk_1seat_1grab_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java
index b26bf6a..7ee3d38 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java
@@ -501,12 +501,12 @@
 	 */
 	/* [GTK3 only, if-def'd in os.h] */
 	public static final native void gdk_drag_status(long context, int action, int time);
+
+	/* GDK Events (GTK3 only, if-def'd in os.h) */
 	/** @param event cast=(GdkEvent *) */
 	public static final native long gdk_event_copy(long event);
 	/** @param event cast=(GdkEvent *) */
-	/* [GTK3 only, if-def'd in os.h] */
 	public static final native void gdk_event_free(long event);
-	/* [GTK3 only, if-def'd in os.h] */
 	public static final native long gdk_event_get();
 	/**
 	 * @param event cast=(GdkEvent *)
@@ -516,39 +516,16 @@
 	public static final native boolean gdk_event_get_coords(long event, double[] px, double[] py);
 	/**
 	 * @param event cast=(GdkEvent *)
-	 * @param mode cast=(GdkCrossingMode *)
-	 */
-	/* [GTK4 only, if-def'd in os.h] */
-	public static final native boolean gdk_event_get_crossing_mode(long event, int [] mode);
-	/**
-	 * @param event cast=(GdkEvent *)
 	 * @param button cast=(guint *)
 	 */
 	public static final native boolean gdk_event_get_button(long event, int[] button);
 	/**
 	 * @param event cast=(GdkEvent *)
-	 * @param in cast=(gboolean *)
-	 */
-	/* [GTK4 only, if-def'd in os.h] */
-	public static final native boolean gdk_event_get_focus_in(long event, boolean [] in);
-	/**
-	 * @param event cast=(GdkEvent *)
 	 * @param keyval cast=(guint *)
 	 */
 	public static final native boolean gdk_event_get_keyval(long event,int [] keyval);
 	/**
 	 * @param event cast=(GdkEvent *)
-	 * @param keycode cast=(guint16 *)
-	 */
-	public static final native boolean gdk_event_get_keycode(long event, short [] keycode);
-	/**
-	 * @param event cast=(GdkEvent *)
-	 * @param group cast=(guint *)
-	 */
-	/* [GTK4 only, if-def'd in os.h] */
-	public static final native boolean gdk_event_get_key_group(long event,int [] group);
-	/**
-	 * @param event cast=(GdkEvent *)
 	 * @param x cast=(gdouble *)
 	 * @param y cast=(gdouble *)
 	 */
@@ -559,12 +536,6 @@
 	 */
 	public static final native boolean gdk_event_get_state(long event, int[] pmod);
 	/**
-	 * @param event cast=(GdkEvent *)
-	 * @param string cast=(const char **)
-	 */
-	/* [GTK4 only, if-def'd in os.h] */
-	public static final native boolean gdk_event_get_string(long event, long [] string);
-	/**
 	 * @param event cast=(const GdkEvent *)
 	 * @param delta_x cast=(gdouble *)
 	 * @param delta_y cast=(gdouble *)
@@ -575,6 +546,37 @@
 	 * @param direction cast=(GdkScrollDirection *)
 	 */
 	public static final native boolean gdk_event_get_scroll_direction(long event, int [] direction);
+
+	/* GDK Events (GTK4 only, if-def'd in os.h) */
+	/** @param event cast=(GdkEvent *) */
+	public static final native long gdk_event_ref(long event);
+	/** @param event cast=(GdkEvent *) */
+	public static final native void gdk_event_unref(long event);
+	/**
+	 * @param event cast=(GdkEvent *)
+	 * @param px cast=(gdouble *)
+	 * @param py cast=(gdouble *)
+	 */
+	public static final native boolean gdk_event_get_position(long event, double[] px, double[] py);
+	/** @param event cast=(GdkEvent *) */
+	public static final native int gdk_crossing_event_get_mode(long event);
+	/** @param event cast=(GdkEvent *) */
+	public static final native int gdk_button_event_get_button(long event);
+	/** @param event cast=(GdkEvent *) */
+	public static final native boolean gdk_focus_event_get_in(long event);
+	/** @param event cast=(GdkEvent *) */
+	public static final native int gdk_key_event_get_keyval(long event);
+	/**
+	 * @param event cast=(GdkEvent *)
+	 * */
+	public static final native int gdk_key_event_get_layout(long event);
+	/** @param event cast=(GdkEvent *) */
+	public static final native int gdk_event_get_modifier_state(long event);
+	/** @param event cast=(GdkEvent *) */
+	public static final native void gdk_scroll_event_get_deltas(long event, double[] delta_x, double[] delta_y);
+	/** @param event cast=(GdkEvent *) */
+	public static final native int gdk_scroll_event_get_direction(long event);
+
 	/**
 	 * @method flags=dynamic
 	 */
@@ -636,7 +638,7 @@
 	 * @param keys cast=(GdkKeymapKey**)
 	 * @param n_keys cast=(gint*)
 	 */
-	/* [GTK4 only, if-def'd in os.h] */
+	/* [GTK4 only] */
 	public static final native boolean gdk_display_map_keyval(long display, int keyval, long[] keys, int[] n_keys);
 	/**
 	 * @method flags=dynamic
@@ -662,6 +664,9 @@
 	public static final native boolean gdk_keymap_get_entries_for_keyval(long keymap, int keyval, long [] keys, int[] n_keys);
 	public static final native long gdk_keyval_to_lower(long keyval);
 	public static final native long gdk_keyval_to_unicode(long keyval);
+
+	/** @param keyval cast=(guint) */
+	public static final native long gdk_keyval_name(int keyval);
 	/**
 	 * @method flags=dynamic
 	 */
@@ -884,7 +889,7 @@
 	public static final native long gdk_display_peek_event(long display);
 	/**
 	 * @param display cast=(GdkDisplay *)
-	 * @param event cast=(const GdkEvent *)
+	 * @param event cast=(GdkEvent *)
 	 */
 	public static final native void gdk_display_put_event(long display, long event);
 	/**
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
index 533afdf..64dd34f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
@@ -547,10 +547,16 @@
 			switch (GDK.GDK_EVENT_TYPE (event)) {
 				case GDK.GDK_KEY_PRESS: {
 					if (browser.isFocusControl ()) {
-						int [] key = new int[1];
-						GDK.gdk_event_get_keyval(event, key);
+						int [] key = new int [1];
 						int [] state = new int[1];
-						GDK.gdk_event_get_state(event, state);
+						if (GTK.GTK4) {
+							key[0] = GDK.gdk_key_event_get_keyval(event);
+							state[0] = GDK.gdk_event_get_modifier_state(event);
+						} else {
+							GDK.gdk_event_get_keyval(event, key);
+							GDK.gdk_event_get_state(event, state);
+						}
+						
 						switch (key[0]) {
 							case GDK.GDK_ISO_Left_Tab:
 							case GDK.GDK_Tab: {
@@ -1565,7 +1571,11 @@
 	if (eventPtr != 0) {
 		int eventType = GDK.gdk_event_get_event_type(eventPtr);
 		int [] state = new int[1];
-		GDK.gdk_event_get_state(eventPtr, state);
+		if (GTK.GTK4) {
+			state[0] = GDK.gdk_event_get_modifier_state(eventPtr);
+		} else {
+			GDK.gdk_event_get_state(eventPtr, state);
+		}
 		switch (eventType) {
 			case GDK.GDK_KEY_PRESS:
 			case GDK.GDK_KEY_RELEASE:
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java
index bd4fba9..8101c7e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java
@@ -1357,7 +1357,12 @@
 	* send the mouse event from the event_after handler.
 	*/
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+	}
+
 	int eventType = GDK.gdk_event_get_event_type(event);
 	eventType = fixGdkEventTypeValues(eventType);
 	if (eventType == GDK.GDK_BUTTON_PRESS && eventButton[0] == 1) {
@@ -1569,13 +1574,21 @@
 	switch (eventType) {
 		case GDK.GDK_BUTTON_PRESS: {
 			int [] eventButton = new int [1];
-			GDK.gdk_event_get_button(gdkEvent, eventButton);
+			int [] eventState = new int [1];
+			if (GTK.GTK4) {
+				eventButton[0] = GDK.gdk_button_event_get_button(gdkEvent);
+				eventState[0] = GDK.gdk_event_get_modifier_state(gdkEvent);
+			} else {
+				GDK.gdk_event_get_button(gdkEvent, eventButton);
+				GDK.gdk_event_get_state(gdkEvent, eventState);
+			}
+
 			int eventTime = GDK.gdk_event_get_time(gdkEvent);
+
 			double [] eventRX = new double [1];
 			double [] eventRY = new double [1];
 			GDK.gdk_event_get_root_coords(gdkEvent, eventRX, eventRY);
-			int [] eventState = new int [1];
-			GDK.gdk_event_get_state(gdkEvent, eventState);
+			
 			if (eventButton[0] == 1) {
 				if (!sendMouseEvent (SWT.MouseDown, eventButton[0], display.clickCount, 0, false, eventTime, eventRX[0], eventRY[0], false, eventState[0])) {
 					return 1;
@@ -1590,7 +1603,7 @@
 			if ((style & SWT.READ_ONLY) == 0) {
 				boolean [] focusIn = new boolean [1];
 				if (GTK.GTK4) {
-					GDK.gdk_event_get_focus_in(gdkEvent, focusIn);
+					focusIn[0] = GDK.gdk_focus_event_get_in(gdkEvent);
 				} else {
 					GdkEventFocus gdkEventFocus = new GdkEventFocus ();
 					OS.memmove (gdkEventFocus, gdkEvent, GdkEventFocus.sizeof);
@@ -1669,7 +1682,12 @@
 		int oldIndex = GTK.gtk_combo_box_get_active (handle);
 		int newIndex = oldIndex;
 		int [] eventKeyval = new int [1];
-		GDK.gdk_event_get_keyval(event, eventKeyval);
+		if (GTK.GTK4) {
+			eventKeyval[0] = GDK.gdk_key_event_get_keyval(event);
+		} else {
+			GDK.gdk_event_get_keyval(event, eventKeyval);
+		}
+
 		switch (eventKeyval[0]) {
 			case GDK.GDK_Down:
 			case GDK.GDK_KP_Down:
@@ -2619,8 +2637,13 @@
 
 @Override
 boolean translateTraversal (long event) {
-	int [] key = new int[1];
-	GDK.gdk_event_get_keyval(event, key);
+	int [] key = new int [1];
+	if (GTK.GTK4) {
+		key[0] = GDK.gdk_key_event_get_keyval(event);
+	} else {
+		GDK.gdk_event_get_keyval(event, key);
+	}
+
 	switch (key[0]) {
 		case GDK.GDK_KP_Enter:
 		case GDK.GDK_Return: {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
index 3dd4747..dc4a072 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
@@ -862,7 +862,12 @@
 	*/
 	if ((state & CANVAS) != 0 && socketHandle == 0) {
 		int [] eventKeyval = new int [1];
-		GDK.gdk_event_get_keyval(event, eventKeyval);
+		if (GTK.GTK4) {
+			eventKeyval[0] = GDK.gdk_key_event_get_keyval(event);
+		} else {
+			GDK.gdk_event_get_keyval(event, eventKeyval);
+		}
+
 		switch (eventKeyval[0]) {
 			case GDK.GDK_Return:
 			case GDK.GDK_KP_Enter: return 1;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
index 2868ebe..3bddb4b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
@@ -2733,12 +2733,19 @@
 			eventType = fixGdkEventTypeValues(eventType);
 			switch (eventType) {
 				case GDK.GDK_MOTION_NOTIFY: {
-					int [] state = new int[1];
-					GDK.gdk_event_get_state(eventPtr, state);
 					long gdkResource = gdk_event_get_surface_or_window(eventPtr);
+
+					int [] state = new int[1];
 					double [] eventX = new double[1];
 					double [] eventY = new double[1];
-					GDK.gdk_event_get_coords(eventPtr, eventX, eventY);
+					if (GTK.GTK4) {
+						state[0] = GDK.gdk_event_get_modifier_state(eventPtr);
+						GDK.gdk_event_get_position(eventPtr, eventX, eventY);
+					} else {
+						GDK.gdk_event_get_state(eventPtr, state);
+						GDK.gdk_event_get_coords(eventPtr, eventX, eventY);
+					}
+
 					if ((state[0] & GDK.GDK_BUTTON1_MASK) != 0) {
 						if (GTK.gtk_drag_check_threshold (handle, x, y, (int) eventX[0], (int) eventY[0])) {
 							dragging = true;
@@ -2758,7 +2765,12 @@
 				case GDK.GDK_KEY_PRESS:
 				case GDK.GDK_KEY_RELEASE: {
 					int [] eventKeyval = new int [1];
-					GDK.gdk_event_get_keyval(eventPtr, eventKeyval);
+					if (GTK.GTK4) {
+						eventKeyval[0] = GDK.gdk_key_event_get_keyval(eventPtr);
+					} else {
+						GDK.gdk_event_get_keyval(eventPtr, eventKeyval);
+					}
+
 					if (eventKeyval[0] == GDK.GDK_Escape) quit = true;
 					break;
 				}
@@ -3423,15 +3435,31 @@
 	// Event fields
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+	}
+
 	double [] eventRX = new double [1];
 	double [] eventRY = new double [1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
+
 	int eventTime = GDK.gdk_event_get_time(event);
+
 	int [] eventState = new int[1];
-	GDK.gdk_event_get_state(event, eventState);
+	if (GTK.GTK4) {
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_state(event, eventState);
+	}
 
 	lastInput.x = (int) eventX[0];
 	lastInput.y = (int) eventY[0];
@@ -3466,15 +3494,31 @@
 	// Event fields
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+	}
+
 	int eventTime = GDK.gdk_event_get_time(event);
+
 	double [] eventRX = new double [1];
 	double [] eventRY = new double [1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
-	int [] eventState = new int [1];
-	GDK.gdk_event_get_state(event, eventState);
+
+	int [] eventState = new int[1];
+	if (GTK.GTK4) {
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_state(event, eventState);
+	}
 
 	lastInput.x = (int) eventX[0];
 	lastInput.y = (int) eventY[0];
@@ -3494,18 +3538,31 @@
 	// Event fields
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	int eventType = GDK.gdk_event_get_event_type(event);
 	eventType = fixGdkEventTypeValues(eventType);
+
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	int [] eventState = new int[1];
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+		GDK.gdk_event_get_state(event, eventState);
+	}
+
 	int eventTime = GDK.gdk_event_get_time(event);
+	
 	double [] eventRX = new double [1];
 	double [] eventRY = new double [1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
-	int [] eventState = new int [1];
-	GDK.gdk_event_get_state(event, eventState);
-
+	
 	lastInput.x = (int) eventX[0];
 	lastInput.y = (int) eventY[0];
 	if (containedInRegion(lastInput.x, lastInput.y)) return 0;
@@ -3598,15 +3655,27 @@
 	// Event fields
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	int [] eventState = new int[1];
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+		GDK.gdk_event_get_state(event, eventState);
+	}
+
 	int eventTime = GDK.gdk_event_get_time(event);
+
 	double [] eventRX = new double [1];
 	double [] eventRY = new double [1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
-	int [] eventState = new int [1];
-	GDK.gdk_event_get_state(event, eventState);
 
 	lastInput.x = (int) eventX[0];
 	lastInput.y = (int) eventY[0];
@@ -3643,23 +3712,33 @@
 	GTK.gtk_widget_set_tooltip_text (toolHandle, buffer);
 
 	if (display.currentControl == this) return 0;
-	GdkEventCrossing gdkEvent = new GdkEventCrossing ();
-	long childGdkResource = 0;
-	int [] crossingMode = new int[1];
+
 	int [] state = new int [1];
-	GDK.gdk_event_get_state(event, state);
+	double [] eventX = new double [1];
+	double [] eventY = new double [1];
+	if (GTK.GTK4) {
+		state[0] = GDK.gdk_event_get_modifier_state(event);
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_state(event, state);
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	int time = GDK.gdk_event_get_time(event);
+
 	double [] eventRX = new double [1];
 	double [] eventRY = new double [1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
-	double [] eventX = new double [1];
-	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+
 	lastInput.x = (int) eventX[0];
 	lastInput.y = (int) eventY[0];
 	if (containedInRegion(lastInput.x, lastInput.y)) return 0;
+
+	GdkEventCrossing gdkEvent = new GdkEventCrossing ();
+	long childGdkResource = 0;
+	int [] crossingMode = new int[1];
 	if (GTK.GTK4) {
-		GDK.gdk_event_get_crossing_mode(event, crossingMode);
+		crossingMode[0] = GDK.gdk_crossing_event_get_mode(event);
 		// TODO_GTK4: GTK devs are still deciding whether or not
 		// to provide API for GdkEventCrossing->child_surface.
 	} else {
@@ -3708,8 +3787,14 @@
 				double [] eventRX = new double [1];
 				double [] eventRY = new double [1];
 				GDK.gdk_event_get_root_coords(gdkEvent, eventRX, eventRY);
+
 				int [] eventButton = new int [1];
-				GDK.gdk_event_get_button(gdkEvent, eventButton);
+				if (GTK.GTK4) {
+					eventButton[0] = GDK.gdk_button_event_get_button(gdkEvent);
+				} else {
+					GDK.gdk_event_get_button(gdkEvent, eventButton);
+				}
+
 				if (eventButton[0] == 3) {
 					showMenu ((int) eventRX[0], (int) eventRY[0]);
 				}
@@ -3720,7 +3805,7 @@
 			if (!isFocusHandle (widget)) break;
 			boolean [] focusIn = new boolean [1];
 			if (GTK.GTK4) {
-				GDK.gdk_event_get_focus_in(gdkEvent, focusIn);
+				focusIn[0] = GDK.gdk_focus_event_get_in(gdkEvent);
 			} else {
 				GdkEventFocus gdkEventFocus = new GdkEventFocus ();
 				OS.memmove (gdkEventFocus, gdkEvent, GdkEventFocus.sizeof);
@@ -3906,7 +3991,12 @@
 @Override
 long gtk_key_press_event (long widget, long event) {
 	int [] eventKeyval = new int [1];
-	GDK.gdk_event_get_keyval(event, eventKeyval);
+	if (GTK.GTK4) {
+		eventKeyval[0] = GDK.gdk_key_event_get_keyval(event);
+	} else {
+		GDK.gdk_event_get_keyval(event, eventKeyval);
+	}
+
 	if (!hasFocus ()) {
 		/*
 		* Feature in GTK.  On AIX, the IME window deactivates the current shell and even
@@ -3946,22 +4036,32 @@
 @Override
 long gtk_leave_notify_event (long widget, long event) {
 	if (display.currentControl != this) return 0;
-	GdkEventCrossing gdkEvent = new GdkEventCrossing ();
-	int [] crossingMode = new int[1];
+
 	int [] state = new int [1];
-	GDK.gdk_event_get_state(event, state);
+	double [] eventX = new double [1];
+	double [] eventY = new double [1];
+	if (GTK.GTK4) {
+		state[0] = GDK.gdk_event_get_modifier_state(event);
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_state(event, state);
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	int time = GDK.gdk_event_get_time(event);
+
 	double [] eventRX = new double [1];
 	double [] eventRY = new double [1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
-	double [] eventX = new double [1];
-	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	
 	lastInput.x = (int) eventX[0];
 	lastInput.y = (int) eventY[0];
 	if (containedInRegion(lastInput.x, lastInput.y)) return 0;
+
+	GdkEventCrossing gdkEvent = new GdkEventCrossing ();
+	int [] crossingMode = new int[1];
 	if (GTK.GTK4) {
-		GDK.gdk_event_get_crossing_mode(event, crossingMode);
+		crossingMode[0] = GDK.gdk_crossing_event_get_mode(event);
 	} else {
 		OS.memmove(gdkEvent, event, GdkEventCrossing.sizeof);
 		crossingMode[0] = gdkEvent.mode;
@@ -4005,12 +4105,18 @@
 		dragBegun = true;
 	}
 	int result;
-	double [] eventX = new double[1];
-	double [] eventY = new double[1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	double [] eventX = new double [1];
+	double [] eventY = new double [1];
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	double [] eventRX = new double[1];
 	double [] eventRY = new double[1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
+
 	lastInput.x = (int) eventX[0];
 	lastInput.y = (int) eventY[0];
 	if (containedInRegion(lastInput.x, lastInput.y)) return 0;
@@ -4033,11 +4139,19 @@
 			GTK.gtk_event_controller_handle_event(dragGesture,event);
 			int eventType = GDK.gdk_event_get_event_type(event);
 			if (eventType == GDK.GDK_3BUTTON_PRESS) return 0;
+
 			Point scaledEvent = DPIUtil.autoScaleDown(new Point((int)eventX[0], (int) eventY[0]));
+
 			int [] eventButton = new int [1];
-			GDK.gdk_event_get_button(event, eventButton);
 			int [] eventState = new int [1];
-			GDK.gdk_event_get_state(event, eventState);
+			if (GTK.GTK4) {
+				eventButton[0] = GDK.gdk_button_event_get_button(event);
+				eventState[0] = GDK.gdk_event_get_modifier_state(event);
+			} else {
+				GDK.gdk_event_get_button(event, eventButton);
+				GDK.gdk_event_get_state(event, eventState);
+			}
+
 			if (sendDragEvent (eventButton[0], eventState[0], scaledEvent.x, scaledEvent.y, false)){
 				return 1;
 			}
@@ -4061,7 +4175,7 @@
 			state[0] = mask [0];
 		}
 	} else {
-		GDK.gdk_event_get_state(event, state);
+		state[0] = GDK.gdk_event_get_modifier_state(event);
 	}
 	int time = GDK.gdk_event_get_time(event);
 	if (this != display.currentControl) {
@@ -4119,20 +4233,36 @@
 @Override
 long gtk_scroll_event (long widget, long eventPtr) {
 	long result = 0;
-	double [] eventX = new double[1];
-	double [] eventY = new double[1];
-	GDK.gdk_event_get_coords(eventPtr, eventX, eventY);
+	double [] eventX = new double [1];
+	double [] eventY = new double [1];
+	int [] state = new int [1];
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(eventPtr, eventX, eventY);
+		state[0] = GDK.gdk_event_get_modifier_state(eventPtr);
+	} else {
+		GDK.gdk_event_get_coords(eventPtr, eventX, eventY);
+		GDK.gdk_event_get_state(eventPtr, state);
+	}
+
 	double [] eventRX = new double[1];
 	double [] eventRY = new double[1];
 	GDK.gdk_event_get_root_coords(eventPtr, eventRX, eventRY);
+
 	int time = GDK.gdk_event_get_time(eventPtr);
-	int [] state = new int[1];
-	GDK.gdk_event_get_state(eventPtr, state);
+
+	int [] direction = new int[1];
+	boolean fetched;
+	if (GTK.GTK4) {
+		direction[0] = GDK.gdk_scroll_event_get_direction(eventPtr);
+		fetched = direction[0] != GDK.GDK_SCROLL_SMOOTH;
+	} else {
+		fetched = GDK.gdk_event_get_scroll_direction(eventPtr, direction);
+	}
+
 	lastInput.x = (int) eventX[0];
 	lastInput.y = (int) eventY[0];
-	int [] direction = new int[1];
-	boolean fetched = GDK.gdk_event_get_scroll_direction(eventPtr, direction);
 	if (containedInRegion(lastInput.x, lastInput.y)) return 0;
+
 	if (fetched) {
 		switch (direction[0]) {
 			case GDK.GDK_SCROLL_UP:
@@ -4146,7 +4276,16 @@
 		}
 	} else {
 		double[] delta_x = new double[1], delta_y = new double [1];
-		if (GDK.gdk_event_get_scroll_deltas (eventPtr, delta_x, delta_y)) {
+		boolean deltasAvailable;
+		if (GTK.GTK4) {
+			GDK.gdk_scroll_event_get_deltas(eventPtr, delta_x, delta_y);
+			// In GTK4, deltas is always available but zero when not GDK_SMOOTH_SCROLL
+			deltasAvailable = true;
+		} else {
+			deltasAvailable = GDK.gdk_event_get_scroll_deltas (eventPtr, delta_x, delta_y);
+		}
+
+		if (deltasAvailable) {
 			if (delta_x [0] != 0) {
 				result = (sendMouseEvent (SWT.MouseHorizontalWheel, 0, (int)(-3 * delta_x [0]), 0, true, time, eventRX[0], eventRY[0], false, state[0]) ? 0 : 1);
 			}
@@ -6390,7 +6529,12 @@
 boolean translateMnemonic (int keyval, long event) {
 	long key = GDK.gdk_keyval_to_unicode (keyval);
 	int [] state = new int[1];
-	GDK.gdk_event_get_state(event, state);
+	if (GTK.GTK4) {
+		state[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_state(event, state);
+	}
+
 	if (key < 0x20) return false;
 	if (state[0] == 0) {
 		int code = traversalCode (keyval, event);
@@ -6413,10 +6557,17 @@
 
 boolean translateTraversal (long event) {
 	int detail = SWT.TRAVERSE_NONE;
+
 	int [] eventKeyval = new int [1];
-	GDK.gdk_event_get_keyval(event, eventKeyval);
 	int [] eventState = new int[1];
-	GDK.gdk_event_get_state(event, eventState);
+	if (GTK.GTK4) {
+		eventKeyval[0] = GDK.gdk_key_event_get_keyval(event);
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_keyval(event, eventKeyval);
+		GDK.gdk_event_get_state(event, eventState);
+	}
+
 	int key = eventKeyval[0];
 	int code = traversalCode (key, event);
 	boolean all = false;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/DateTime.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/DateTime.java
index 2b9d271..5e24a28 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/DateTime.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/DateTime.java
@@ -1926,8 +1926,13 @@
 @Override
 long gtk_key_press_event (long widget, long event) {
 	if (!isReadOnly () && (isTime () || isDate ())) {
-		int [] key = new int[1];
-		GDK.gdk_event_get_keyval(event, key);
+		int [] key = new int [1];
+		if (GTK.GTK4) {
+			key[0] = GDK.gdk_key_event_get_keyval(event);
+		} else {
+			GDK.gdk_event_get_keyval(event, key);
+		}
+
 		switch (key[0]) {
 		case GDK.GDK_Up:
 		case GDK.GDK_KP_Up:
@@ -2081,7 +2086,12 @@
 long gtk_button_release_event (long widget, long event) {
 	if (isDate () || isTime ()) {
 		int [] eventButton = new int [1];
-		GDK.gdk_event_get_button(event, eventButton);
+		if (GTK.GTK4) {
+			eventButton[0] = GDK.gdk_button_event_get_button(event);
+		} else {
+			GDK.gdk_event_get_button(event, eventButton);
+		}
+
 		if (eventButton[0] == 1) { // left mouse button.
 			onTextMouseClick ();
 		}
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 46ca33b..0ce2ab6 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
@@ -1479,7 +1479,14 @@
 		}
 	}
 	if (!dispatch) {
-		addGdkEvent (GDK.gdk_event_copy (event));
+		long copiedEvent;
+		if (GTK.GTK4) {
+			copiedEvent = GDK.gdk_event_ref (event);
+		} else {
+			copiedEvent = GDK.gdk_event_copy (event);
+		}
+
+		addGdkEvent (copiedEvent);
 		return 0;
 	}
 	dispatch = true;
@@ -4323,10 +4330,11 @@
 				} else {
 					GDK.gdk_event_put (eventPtr);
 				}
+
 				if (GTK.GTK4) {
-					OS.g_object_unref(eventPtr);
+					GDK.gdk_event_unref(eventPtr);
 				} else {
-					GDK.gdk_event_free (eventPtr);
+					GDK.gdk_event_free(eventPtr);
 				}
 				return true;
 			case SWT.MouseDown:
@@ -4356,9 +4364,9 @@
 
 				GDK.gdk_event_put(eventPtr);
 				if (GTK.GTK4) {
-					OS.g_object_unref(eventPtr);
+					GDK.gdk_event_unref(eventPtr);
 				} else {
-					GDK.gdk_event_free (eventPtr);
+					GDK.gdk_event_free(eventPtr);
 				}
 				return true;
 		}
@@ -4402,7 +4410,7 @@
 				}
 			}
 			if (GTK.GTK4) {
-				OS.g_object_unref (event);
+				GDK.gdk_event_unref (event);
 			} else {
 				GDK.gdk_event_free (event);
 			}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ExpandBar.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ExpandBar.java
index e8800f7..c199f52 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ExpandBar.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ExpandBar.java
@@ -318,8 +318,14 @@
 		if (items [index].hasFocus ()) break;
 		index++;
 	}
-	int [] key = new int[1];
-	GDK.gdk_event_get_keyval(event, key);
+
+	int [] key = new int [1];
+	if (GTK.GTK4) {
+		key[0] = GDK.gdk_key_event_get_keyval(event);
+	} else {
+		GDK.gdk_event_get_keyval(event, key);
+	}
+
 	boolean next = false;
 	switch (key[0]) {
 		case GDK.GDK_Up:
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java
index 85da7a6..4d2a6e9 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java
@@ -330,13 +330,25 @@
 long gtk_button_press_event (long widget, long event) {
 	long result = super.gtk_button_press_event (widget, event);
 	if (result != 0) return result;
+
 	int eventType = GDK.gdk_event_get_event_type(event);
 	eventType = fixGdkEventTypeValues(eventType);
+
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+	}
+
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	if (eventButton[0] == 1 && eventType == GDK.GDK_BUTTON_PRESS) {
 		if (focusIndex != -1) setFocus ();
 		int x = (int) eventX[0];
@@ -376,11 +388,22 @@
 	long result = super.gtk_button_release_event (widget, event);
 	if (result != 0) return result;
 	if (focusIndex == -1) return result;
+
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+	}
+
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	if (eventButton[0] == 1) {
 		int x = (int) eventX[0];
 		int y = (int) eventY[0];
@@ -429,8 +452,13 @@
 	long result = super.gtk_key_press_event (widget, eventPtr);
 	if (result != 0) return result;
 	if (focusIndex == -1) return result;
-	int [] key = new int[1];
-	GDK.gdk_event_get_keyval(eventPtr, key);
+
+	int [] key = new int [1];
+	if (GTK.GTK4) {
+		key[0] = GDK.gdk_key_event_get_keyval(eventPtr);
+	} else {
+		GDK.gdk_event_get_keyval(eventPtr, key);
+	}
 	switch (key[0]) {
 		case GDK.GDK_Return:
 		case GDK.GDK_KP_Enter:
@@ -459,13 +487,21 @@
 long gtk_motion_notify_event (long widget, long event) {
 	long result = super.gtk_motion_notify_event (widget, event);
 	if (result != 0) return result;
+
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	int [] state = new int [1];
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+		state[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+		GDK.gdk_event_get_state(event, state);
+	}
+
 	int x = (int) eventX[0];
 	int y = (int) eventY[0];
-	int [] state = new int [1];
-	GDK.gdk_event_get_state(event, state);
+
 	if ((style & SWT.MIRRORED) != 0) x = getClientWidth () - x;
 	if ((state[0] & GDK.GDK_BUTTON1_MASK) != 0) {
 		int oldSelection = selection.y;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java
index 881cbe6..614502d 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java
@@ -798,12 +798,20 @@
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
 	GDK.gdk_event_get_coords(event, eventX, eventY);
+
 	int eventType = GDK.gdk_event_get_event_type(event);
 	eventType = fixGdkEventTypeValues(eventType);
+
 	int [] eventState = new int [1];
-	GDK.gdk_event_get_state(event, eventState);
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+		GDK.gdk_event_get_state(event, eventState);
+	}
+
 	if ((state & DRAG_DETECT) != 0 && hooks (SWT.DragDetect) &&
 			!OS.isX11() && eventType == GDK.GDK_BUTTON_PRESS) { // Wayland
 		// check to see if there is another event coming in that is not a double/triple click, this is to prevent Bug 514531
@@ -913,8 +921,13 @@
 
 @Override
 long gtk_key_press_event (long widget, long event) {
-	int [] key = new int[1];
-	GDK.gdk_event_get_keyval(event, key);
+	int [] key = new int [1];
+	if (GTK.GTK4) {
+		key[0] = GDK.gdk_key_event_get_keyval(event);
+	} else {
+		GDK.gdk_event_get_keyval(event, key);
+	}
+
 	keyPressDefaultSelectionHandler (event, key[0]);
 	return super.gtk_key_press_event (widget, event);
 }
@@ -922,10 +935,16 @@
 @Override
 long gtk_button_release_event (long widget, long event) {
 	int [] eventState = new int [1];
-	GDK.gdk_event_get_state(event, eventState);
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	if (GTK.GTK4) {
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_state(event, eventState);
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	long eventGdkResource = gdk_event_get_surface_or_window(event);
 	if (GTK.GTK4) {
 		if (eventGdkResource != gtk_widget_get_surface (handle)) return 0;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java
index b5269e2..efb2094 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java
@@ -170,11 +170,18 @@
 	if (result != 0) return result;
 	// Event fields
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+	}
+
 	int eventType = GDK.gdk_event_get_event_type(event);
+
 	double [] eventRX = new double [1];
 	double [] eventRY = new double [1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
+
 	int eventTime = GDK.gdk_event_get_time(event);
 
 	int button = eventButton[0];
@@ -224,13 +231,21 @@
 long gtk_button_release_event (long widget, long event) {
 	long result = super.gtk_button_release_event (widget, event);
 	if (result != 0) return result;
+
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+	}
+
 	int eventTime = GDK.gdk_event_get_time(event);
+
 	int button = eventButton[0];
 	if (button != 1) return 0;
 	if (!dragging) return 0;
 	dragging = false;
+
 	GtkAllocation allocation = new GtkAllocation ();
 	GTK.gtk_widget_get_allocation (handle, allocation);
 	int width = allocation.width;
@@ -284,10 +299,17 @@
 long gtk_key_press_event (long widget, long eventPtr) {
 	long result = super.gtk_key_press_event (widget, eventPtr);
 	if (result != 0) return result;
-	int [] key = new int[1];
-	GDK.gdk_event_get_keyval(eventPtr, key);
+	
+	int [] key = new int [1];
 	int [] state = new int[1];
-	GDK.gdk_event_get_state(eventPtr, state);
+	if (GTK.GTK4) {
+		key[0] = GDK.gdk_key_event_get_keyval(eventPtr);
+		state[0] = GDK.gdk_event_get_modifier_state(eventPtr);
+	} else {
+		GDK.gdk_event_get_keyval(eventPtr, key);
+		GDK.gdk_event_get_state(eventPtr, state);
+	}
+
 	switch (key[0]) {
 		case GDK.GDK_Left:
 		case GDK.GDK_Right:
@@ -367,8 +389,14 @@
 	double [] fetchedX = new double [1];
 	double [] fetchedY = new double [1];
 	GDK.gdk_event_get_root_coords(eventPtr, fetchedX, fetchedY);
+	
 	int [] state = new int [1];
-	GDK.gdk_event_get_state(eventPtr, state);
+	if (GTK.GTK4) {
+		state[0] = GDK.gdk_event_get_modifier_state(eventPtr);
+	} else {
+		GDK.gdk_event_get_state(eventPtr, state);
+	}
+	
 	long gdkResource = gdk_event_get_surface_or_window(eventPtr);
 	boolean isHint;
 	if (GTK.GTK4) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ScrollBar.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ScrollBar.java
index 55ec88c..b5620ab 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ScrollBar.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ScrollBar.java
@@ -579,7 +579,12 @@
 	switch (eventType) {
 		case GDK.GDK_BUTTON_RELEASE: {
 			int [] eventButton = new int [1];
-			GDK.gdk_event_get_button(gdkEvent, eventButton);
+			if (GTK.GTK4) {
+				eventButton[0] = GDK.gdk_button_event_get_button(gdkEvent);
+			} else {
+				GDK.gdk_event_get_button(gdkEvent, eventButton);
+			}
+
 			if (eventButton[0] == 1 && detail == GTK.GTK_SCROLL_JUMP) {
 				if (!dragSent) {
 					Event event = new Event ();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java
index 2375f6f..5bb3b80 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java
@@ -358,10 +358,26 @@
 	if ((state & CANVAS) != 0) {
 		ScrollBar scrollBar;
 		int [] direction = new int[1];
-		boolean fetched = GDK.gdk_event_get_scroll_direction(eventPtr, direction);
+		boolean fetched;
+		if (GTK.GTK4) {
+			direction[0] = GDK.gdk_scroll_event_get_direction(eventPtr);
+			fetched = direction[0] != GDK.GDK_SCROLL_SMOOTH;
+		} else {
+			fetched = GDK.gdk_event_get_scroll_direction(eventPtr, direction);
+		}
+
 		if (!fetched) {
 			double[] delta_x = new double[1], delta_y = new double [1];
-			if (GDK.gdk_event_get_scroll_deltas (eventPtr, delta_x, delta_y)) {
+			boolean deltasAvailable;
+			if (GTK.GTK4) {
+				GDK.gdk_scroll_event_get_deltas(eventPtr, delta_x, delta_y);
+				// In GTK4, deltas is always available but zero when not GDK_SMOOTH_SCROLL
+				deltasAvailable = true;
+			} else {
+				deltasAvailable = GDK.gdk_event_get_scroll_deltas (eventPtr, delta_x, delta_y);
+			}
+
+			if (deltasAvailable) {
 				if (delta_x [0] != 0) {
 					scrollBar = horizontalBar;
 					if (scrollBar != null && !GTK.gtk_widget_get_visible (scrollBar.handle) && scrollBar.getEnabled()) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
index d0407ed..0d11ebb 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
@@ -1424,8 +1424,14 @@
 			double [] eventRX = new double [1];
 			double [] eventRY = new double [1];
 			GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
+
 			int [] eventButton = new int [1];
-			GDK.gdk_event_get_button(event, eventButton);
+			if (GTK.GTK4) {
+				eventButton[0] = GDK.gdk_button_event_get_button(event);
+			} else {
+				GDK.gdk_event_get_button(event, eventButton);
+			}
+
 			if (eventButton[0] == 1) {
 				display.resizeLocationX = eventRX[0];
 				display.resizeLocationY = eventRY[0];
@@ -1576,7 +1582,12 @@
 	if (widget == shellHandle) {
 		if (isCustomResize ()) {
 			int [] state = new int [1];
-			GDK.gdk_event_get_state(event, state);
+			if (GTK.GTK4) {
+				state[0] = GDK.gdk_event_get_modifier_state(event);
+			} else {
+				GDK.gdk_event_get_state(event, state);
+			}
+
 			if ((state[0] & GDK.GDK_BUTTON1_MASK) == 0) {
 				if (GTK.GTK4) {
 					GTK.gtk_widget_set_cursor (shellHandle, 0);
@@ -1617,7 +1628,11 @@
 	if (widget == shellHandle) {
 		if (isCustomResize ()) {
 			int [] state = new int [1];
-			GDK.gdk_event_get_state(event, state);
+			if (GTK.GTK4) {
+				state[0] = GDK.gdk_event_get_modifier_state(event);
+			} else {
+				GDK.gdk_event_get_state(event, state);
+			}
 			double [] eventRX = new double [1];
 			double [] eventRY = new double [1];
 			GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
@@ -1679,7 +1694,12 @@
 			} else {
 				double [] eventX = new double [1];
 				double [] eventY = new double [1];
-				GDK.gdk_event_get_coords(event, eventX, eventY);
+				if (GTK.GTK4) {
+					GDK.gdk_event_get_position(event, eventX, eventY);
+				} else {
+					GDK.gdk_event_get_coords(event, eventX, eventY);
+				}
+
 				int mode = getResizeMode (eventX[0], eventY[0]);
 				if (mode != display.resizeMode) {
 					long cursor = display.getSystemCursor(mode).handle;
@@ -1716,10 +1736,16 @@
 					GTK.gtk_accelerator_parse (accel [0], keyval, mods);
 					OS.g_free (accel [0]);
 					if (keyval [0] != 0) {
-						int [] key = new int[1];
-						GDK.gdk_event_get_keyval(event, key);
-						int [] state = new int [1];
-						GDK.gdk_event_get_state(event, state);
+						int [] key = new int [1];
+						int [] state = new int[1];
+						if (GTK.GTK4) {
+							key[0] = GDK.gdk_key_event_get_keyval(event);
+							state[0] = GDK.gdk_event_get_modifier_state(event);
+						} else {
+							GDK.gdk_event_get_keyval(event, key);
+							GDK.gdk_event_get_state(event, state);
+						}
+
 						int mask = GTK.gtk_accelerator_get_default_mod_mask ();
 						if (key[0] == keyval [0] && (state[0] & mask) == (mods [0] & mask)) {
 							return focusControl.gtk_key_press_event (focusControl.focusHandle (), event);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Slider.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Slider.java
index 21aca63..af53197 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Slider.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Slider.java
@@ -230,7 +230,12 @@
 	switch (eventType) {
 		case GDK.GDK_BUTTON_RELEASE: {
 			int [] eventButton = new int [1];
-			GDK.gdk_event_get_button(gdkEvent, eventButton);
+			if (GTK.GTK4) {
+				eventButton[0] = GDK.gdk_button_event_get_button(gdkEvent);
+			} else {
+				GDK.gdk_event_get_button(gdkEvent, eventButton);
+			}
+
 			if (eventButton[0] == 1 && detail == SWT.DRAG) {
 				if (!dragSent) {
 					Event event = new Event ();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Spinner.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Spinner.java
index 3ffbfa7..e035c52 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Spinner.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Spinner.java
@@ -1220,8 +1220,13 @@
 
 @Override
 boolean translateTraversal (long event) {
-	int [] key = new int[1];
-	GDK.gdk_event_get_keyval(event, key);
+	int [] key = new int [1];
+	if (GTK.GTK4) {
+		key[0] = GDK.gdk_key_event_get_keyval(event);
+	} else {
+		GDK.gdk_event_get_keyval(event, key);
+	}
+
 	switch (key[0]) {
 		case GDK.GDK_KP_Enter:
 		case GDK.GDK_Return: {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
index aeeab7b..63f08ff 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
@@ -2017,22 +2017,36 @@
 long gtk_button_press_event (long widget, long event) {
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	int eventType = GDK.gdk_event_get_event_type(event);
 	eventType = fixGdkEventTypeValues(eventType);
+
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	int [] eventState = new int [1];
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+		GDK.gdk_event_get_state(event, eventState);
+	}
+
 	double [] eventRX = new double [1];
 	double [] eventRY = new double [1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
-	int [] eventState = new int [1];
-	GDK.gdk_event_get_state(event, eventState);
+	
 	long eventGdkResource = gdk_event_get_surface_or_window(event);
 	if (GTK.GTK4) {
 		if (eventGdkResource != gtk_widget_get_surface (handle)) return 0;
 	} else {
 		if (eventGdkResource != GTK.gtk_tree_view_get_bin_window (handle)) return 0;
 	}
+
 	long result = super.gtk_button_press_event (widget, event);
 	if (result != 0) return result;
 	/*
@@ -2148,8 +2162,13 @@
 
 @Override
 long gtk_key_press_event (long widget, long event) {
-	int [] key = new int[1];
-	GDK.gdk_event_get_keyval(event, key);
+	int [] key = new int [1];
+	if (GTK.GTK4) {
+		key[0] = GDK.gdk_key_event_get_keyval(event);
+	} else {
+		GDK.gdk_event_get_keyval(event, key);
+	}
+
 	keyPressDefaultSelectionHandler (event, key[0]);
 	return super.gtk_key_press_event (widget, event);
 }
@@ -2198,14 +2217,26 @@
 long gtk_button_release_event (long widget, long event) {
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	int [] eventState = new int [1];
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+		GDK.gdk_event_get_state(event, eventState);
+	}
+
 	double [] eventRX = new double [1];
 	double [] eventRY = new double [1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
-	int [] eventState = new int [1];
-	GDK.gdk_event_get_state(event, eventState);
+
 	long eventGdkResource = gdk_event_get_surface_or_window(event);
 	if (GTK.GTK4) {
 		if (eventGdkResource != gtk_widget_get_surface (handle)) return 0;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableColumn.java
index 47cf8f6..0f94122 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableColumn.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableColumn.java
@@ -350,7 +350,12 @@
 	long eventPtr = GTK.gtk_get_current_event ();
 	if (eventPtr != 0) {
 		int [] eventButton = new int [1];
-		GDK.gdk_event_get_button(eventPtr, eventButton);
+		if (GTK.GTK4) {
+			eventButton[0] = GDK.gdk_button_event_get_button(eventPtr);
+		} else {
+			GDK.gdk_event_get_button(eventPtr, eventButton);
+		}
+
 		int eventType = GDK.gdk_event_get_event_type(eventPtr);
 		eventType = Control.fixGdkEventTypeValues(eventType);
 		int eventTime = GDK.gdk_event_get_time(eventPtr);
@@ -378,7 +383,12 @@
 	switch (eventType) {
 		case GDK.GDK_BUTTON_PRESS: {
 			int [] eventButton = new int [1];
-			GDK.gdk_event_get_button(gdkEvent, eventButton);
+			if (GTK.GTK4) {
+				eventButton[0] = GDK.gdk_button_event_get_button(gdkEvent);
+			} else {
+				GDK.gdk_event_get_button(gdkEvent, eventButton);
+			}
+
 			if (eventButton[0] == 3) {
 				double [] eventRX = new double [1];
 				double [] eventRY = new double [1];
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 7fdcc1a..36db69c 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
@@ -1655,7 +1655,7 @@
 			case GDK.GDK_FOCUS_CHANGE:
 				boolean [] focusIn = new boolean [1];
 				if (GTK.GTK4) {
-					GDK.gdk_event_get_focus_in(gdkEvent, focusIn);
+					focusIn[0] = GDK.gdk_focus_event_get_in(gdkEvent);
 				} else {
 					GdkEventFocus gdkEventFocus = new GdkEventFocus ();
 					OS.memmove (gdkEventFocus, gdkEvent, GdkEventFocus.sizeof);
@@ -1774,16 +1774,19 @@
 	if (hooks (SWT.Segments) || filters (SWT.Segments)) {
 		int length;
 		int [] state = new int[1];
-		GDK.gdk_event_get_state(event, state);
+		int [] keyval = new int [1];
 		if (GTK.GTK4) {
-			long [] eventString = new long [1];
-			GDK.gdk_event_get_string(event, eventString);
-			length = (int)OS.g_utf16_strlen (eventString[0], -1);
+			state[0] = GDK.gdk_event_get_modifier_state(event);
+			keyval[0] = GDK.gdk_key_event_get_keyval(event);
+
 		} else {
-			GdkEventKey gdkEvent = new GdkEventKey ();
-			OS.memmove(gdkEvent, event, GdkEventKey.sizeof);
-			length = gdkEvent.length;
+			GDK.gdk_event_get_state(event, state);
+			GDK.gdk_event_get_keyval(event, keyval);
 		}
+
+		long eventStringPtr = GDK.gdk_keyval_name(keyval[0]);
+		length = (int)OS.g_utf16_strlen (eventStringPtr, -1);
+
 		if (length > 0 && (state[0] & (GDK.GDK_MOD1_MASK | GDK.GDK_CONTROL_MASK)) == 0) {
 			handleSegments = true;
 			if (segments != null) {
@@ -2741,8 +2744,13 @@
 
 @Override
 boolean translateTraversal (long event) {
-	int [] key = new int[1];
-	GDK.gdk_event_get_keyval(event, key);
+	int [] key = new int [1];
+	if (GTK.GTK4) {
+		key[0] = GDK.gdk_key_event_get_keyval(event);
+	} else {
+		GDK.gdk_event_get_keyval(event, key);
+	}
+
 	switch (key[0]) {
 		case GDK.GDK_KP_Enter:
 		case GDK.GDK_Return: {
@@ -2768,8 +2776,12 @@
 	if ((style & SWT.MULTI) != 0) {
 		bits &= ~SWT.TRAVERSE_RETURN;
 		if (key == GDK.GDK_Tab && event != 0) {
-			int [] eventState = new int [1];
-			GDK.gdk_event_get_state(event, eventState);
+			int [] eventState = new int[1];
+			if (GTK.GTK4) {
+				eventState[0] = GDK.gdk_event_get_modifier_state(event);
+			} else {
+				GDK.gdk_event_get_state(event, eventState);
+			}
 			boolean next = (eventState[0] & GDK.GDK_SHIFT_MASK) == 0;
 			if (next && (eventState[0] & GDK.GDK_CONTROL_MASK) == 0) {
 				bits &= ~(SWT.TRAVERSE_TAB_NEXT | SWT.TRAVERSE_TAB_PREVIOUS);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java
index 708874b..ee7e5b2 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java
@@ -678,7 +678,12 @@
 	switch (eventType) {
 		case GDK.GDK_BUTTON_PRESS: {
 			int [] eventButton = new int [1];
-			GDK.gdk_event_get_button(gdkEvent, eventButton);
+			if (GTK.GTK4) {
+				eventButton[0] = GDK.gdk_button_event_get_button(gdkEvent);
+			} else {
+				GDK.gdk_event_get_button(gdkEvent, eventButton);
+			}
+
 			if (eventButton[0] == 3) {
 				double [] eventRX = new double [1];
 				double [] eventRY = new double [1];
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tracker.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tracker.java
index 5b244d8..b60b4af 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tracker.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tracker.java
@@ -485,10 +485,17 @@
 long gtk_key_press_event (long widget, long eventPtr) {
 	long result = super.gtk_key_press_event (widget, eventPtr);
 	if (result != 0) return result;
-	int [] state = new int[1];
-	GDK.gdk_event_get_state(eventPtr, state);
-	int [] keyval = new int[1];
-	GDK.gdk_event_get_keyval(eventPtr, keyval);
+	
+	int [] state = new int [1];
+	int [] keyval = new int [1];
+	if (GTK.GTK4) {
+		state[0] = GDK.gdk_event_get_modifier_state(eventPtr);
+		keyval[0] = GDK.gdk_key_event_get_keyval(eventPtr);
+	} else {
+		GDK.gdk_event_get_state(eventPtr, state);
+		GDK.gdk_event_get_keyval(eventPtr, keyval);
+	}
+
 	int stepSize = ((state[0] & GDK.GDK_CONTROL_MASK) != 0) ? STEPSIZE_SMALL : STEPSIZE_LARGE;
 	int xChange = 0, yChange = 0;
 	switch (keyval[0]) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TrayItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TrayItem.java
index 90557f8..11fda1e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TrayItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TrayItem.java
@@ -276,8 +276,14 @@
 long gtk_button_press_event (long widget, long event) {
 	int eventType = GDK.gdk_event_get_event_type(event);
 	eventType = Control.fixGdkEventTypeValues(eventType);
+
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+	}
+
 	if (eventType == GDK.GDK_3BUTTON_PRESS) return 0;
 	if (eventButton[0] == 3 && eventType == GDK.GDK_BUTTON_PRESS) {
 		sendEvent (SWT.MenuDetect);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
index 59b2c64..4dcc493 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
@@ -2117,16 +2117,29 @@
 long gtk_button_press_event (long widget, long event) {
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
+
 	int eventType = GDK.gdk_event_get_event_type(event);
 	eventType = fixGdkEventTypeValues(eventType);
+
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	int [] eventState = new int [1];
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+		GDK.gdk_event_get_state(event, eventState);
+	}
+
 	double [] eventRX = new double [1];
 	double [] eventRY = new double [1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
-	int [] eventState = new int [1];
-	GDK.gdk_event_get_state(event, eventState);
+
 	long eventGdkResource = gdk_event_get_surface_or_window(event);
 	if (GTK.GTK4) {
 		if (eventGdkResource != gtk_widget_get_surface (handle)) return 0;
@@ -2248,8 +2261,13 @@
 
 @Override
 long gtk_key_press_event (long widget, long event) {
-	int [] key = new int[1];
-	GDK.gdk_event_get_keyval(event, key);
+	int [] key = new int [1];
+	if (GTK.GTK4) {
+		key[0] = GDK.gdk_key_event_get_keyval(event);
+	} else {
+		GDK.gdk_event_get_keyval(event, key);
+	}
+
 	keyPressDefaultSelectionHandler (event, key[0]);
 	return super.gtk_key_press_event (widget, event);
 }
@@ -2297,14 +2315,25 @@
 long gtk_button_release_event (long widget, long event) {
 	double [] eventX = new double [1];
 	double [] eventY = new double [1];
-	GDK.gdk_event_get_coords(event, eventX, eventY);
+	if (GTK.GTK4) {
+		GDK.gdk_event_get_position(event, eventX, eventY);
+	} else {
+		GDK.gdk_event_get_coords(event, eventX, eventY);
+	}
 	int [] eventButton = new int [1];
-	GDK.gdk_event_get_button(event, eventButton);
+	int [] eventState = new int [1];
+	if (GTK.GTK4) {
+		eventButton[0] = GDK.gdk_button_event_get_button(event);
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_button(event, eventButton);
+		GDK.gdk_event_get_state(event, eventState);
+	}
+
 	double [] eventRX = new double [1];
 	double [] eventRY = new double [1];
 	GDK.gdk_event_get_root_coords(event, eventRX, eventRY);
-	int [] eventState = new int [1];
-	GDK.gdk_event_get_state(event, eventState);
+
 	long eventGdkResource = gdk_event_get_surface_or_window(event);
 	if (GTK.GTK4) {
 		if (eventGdkResource != gtk_widget_get_surface (handle)) return 0;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeColumn.java
index ec30bbe..5f62774 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeColumn.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeColumn.java
@@ -352,7 +352,12 @@
 	long eventPtr = GTK.gtk_get_current_event ();
 	if (eventPtr != 0) {
 		int [] eventButton = new int [1];
-		GDK.gdk_event_get_button(eventPtr, eventButton);
+		if (GTK.GTK4) {
+			eventButton[0] = GDK.gdk_button_event_get_button(eventPtr);
+		} else {
+			GDK.gdk_event_get_button(eventPtr, eventButton);
+		}
+
 		int eventType = GDK.gdk_event_get_event_type(eventPtr);
 		eventType = Control.fixGdkEventTypeValues(eventType);
 		int eventTime = GDK.gdk_event_get_time(eventPtr);
@@ -380,10 +385,16 @@
 	switch (eventType) {
 		case GDK.GDK_BUTTON_PRESS: {
 			int [] eventButton = new int [1];
-			GDK.gdk_event_get_button(gdkEvent, eventButton);
+			if (GTK.GTK4) {
+				eventButton[0] = GDK.gdk_button_event_get_button(gdkEvent);
+			} else {
+				GDK.gdk_event_get_button(gdkEvent, eventButton);
+			}
+
 			double [] eventRX = new double [1];
 			double [] eventRY = new double [1];
 			GDK.gdk_event_get_root_coords(gdkEvent, eventRX, eventRY);
+
 			if (eventButton[0] == 3) {
 				parent.showMenu ((int) eventRX[0], (int) eventRY[0]);
 			}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java
index ea39d1a..076f64f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java
@@ -1456,17 +1456,16 @@
 boolean sendKeyEvent (int type, long event) {
 	int length;
 	long string;
+	int [] keyval = new int [1];
 	if (GTK.GTK4) {
-		long [] eventString = new long [1];
-		GDK.gdk_event_get_string(event, eventString);
-		string = eventString[0];
-		length = (int)OS.g_utf16_strlen (string, -1);
+		keyval[0] = GDK.gdk_key_event_get_keyval(event);
 	} else {
-		GdkEventKey gdkEvent = new GdkEventKey ();
-		OS.memmove(gdkEvent, event, GdkEventKey.sizeof);
-		length = gdkEvent.length;
-		string = gdkEvent.string;
+		GDK.gdk_event_get_keyval(event, keyval);
 	}
+
+	string = GDK.gdk_keyval_name(keyval[0]);
+	length = (int)OS.g_utf16_strlen (string, -1);
+
 	if (string == 0 || OS.g_utf16_strlen (string, length) <= 1) {
 		Event javaEvent = new Event ();
 		javaEvent.time = GDK.gdk_event_get_time(event);
@@ -1501,7 +1500,11 @@
 				case GDK.GDK_KEY_PRESS:
 				case GDK.GDK_KEY_RELEASE:
 					int [] eventState = new int[1];
-					GDK.gdk_event_get_state(ptr, eventState);
+					if (GTK.GTK4) {
+						eventState[0] = GDK.gdk_event_get_modifier_state(event);
+					} else {
+						GDK.gdk_event_get_state(event, eventState);
+					}
 					state = eventState[0];
 					break;
 				default:
@@ -1566,15 +1569,25 @@
 			case GDK.GDK_BUTTON_PRESS:
 			case GDK.GDK_2BUTTON_PRESS:
 			case GDK.GDK_BUTTON_RELEASE: {
+
 				int [] eventButton = new int [1];
-				GDK.gdk_event_get_button(ptr, eventButton);
+				if (GTK.GTK4) {
+					eventButton[0] = GDK.gdk_button_event_get_button(ptr);
+				} else {
+					GDK.gdk_event_get_button(ptr, eventButton);
+				}
+
 				setButtonState(event, eventButton [0]);
 			}
 			//$FALL-THROUGH$
 			case GDK.GDK_KEY_PRESS:
 			case GDK.GDK_KEY_RELEASE: {
-				int [] state = new int [1];
-				GDK.gdk_event_get_state (ptr, state);
+				int [] state = new int[1];
+				if (GTK.GTK4) {
+					state[0] = GDK.gdk_event_get_modifier_state(ptr);
+				} else {
+					GDK.gdk_event_get_state(ptr, state);
+				}
 				setInputState (event, state [0]);
 				break;
 			}
@@ -1740,26 +1753,28 @@
 boolean setKeyState (Event javaEvent, long event) {
 	long string;
 	int length;
-	int [] eventKeyval = new int[1];
 	int group;
-	GDK.gdk_event_get_keyval(event, eventKeyval);
-	int [] eventState = new int[1];
-	GDK.gdk_event_get_state(event, eventState);
+	int [] eventKeyval = new int [1];
+	int [] eventState = new int [1];
 	if (GTK.GTK4) {
-		long [] eventString = new long [1];
-		GDK.gdk_event_get_string(event, eventString);
-		string = eventString[0];
-		length = (int)OS.g_utf16_strlen (string, -1);
-		int [] eventGroup = new int [1];
-		GDK.gdk_event_get_key_group(event, eventGroup);
-		group = eventGroup[0];
+		eventKeyval[0] = GDK.gdk_key_event_get_keyval(event);
+		eventState[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_keyval(event, eventKeyval);
+		GDK.gdk_event_get_state(event, eventState);
+	}
+
+	if (GTK.GTK4) {
+		group = GDK.gdk_key_event_get_layout(event);
 	} else {
 		GdkEventKey gdkEvent = new GdkEventKey ();
 		OS.memmove(gdkEvent, event, GdkEventKey.sizeof);
-		length = gdkEvent.length;
-		string = gdkEvent.string;
 		group = gdkEvent.group;
 	}
+
+	string = GDK.gdk_keyval_name(eventKeyval[0]);
+	length = (int)OS.g_utf16_strlen (string, -1);
+
 	if (string != 0 && OS.g_utf16_strlen (string, length) > 1) return false;
 	boolean isNull = false;
 	javaEvent.keyCode = Display.translateKey (eventKeyval[0]);
@@ -1806,7 +1821,11 @@
 
 void setLocationState (Event event, long eventPtr) {
 	int [] eventKeyval = new int[1];
-	GDK.gdk_event_get_keyval(eventPtr, eventKeyval);
+	if (GTK.GTK4) {
+		eventKeyval[0] = GDK.gdk_key_event_get_keyval(eventPtr);
+	} else {
+		GDK.gdk_event_get_keyval(eventPtr, eventKeyval);
+	}
 	switch (eventKeyval[0]) {
 		case GDK.GDK_Alt_L:
 		case GDK.GDK_Shift_L:
@@ -1944,7 +1963,7 @@
 void gdk_event_free (long event) {
 	if (event == 0) return;
 	if (GTK.GTK4) {
-		OS.g_object_unref(event);
+		GDK.gdk_event_unref(event);
 	} else {
 		GDK.gdk_event_free(event);
 	}
@@ -1988,8 +2007,12 @@
  *        OS.GDK_SHIFT_MASK / OS.GDK_CONTROL_MASK / OS.GDK_MOD1_MASK etc..
  */
 int gdk_event_get_state (long event) {
-	int [] state = new int [1];
-	GDK.gdk_event_get_state (event, state);
+	int [] state = new int[1];
+	if (GTK.GTK4) {
+		state[0] = GDK.gdk_event_get_modifier_state(event);
+	} else {
+		GDK.gdk_event_get_state(event, state);
+	}
 	return state[0];
 }