From 9c50514cc131ee6b40985a3a1e3e63f72e01dae8 Mon Sep 17 00:00:00 2001 From: nathan Date: Sun, 3 Sep 2017 14:49:28 +0200 Subject: [PATCH] Added major,minor,micro version info to GtkCheck. Added extra methods. Moved GTK3 version specific methods to method loader, so GTK will always load the gtk3 library, even if the version is not high enough --- src/dorkbox/util/jna/linux/Gtk.java | 9 +++++ src/dorkbox/util/jna/linux/Gtk2.java | 4 +++ src/dorkbox/util/jna/linux/Gtk3.java | 43 ++++++++++++++++++++++- src/dorkbox/util/jna/linux/GtkCheck.java | 43 +++++++++++++++++++++++ src/dorkbox/util/jna/linux/GtkLoader.java | 15 +++++--- 5 files changed, 109 insertions(+), 5 deletions(-) diff --git a/src/dorkbox/util/jna/linux/Gtk.java b/src/dorkbox/util/jna/linux/Gtk.java index 996152d..d8a89aa 100644 --- a/src/dorkbox/util/jna/linux/Gtk.java +++ b/src/dorkbox/util/jna/linux/Gtk.java @@ -38,6 +38,7 @@ interface Gtk { int FALSE = 0; int TRUE = 1; + // use GtkCheck for a safe accessor of these int MAJOR = GtkLoader.MAJOR; int MINOR = GtkLoader.MINOR; int MICRO = GtkLoader.MICRO; @@ -47,6 +48,7 @@ interface Gtk { Gtk Gtk2 = GtkLoader.isGtk2 ? new Gtk2() : new Gtk3(); Gtk3 Gtk3 = GtkLoader.isGtk2 ? null : (Gtk3) Gtk2; + // use GtkCheck for a safe accessor of these boolean isGtk2 = GtkLoader.isGtk2; boolean isGtk3 = GtkLoader.isGtk3; boolean isLoaded = GtkLoader.isLoaded; @@ -393,5 +395,12 @@ interface Gtk { * @since 2.12 */ void gtk_widget_set_tooltip_text(Pointer widget, String text); + + /** + * Gets the default GdkDisplay. This is a convenience function for gdk_display_manager_get_default_display (gdk_display_manager_get()). + * + * @since: 2.2 + */ + Pointer gdk_display_get_default(); } diff --git a/src/dorkbox/util/jna/linux/Gtk2.java b/src/dorkbox/util/jna/linux/Gtk2.java index 4d982f6..766975c 100644 --- a/src/dorkbox/util/jna/linux/Gtk2.java +++ b/src/dorkbox/util/jna/linux/Gtk2.java @@ -198,4 +198,8 @@ class Gtk2 implements Gtk { @Override public native void gtk_widget_set_tooltip_text(final Pointer widget, final String text); + + @Override + public native + Pointer gdk_display_get_default(); } diff --git a/src/dorkbox/util/jna/linux/Gtk3.java b/src/dorkbox/util/jna/linux/Gtk3.java index 06a46ca..60d56dc 100644 --- a/src/dorkbox/util/jna/linux/Gtk3.java +++ b/src/dorkbox/util/jna/linux/Gtk3.java @@ -16,6 +16,7 @@ package dorkbox.util.jna.linux; import com.sun.jna.Function; +import com.sun.jna.NativeLibrary; import com.sun.jna.Pointer; import dorkbox.util.jna.linux.structs.GtkStyle; @@ -25,13 +26,33 @@ import dorkbox.util.jna.linux.structs.GtkStyle; *

* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md */ +@SuppressWarnings("WeakerAccess") public class Gtk3 implements Gtk { - static Function gdk_window_get_scale_factor = null; + private static Function gdk_window_get_scale_factor = null; + private static Function gtk_show_uri_on_window = null; // objdump -T /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 | grep gtk // objdump -T /usr/local/lib/libgtk-3.so.0 | grep gtk + /** + * Loads version specific methods + * + * @param library + */ + static + void loadMethods(final NativeLibrary library) { + // Abusing static fields this way is not proper, but it gets the job done nicely. + + if (GtkCheck.gtkIsGreaterOrEqual(3, 10, 0)) { + gdk_window_get_scale_factor = library.getFunction("gdk_window_get_scale_factor"); + } + + if (GtkCheck.gtkIsGreaterOrEqual(3, 22, 0)) { + gtk_show_uri_on_window = library.getFunction("gtk_show_uri_on_window"); + } + } + /** * Retrieves the minimum and natural size of a widget, taking into account the widget’s preference for height-for-width management. *

@@ -73,6 +94,22 @@ class Gtk3 implements Gtk { } } + /** + * @return TRUE on success, FALSE on error + * + * @since: 3.22 + */ + public + boolean gtk_show_uri_on_window(final Pointer parent, final String uri, final int timestamp, final Pointer error) { + if (gtk_show_uri_on_window != null) { + return (Boolean) gtk_show_uri_on_window.invoke(Boolean.class, new Object[] {parent, uri, timestamp, error}); + } + else { + return false; + } + } + + /////////////////////////// //// GTK2 methods /////////////////////////// @@ -258,4 +295,8 @@ class Gtk3 implements Gtk { @Override public native void gtk_widget_set_tooltip_text(final Pointer widget, final String text); + + @Override + public native + Pointer gdk_display_get_default(); } diff --git a/src/dorkbox/util/jna/linux/GtkCheck.java b/src/dorkbox/util/jna/linux/GtkCheck.java index bfbe4ad..458e04f 100644 --- a/src/dorkbox/util/jna/linux/GtkCheck.java +++ b/src/dorkbox/util/jna/linux/GtkCheck.java @@ -45,6 +45,47 @@ class GtkCheck { */ public static volatile boolean isGtkLoaded = false; + + /** If GTK is loaded, this is the GTK MAJOR version */ + public static volatile int MAJOR = 0; + + /** If GTK is loaded, this is the GTK MINOR version */ + public static volatile int MINOR = 0; + + /** If GTK is loaded, this is the GTK MICRO version */ + public static volatile int MICRO = 0; + + + /** + * @return true if the currently loaded GTK version is greater to or equal to the passed-in major.minor.mico + */ + public static + boolean gtkIsGreaterOrEqual(final int major, final int minor, final int micro) { + if (MAJOR > major) { + return true; + } + if (MAJOR < major) { + return false; + } + + if (MINOR > minor) { + return true; + } + if (MINOR < minor) { + return false; + } + + if (MICRO > micro) { + return true; + } + if (MICRO < micro) { + return false; + } + + // same exact version + return true; + } + /** * This method is agnostic w.r.t. how GTK is loaded, which can be manually loaded or loaded via JavaFX/SWT/Swing. * @@ -80,4 +121,6 @@ class GtkCheck { // now check if swing has loaded GTK from the Look and Feel return SwingUtil.getLoadedGtkVersion(); } + + } diff --git a/src/dorkbox/util/jna/linux/GtkLoader.java b/src/dorkbox/util/jna/linux/GtkLoader.java index 0dd7aa5..15f8418 100644 --- a/src/dorkbox/util/jna/linux/GtkLoader.java +++ b/src/dorkbox/util/jna/linux/GtkLoader.java @@ -49,6 +49,7 @@ class GtkLoader { static Function gtk_status_icon_position_menu = null; + // use GtkCheck for a safe accessor of these static int MAJOR; static int MINOR; static int MICRO; @@ -139,10 +140,6 @@ class GtkLoader { library = null; library = JnaHelper.register(gtk3LibName, Gtk3.class); - if (major >= 3 && minor >= 10) { - // Abusing static fields this way is not proper, but it gets the job done nicely. - Gtk3.gdk_window_get_scale_factor = library.getFunction("gdk_window_get_scale_factor"); - } gtk_status_icon_position_menu = library.getFunction( "gtk_status_icon_position_menu"); Function gtk_main_level = library.getFunction("gtk_main_level"); @@ -229,6 +226,16 @@ class GtkLoader { GtkCheck.isGtk3 = isGtk3; GtkCheck.isGtkLoaded = isLoaded; + GtkCheck.MAJOR = MAJOR; + GtkCheck.MINOR = MINOR; + GtkCheck.MICRO = MICRO; + + + // load any GTK version specific methods + if (isGtk3) { + Gtk3.loadMethods(library); + } + if (shouldLoadGtk) { if (!_isLoaded) { throw new RuntimeException("We apologize for this, but we are unable to determine the GTK library is in use, " +