diff --git a/Dorkbox-Util/src/dorkbox/util/jna/linux/AppIndicator.java b/Dorkbox-Util/src/dorkbox/util/jna/linux/AppIndicator.java deleted file mode 100644 index 9e22239..0000000 --- a/Dorkbox-Util/src/dorkbox/util/jna/linux/AppIndicator.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.jna.linux; - -import com.sun.jna.Library; -import com.sun.jna.Pointer; -import com.sun.jna.Structure; -import dorkbox.util.Keep; -import dorkbox.util.jna.linux.Gobject.GObjectStruct; - -import java.util.Arrays; -import java.util.List; - -/* bindings for libappindicator */ -public -interface AppIndicator extends Library { - // effing retarded. There are DIFFERENT versions, of which they all share the same basic compatibility (of the methods that - // we use), however -- we cannot just LOAD via the 'base-name', we actually have to try each one. There are bash commands that - // will tell us the linked library name, however - I'd rather not run bash commands to determine this. This is so hacky it makes me - // sick. - - AppIndicator INSTANCE = AppIndicatorQuery.get(); - - /** Necessary to provide warnings, because libappindicator3 is a piece of shit. */ - boolean IS_VERSION_3 = AppIndicatorQuery.isVersion3; - - int CATEGORY_APPLICATION_STATUS = 0; - int CATEGORY_COMMUNICATIONS = 1; - int CATEGORY_SYSTEM_SERVICES = 2; - int CATEGORY_HARDWARE = 3; - int CATEGORY_OTHER = 4; - - int STATUS_PASSIVE = 0; - int STATUS_ACTIVE = 1; - int STATUS_ATTENTION = 2; - - - @Keep - class AppIndicatorInstanceStruct extends Structure { - public GObjectStruct parent; - public Pointer priv; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("parent", "priv"); - } - } - - // Note: AppIndicators DO NOT support tooltips, as per mark shuttleworth. Rather stupid IMHO. - // See: https://bugs.launchpad.net/indicator-application/+bug/527458/comments/12 - - AppIndicatorInstanceStruct app_indicator_new(String id, String icon_name, int category); - - void app_indicator_set_status(AppIndicatorInstanceStruct self, int status); - void app_indicator_set_menu(AppIndicatorInstanceStruct self, Pointer menu); - void app_indicator_set_icon(AppIndicatorInstanceStruct self, String icon_name); -} diff --git a/Dorkbox-Util/src/dorkbox/util/jna/linux/AppIndicatorQuery.java b/Dorkbox-Util/src/dorkbox/util/jna/linux/AppIndicatorQuery.java deleted file mode 100644 index e3d93b9..0000000 --- a/Dorkbox-Util/src/dorkbox/util/jna/linux/AppIndicatorQuery.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dorkbox.util.jna.linux; - -import com.sun.jna.Native; - -/** - * Helper for AppIndicator, because it is absolutely mindboggling how those whom maintain the standard, can't agree to what that standard - * library naming convention or features set is. We just try until we find one that work, and are able to map the symbols we need. - */ -class AppIndicatorQuery { - - /** - * must call get() before accessing this! Only "AppIndicator" interface should access this! - */ - static volatile boolean isVersion3 = false; - - /** - * Is AppIndicator loaded yet? - */ - static volatile boolean isLoaded = false; - - - public static - AppIndicator get() { - Object library; - - // NOTE: GtkSupport uses this info to figure out WHAT VERSION OF GTK to use: appindiactor1 -> GTk2, appindicator3 -> GTK3. - - if (GtkSupport.FORCE_GTK2) { - // try loading appindicator1 first, maybe it's there? - - try { - library = Native.loadLibrary("appindicator1", AppIndicator.class); - if (library != null) { - return (AppIndicator) library; - } - } catch (Throwable ignored) { - } - } - - // start with base version - try { - library = Native.loadLibrary("appindicator", AppIndicator.class); - if (library != null) { - String s = library.toString(); - if (s.indexOf("appindicator3") > 0) { - isVersion3 = true; - } - - isLoaded = true; - return (AppIndicator) library; - } - } catch (Throwable ignored) { - } - - // whoops. Symbolic links are bugged out. Look manually for it... - - try { - library = Native.loadLibrary("appindicator1", AppIndicator.class); - if (library != null) { - return (AppIndicator) library; - } - } catch (Throwable ignored) { - } - - // now check all others. super hacky way to do this. - for (int i = 10; i >= 0; i--) { - try { - library = Native.loadLibrary("appindicator" + i, AppIndicator.class); - } catch (Throwable ignored) { - library = null; - } - - if (library != null) { - String s = library.toString(); - // version 3 WILL NOT work with icons in the menu. This allows us to show a warning (in the System tray initialization) - if (i == 3 || s.indexOf("appindicator3") > 0) { - isVersion3 = true; - } - return (AppIndicator) library; - } - } - - // another type. who knows... - try { - library = Native.loadLibrary("appindicator-gtk", AppIndicator.class); - if (library != null) { - return (AppIndicator) library; - } - } catch (Throwable ignored) { - } - - // this is HORRID. such a PITA - try { - library = Native.loadLibrary("appindicator-gtk3", AppIndicator.class); - if (library != null) { - return (AppIndicator) library; - } - } catch (Throwable ignored) { - } - - throw new RuntimeException("We apologize for this, but we are unable to determine the appIndicator library is in use, if " + - "or even if it is in use... Please create an issue for this and include your OS type and configuration."); - } -} diff --git a/Dorkbox-Util/src/dorkbox/util/jna/linux/Gobject.java b/Dorkbox-Util/src/dorkbox/util/jna/linux/Gobject.java deleted file mode 100644 index f5d3228..0000000 --- a/Dorkbox-Util/src/dorkbox/util/jna/linux/Gobject.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.jna.linux; - -import com.sun.jna.*; -import dorkbox.util.Keep; -import dorkbox.util.jna.linux.Gtk.GdkEventButton; - -import java.util.Arrays; -import java.util.List; - -public -interface Gobject extends Library { - Gobject INSTANCE = (Gobject) Native.loadLibrary("gobject-2.0", Gobject.class); - - @Keep - class GTypeClassStruct extends Structure { - public - class ByValue extends GTypeClassStruct implements Structure.ByValue {} - - - public - class ByReference extends GTypeClassStruct implements Structure.ByReference {} - - - public NativeLong g_type; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("g_type"); - } - } - - - @Keep - class GTypeInstanceStruct extends Structure { - public - class ByValue extends GTypeInstanceStruct implements Structure.ByValue {} - - - public - class ByReference extends GTypeInstanceStruct implements Structure.ByReference {} - - - public Pointer g_class; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("g_class"); - } - } - - - @Keep - class GObjectStruct extends Structure { - public - class ByValue extends GObjectStruct implements Structure.ByValue {} - - - public - class ByReference extends GObjectStruct implements Structure.ByReference {} - - - public GTypeInstanceStruct g_type_instance; - public int ref_count; - public Pointer qdata; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("g_type_instance", "ref_count", "qdata"); - } - } - - - @Keep - class GObjectClassStruct extends Structure { - public - class ByValue extends GObjectClassStruct implements Structure.ByValue {} - - - public - class ByReference extends GObjectClassStruct implements Structure.ByReference {} - - - public GTypeClassStruct g_type_class; - public Pointer construct_properties; - public Pointer constructor; - public Pointer set_property; - public Pointer get_property; - public Pointer dispose; - public Pointer finalize; - public Pointer dispatch_properties_changed; - public Pointer notify; - public Pointer constructed; - public NativeLong flags; - public Pointer dummy1; - public Pointer dummy2; - public Pointer dummy3; - public Pointer dummy4; - public Pointer dummy5; - public Pointer dummy6; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("g_type_class", "construct_properties", "constructor", "set_property", "get_property", "dispose", - "finalize", "dispatch_properties_changed", "notify", "constructed", "flags", "dummy1", "dummy2", "dummy3", - "dummy4", "dummy5", "dummy6"); - } - } - - - @Keep - interface GCallback extends Callback { - /** - * @return Gtk.TRUE if we handled this event - */ - int callback(Pointer instance, Pointer data); - } - - - @Keep - interface GEventCallback extends Callback { - void callback(Pointer instance, GdkEventButton event); - } - - - @Keep - class xyPointer extends Structure { - public int value; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("value"); - } - } - - - @Keep - interface GPositionCallback extends Callback { - void callback(Pointer menu, xyPointer x, xyPointer y, Pointer push_in_bool, Pointer user_data); - } - - - - void g_free(Pointer object); - void g_object_ref(Pointer object); - void g_object_unref(Pointer object); - void g_object_ref_sink(Pointer object); - - NativeLong g_signal_connect_data(Pointer instance, String detailed_signal, Callback c_handler, Pointer data, Pointer destroy_data, - int connect_flags); - - void g_signal_handler_disconnect(Pointer instance, NativeLong longAddress); - - Pointer g_markup_printf_escaped(String pattern, String inputString); -} diff --git a/Dorkbox-Util/src/dorkbox/util/jna/linux/Gtk.java b/Dorkbox-Util/src/dorkbox/util/jna/linux/Gtk.java deleted file mode 100644 index 52a53d6..0000000 --- a/Dorkbox-Util/src/dorkbox/util/jna/linux/Gtk.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.jna.linux; - -import com.sun.jna.Function; -import com.sun.jna.Library; -import com.sun.jna.Pointer; -import com.sun.jna.Structure; -import dorkbox.util.Keep; - -import java.util.Arrays; -import java.util.List; - -public -interface Gtk extends Library { - - // objdump -T /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0 | grep gtk - // objdump -T /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 | grep gtk - Gtk INSTANCE = GtkSupport.get(); - Function gtk_status_icon_position_menu = GtkSupport.gtk_status_icon_position_menu; - - int FALSE = 0; - int TRUE = 1; - - - @Keep - class GdkEventButton extends Structure { - public int type; - public Pointer window; - public int send_event; - public int time; - public double x; - public double y; - public Pointer axes; - public int state; - public int button; - public Pointer device; - public double x_root; - public double y_root; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("type", "window", "send_event", "time", "x", "y", "axes", "state", "button", "device", "x_root", "y_root"); - } - } - - boolean gtk_init_check(int argc, String[] argv); - - /** - * Runs the main loop until gtk_main_quit() is called. You can nest calls to gtk_main(). In that case gtk_main_quit() will make the - * innermost invocation of the main loop return. - */ - void gtk_main(); - - - /** sks for the current nesting level of the main loop. Useful to determine (at startup) if GTK is already runnign */ - int gtk_main_level(); - - /** - * Makes the innermost invocation of the main loop return when it regains control. ONLY CALL FROM THE GtkSupport class, UNLESS you know - * what you're doing! - */ - void gtk_main_quit(); - - void gdk_threads_init(); - - // tricky business. This should only be in the dispatch thread - void gdk_threads_enter(); - void gdk_threads_leave(); - - Pointer gtk_menu_new(); - - Pointer gtk_menu_item_new(); - - Pointer gtk_menu_item_new_with_label(String label); - - // to create a menu entry WITH an icon. - Pointer gtk_image_new_from_file(String iconPath); - - - Pointer gtk_image_menu_item_new_with_label(String label); - - void gtk_image_menu_item_set_image(Pointer image_menu_item, Pointer image); - - void gtk_image_menu_item_set_always_show_image(Pointer menu_item, int forceShow); - - Pointer gtk_bin_get_child(Pointer parent); - - void gtk_label_set_text(Pointer label, String text); - - void gtk_label_set_markup(Pointer label, Pointer markup); - - void gtk_label_set_use_markup(Pointer label, int gboolean); - - Pointer gtk_status_icon_new(); - - void gtk_status_icon_set_from_file(Pointer widget, String lablel); - - void gtk_status_icon_set_visible(Pointer widget, boolean visible); - - // app indicators don't support this, and we cater to the lowest common denominator -// void gtk_status_icon_set_tooltip(Pointer widget, String tooltipText); - - void gtk_status_icon_set_title(Pointer widget, String titleText); - - void gtk_status_icon_set_name(Pointer widget, String name); - - void gtk_menu_popup(Pointer menu, Pointer widget, Pointer bla, Function func, Pointer data, int button, int time); - - void gtk_menu_item_set_label(Pointer menu_item, String label); - - void gtk_menu_shell_append(Pointer menu_shell, Pointer child); - - void gtk_menu_shell_deactivate(Pointer menu_shell, Pointer child); - - void gtk_widget_set_sensitive(Pointer widget, int sensitive); - - void gtk_container_remove(Pointer menu, Pointer subItem); - - void gtk_widget_show(Pointer widget); - - void gtk_widget_show_all(Pointer widget); - - void gtk_widget_destroy(Pointer widget); -} - diff --git a/Dorkbox-Util/src/dorkbox/util/jna/linux/GtkSupport.java b/Dorkbox-Util/src/dorkbox/util/jna/linux/GtkSupport.java deleted file mode 100644 index 53063e7..0000000 --- a/Dorkbox-Util/src/dorkbox/util/jna/linux/GtkSupport.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.jna.linux; - -import com.sun.jna.Function; -import com.sun.jna.Native; -import dorkbox.util.Property; - -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.CountDownLatch; - -public -class GtkSupport { - // RE: SWT - // https://developer.gnome.org/glib/stable/glib-Deprecated-Thread-APIs.html#g-thread-init - // Since version >= 2.24, threads can only init once. Multiple calls do nothing, and we can nest gtk_main() - // in a nested loop. - - private static volatile boolean started = false; - private static final ArrayBlockingQueue dispatchEvents = new ArrayBlockingQueue(256); - private static volatile Thread gtkDispatchThread; - - @Property - /** Forces the system to always choose GTK2 (even when GTK3 might be available). JavaFX uses GTK2! */ - public static boolean FORCE_GTK2 = false; - - @Property - /** - * Forces the system to enter into JavaFX compatibility mode, where it will use GTK2 AND will not start/stop the GTK main loop. - * This is only necessary if autodetection fails - */ - public static boolean JAVAFX_COMPATIBILITY_MODE = false; - - /** - * must call get() before accessing this! Only "Gtk" interface should access this! - */ - static volatile Function gtk_status_icon_position_menu = null; - - public static volatile boolean isGtk2 = false; - - private static volatile boolean alreadyRunningGTK = false; - - /** - * Helper for GTK, because we could have v3 or v2. - * - * Observations: JavaFX uses GTK2, and we can't load GTK3 if GTK2 symbols are loaded - */ - @SuppressWarnings("Duplicates") - public static - Gtk get() { - Gtk library; - - boolean shouldUseGtk2 = GtkSupport.FORCE_GTK2 || JAVAFX_COMPATIBILITY_MODE; - alreadyRunningGTK = JAVAFX_COMPATIBILITY_MODE; - - - // for more info on JavaFX: https://docs.oracle.com/javafx/2/system_requirements_2-2-3/jfxpub-system_requirements_2-2-3.htm - // from the page: JavaFX 2.2.3 for Linux requires gtk2 2.18+. - - // in some cases, we ALWAYS want to try GTK2 first - if (shouldUseGtk2) { - try { - gtk_status_icon_position_menu = Function.getFunction("gtk-x11-2.0", "gtk_status_icon_position_menu"); - library = (Gtk) Native.loadLibrary("gtk-x11-2.0", Gtk.class); - if (library != null) { - isGtk2 = true; - - // when running inside of JavaFX, this will be '1'. All other times this should be '0' - // when it's '1', it means that someone else has stared GTK -- so we DO NOT NEED TO. - alreadyRunningGTK |= library.gtk_main_level() != 0; - return library; - } - } catch (Throwable ignored) { - } - } - - if (AppIndicatorQuery.isLoaded) { - if (AppIndicatorQuery.isVersion3) { - // appindicator3 requires GTK3 - try { - gtk_status_icon_position_menu = Function.getFunction("libgtk-3.so.0", "gtk_status_icon_position_menu"); - library = (Gtk) Native.loadLibrary("libgtk-3.so.0", Gtk.class); - if (library != null) { - // when running inside of JavaFX, this will be '1'. All other times this should be '0' - // when it's '1', it means that someone else has stared GTK -- so we DO NOT NEED TO. - alreadyRunningGTK |= library.gtk_main_level() != 0; - return library; - } - } catch (Throwable ignored) { - } - } else { - // appindicator1 requires GTK2 - try { - gtk_status_icon_position_menu = Function.getFunction("gtk-x11-2.0", "gtk_status_icon_position_menu"); - library = (Gtk) Native.loadLibrary("gtk-x11-2.0", Gtk.class); - if (library != null) { - isGtk2 = true; - - // when running inside of JavaFX, this will be '1'. All other times this should be '0' - // when it's '1', it means that someone else has stared GTK -- so we DO NOT NEED TO. - alreadyRunningGTK |= library.gtk_main_level() != 0; - return library; - } - } catch (Throwable ignored) { - } - } - } - - // now for the defaults... - - // start with version 3 - try { - gtk_status_icon_position_menu = Function.getFunction("libgtk-3.so.0", "gtk_status_icon_position_menu"); - library = (Gtk) Native.loadLibrary("libgtk-3.so.0", Gtk.class); - if (library != null) { - // when running inside of JavaFX, this will be '1'. All other times this should be '0' - // when it's '1', it means that someone else has stared GTK -- so we DO NOT NEED TO. - alreadyRunningGTK |= library.gtk_main_level() != 0; - return library; - } - } catch (Throwable ignored) { - } - - // now version 2 - try { - gtk_status_icon_position_menu = Function.getFunction("gtk-x11-2.0", "gtk_status_icon_position_menu"); - library = (Gtk) Native.loadLibrary("gtk-x11-2.0", Gtk.class); - if (library != null) { - isGtk2 = true; - - // when running inside of JavaFX, this will be '1'. All other times this should be '0' - // when it's '1', it means that someone else has stared GTK -- so we DO NOT NEED TO. - alreadyRunningGTK |= library.gtk_main_level() != 0; - return library; - } - } catch (Throwable ignored) { - } - - throw new RuntimeException("We apologize for this, but we are unable to determine the GTK library is in use, if " + - "or even if it is in use... Please create an issue for this and include your OS type and configuration."); - } - - public static - void startGui() { - // only permit one startup per JVM instance - if (!started) { - started = true; - - // GTK specifies that we ONLY run from a single thread. This guarantees that. - gtkDispatchThread = new Thread() { - @Override - public - void run() { - final Gtk gtk = Gtk.INSTANCE; - while (started) { - try { - final Runnable take = dispatchEvents.take(); - - gtk.gdk_threads_enter(); - take.run(); - gtk.gdk_threads_leave(); - - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - }; - gtkDispatchThread.setName("GTK Event Loop"); - gtkDispatchThread.start(); - - - // startup the GTK GUI event loop. There can be multiple/nested loops. - - // If JavaFX/SWT is used, this is UNNECESSARY - if (!alreadyRunningGTK) { - // only necessary if we are the only GTK instance running... - final CountDownLatch blockUntilStarted = new CountDownLatch(1); - Thread gtkUpdateThread = new Thread() { - @Override - public - void run() { - Gtk gtk = Gtk.INSTANCE; - - // prep for the event loop. - gtk.gdk_threads_init(); - gtk.gdk_threads_enter(); - - gtk.gtk_init_check(0, null); - - // notify our main thread to continue - blockUntilStarted.countDown(); - - // blocks unit quit - gtk.gtk_main(); - - gtk.gdk_threads_leave(); - } - }; - gtkUpdateThread.setName("GTK Event Loop (Native)"); - gtkUpdateThread.start(); - - try { - // we CANNOT continue until the GTK thread has started! - blockUntilStarted.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - } - - /** - * Best practices for GTK, is to call EVERYTHING for it on a SINGLE THREAD. This accomplishes that. - */ - public static - void dispatch(Runnable runnable) { - try { - dispatchEvents.put(runnable); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - public static - void shutdownGui() { - // If JavaFX/SWT is used, this is UNNECESSARY (an will break SWT/JavaFX shutdown) - if (!alreadyRunningGTK) { - Gtk.INSTANCE.gtk_main_quit(); - } - - started = false; - - // put it in a NEW dispatch event (so that we cleanup AFTER this one is finished) - dispatch(new Runnable() { - @Override - public - void run() { - new Thread(new Runnable() { - @Override - public - void run() { - // this should happen in a new thread - gtkDispatchThread.interrupt(); - } - }).run(); - } - }); - } -}