From 99b80c807ae25156e72440a7b55a9c0efaca1fe4 Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 15 Jun 2017 14:11:00 +0200 Subject: [PATCH] Added major/minor/micro version info to GTK class. Added/removed methods . Code polish --- src/dorkbox/systemTray/jna/linux/Gtk.java | 121 +++++++++++++++------ src/dorkbox/systemTray/jna/linux/Gtk3.java | 22 ++++ 2 files changed, 108 insertions(+), 35 deletions(-) diff --git a/src/dorkbox/systemTray/jna/linux/Gtk.java b/src/dorkbox/systemTray/jna/linux/Gtk.java index 434fcde..0d79a01 100644 --- a/src/dorkbox/systemTray/jna/linux/Gtk.java +++ b/src/dorkbox/systemTray/jna/linux/Gtk.java @@ -24,6 +24,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import com.sun.jna.Function; +import com.sun.jna.NativeLibrary; import com.sun.jna.Pointer; import dorkbox.systemTray.Entry; @@ -38,14 +39,13 @@ import dorkbox.util.jna.JnaHelper; *

* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md */ -@SuppressWarnings({"Duplicates", "SameParameterValue", "DanglingJavadoc", "DeprecatedIsStillUsed"}) +@SuppressWarnings({"Duplicates", "SameParameterValue", "DeprecatedIsStillUsed"}) public class Gtk { // For funsies to look at, SyncThing did a LOT of work on compatibility in python (unfortunate for us, but interesting). // https://github.com/syncthing/syncthing-gtk/blob/b7a3bc00e3bb6d62365ae62b5395370f3dcc7f55/syncthing_gtk/statusicon.py - @SuppressWarnings("unused") public static class State { public static final int NORMAL = 0x0; // normal state. public static final int ACTIVE = 0x1; // pressed-in or activated; e.g. buttons while the mouse button is held down. @@ -76,18 +76,21 @@ class Gtk { // objdump -T /usr/local/lib/libgtk-3.so.0 | grep gtk - @SuppressWarnings("WeakerAccess") public static final int FALSE = 0; public static final int TRUE = 1; private static final boolean alreadyRunningGTK; + // when debugging the EDT, we need a longer timeout. private static final boolean debugEDT = true; + // timeout is in seconds private static final int TIMEOUT = debugEDT ? 10000000 : 2; + // have to save these in a field to prevent GC on the objects (since they go out-of-scope from java) - @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") private static final LinkedList gtkCallbacks = new LinkedList(); + public static Function gtk_status_icon_position_menu = null; + // This is required because the EDT needs to have it's own value for this boolean, that is a different value than the main thread private static ThreadLocal isDispatch = new ThreadLocal() { @Override @@ -96,11 +99,16 @@ class Gtk { return false; } }; + private static volatile boolean started = false; - @SuppressWarnings("FieldCanBeLocal") + private static Thread gtkUpdateThread = null; - /** + public static final int MAJOR; + public static final int MINOR; + public static final int MICRO; + + /* * We can have GTK v3 or v2. * * Observations: @@ -112,6 +120,9 @@ class Gtk { boolean _isGtk2 = false; boolean _isLoaded = false; boolean _alreadyRunningGTK = false; + int major = 0; + int minor = 0; + int micro = 0; boolean shouldLoadGtk = !(OS.isWindows() || OS.isMacOsX()); if (!shouldLoadGtk) { @@ -124,6 +135,7 @@ class Gtk { if (SystemTray.DEBUG) { logger.debug("Not loading GTK for Swing or AWT"); } + shouldLoadGtk = false; _isLoaded = true; } @@ -134,7 +146,7 @@ class Gtk { if (!_isLoaded && shouldUseGtk2) { try { - JnaHelper.register(gtk2LibName, Gtk.class); + NativeLibrary library = JnaHelper.register(gtk2LibName, Gtk.class); gtk_status_icon_position_menu = Function.getFunction(gtk2LibName, "gtk_status_icon_position_menu"); _isGtk2 = true; @@ -143,6 +155,10 @@ class Gtk { _alreadyRunningGTK = gtk_main_level() != 0; _isLoaded = true; + major = library.getGlobalVariableAddress("gtk_major_version").getInt(0); + minor = library.getGlobalVariableAddress("gtk_minor_version").getInt(0); + micro = library.getGlobalVariableAddress("gtk_micro_version").getInt(0); + if (SystemTray.DEBUG) { logger.debug("GTK: {}", gtk2LibName); } @@ -171,6 +187,10 @@ class Gtk { _alreadyRunningGTK = gtk_main_level() != 0; _isLoaded = true; + major = Gtk3.gtk_get_major_version(); + minor = Gtk3.gtk_get_minor_version(); + micro = Gtk3.gtk_get_micro_version(); + if (SystemTray.DEBUG) { logger.debug("GTK: {}", gtk3LibName); } @@ -184,7 +204,7 @@ class Gtk { // now version 2 if (!_isLoaded) { try { - JnaHelper.register(gtk2LibName, Gtk.class); + NativeLibrary library = JnaHelper.register(gtk2LibName, Gtk.class); gtk_status_icon_position_menu = Function.getFunction(gtk2LibName, "gtk_status_icon_position_menu"); _isGtk2 = true; @@ -193,6 +213,10 @@ class Gtk { _alreadyRunningGTK = gtk_main_level() != 0; _isLoaded = true; + major = library.getGlobalVariableAddress("gtk_major_version").getInt(0); + minor = library.getGlobalVariableAddress("gtk_minor_version").getInt(0); + micro = library.getGlobalVariableAddress("gtk_micro_version").getInt(0); + if (SystemTray.DEBUG) { logger.debug("GTK: {}", gtk2LibName); } @@ -217,6 +241,10 @@ class Gtk { alreadyRunningGTK = _alreadyRunningGTK; isGtk2 = _isGtk2; isGtk3 = !_isGtk2; + + MAJOR = major; + MINOR = minor; + MICRO = micro; } else { isLoaded = false; @@ -224,11 +252,22 @@ class Gtk { alreadyRunningGTK = false; isGtk2 = false; isGtk3 = false; + + MAJOR = 0; + MINOR = 0; + MICRO = 0; } - if (shouldLoadGtk && !_isLoaded) { - throw new RuntimeException("We apologize for this, but we are unable to determine the GTK library is in use, " + - "or even if it is in use... Please create an issue for this and include your OS type and configuration."); + if (shouldLoadGtk) { + // now we output what version of GTK we have loaded. + if (SystemTray.DEBUG) { + SystemTray.logger.debug("GTK Version: " + MAJOR + "." + MINOR + "." + MICRO); + } + + if (!_isLoaded) { + throw new RuntimeException("We apologize for this, but we are unable to determine the GTK library is in use, " + + "or even if it is in use... Please create an issue for this and include your OS type and configuration."); + } } } @@ -568,7 +607,6 @@ class Gtk { public static native Pointer gtk_menu_new(); - /** * Sets or replaces the menu item’s submenu, or removes it when a NULL submenu is passed. */ @@ -646,16 +684,37 @@ class Gtk { Pointer gtk_status_icon_new(); /** - * Gets the size in pixels that is available for the image. Stock icons and named icons adapt their size automatically if the size of - * the notification area changes. For other storage types, the size-changed signal can be used to react to size changes. - * Note that the returned size is only meaningful while the status icon is embedded (see gtk_status_icon_is_embedded()). - *

- * gtk_status_icon_get_size has been deprecated since version 3.14 and should not be used in newly-written code. - * Use notifications + * Obtains the root window (parent all other windows are inside) for the default display and screen. + * + * @return the default root window */ - @Deprecated public static native - int gtk_status_icon_get_size(Pointer status_icon); + Pointer gdk_get_default_root_window(); + + /** + * Gets the default screen for the default display. (See gdk_display_get_default()). + * + * @return a GdkScreen, or NULL if there is no default display. + * + * @since 2.2 + */ + public static native + Pointer gdk_screen_get_default(); + + /** + * Gets the resolution for font handling on the screen; see gdk_screen_set_resolution() for full details. + * + * IE: + * + * The resolution for font handling on the screen. This is a scale factor between points specified in a PangoFontDescription and + * cairo units. The default value is 96, meaning that a 10 point font will be 13 units high. (10 * 96. / 72. = 13.3). + * + * @return the current resolution, or -1 if no resolution has been set. + * + * @since Since: 2.10 + */ + public static native + double gdk_screen_get_resolution(Pointer screen); /** * Makes status_icon display the file filename . See gtk_status_icon_new_from_file() for details. @@ -678,7 +737,6 @@ class Gtk { void gtk_status_icon_set_visible(Pointer widget, boolean visible); - @Deprecated /** * Sets text as the contents of the tooltip. * This function will take care of setting “has-tooltip” to TRUE and of the default handler for the “query-tooltip” signal. @@ -687,7 +745,9 @@ class Gtk { * * gtk_status_icon_set_tooltip_text has been deprecated since version 3.14 and should not be used in newly-written code. * Use notifications - */ public static native + */ + @Deprecated + public static native void gtk_status_icon_set_tooltip_text(Pointer widget, String tooltipText); /** @@ -780,13 +840,12 @@ class Gtk { void gtk_widget_destroy(Pointer widget); /** - * Gets the GtkSettings object for the default GDK screen, creating it if necessary. See gtk_settings_get_for_screen(). - *

- * If there is no default screen, then returns NULL. + * Gets the GtkSettings object for screen , creating it if necessary. + * + * @since 2.2 */ public static native - Pointer gtk_settings_get_default(); - + Pointer gtk_settings_get_for_screen(Pointer screen); /** * Simply an accessor function that returns @widget->style. @@ -801,14 +860,6 @@ class Gtk { public static native Pointer gtk_rc_get_style(Pointer widget); - /** - * Creates a toplevel container widget that is used to retrieve snapshots of widgets without showing them on the screen. - * - * @since 2.20 - */ - public static native - Pointer gtk_offscreen_window_new(); - /** * Looks up color_name in the style’s logical color mappings, filling in color and returning TRUE if found, otherwise returning * FALSE. Do not cache the found mapping, because it depends on the GtkStyle and might change when a theme switch occurs. diff --git a/src/dorkbox/systemTray/jna/linux/Gtk3.java b/src/dorkbox/systemTray/jna/linux/Gtk3.java index 6a67aed..39fe5c8 100644 --- a/src/dorkbox/systemTray/jna/linux/Gtk3.java +++ b/src/dorkbox/systemTray/jna/linux/Gtk3.java @@ -27,6 +27,11 @@ class Gtk3 { // 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 + public static native int gtk_get_major_version(); + public static native int gtk_get_minor_version(); + public static native int gtk_get_micro_version(); + + /** * Loads a theme from the usual theme paths * @@ -83,4 +88,21 @@ class Gtk3 { * @since 3.0 (but not in the documentation...) */ public static native Pointer gtk_widget_get_style_context(Pointer widget); + + /** + * Returns the internal scale factor that maps from window coordinates to the actual device pixels. On traditional systems this is 1, + * but on very high density outputs this can be a higher value (often 2). + * + * A higher value means that drawing is automatically scaled up to a higher resolution, so any code doing drawing will automatically + * look nicer. However, if you are supplying pixel-based data the scale value can be used to determine whether to use a pixel + * resource with higher resolution data. + * + * The scale of a window may change during runtime, if this happens a configure event will be sent to the toplevel window. + * + * @return the scale factor + * + * @since 3.10 + */ + public static native + int gdk_window_get_scale_factor (Pointer window); }