< prev index next >
modules/graphics/src/main/java/com/sun/glass/ui/gtk/GtkApplication.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -34,22 +34,77 @@
import com.sun.glass.ui.Screen;
import com.sun.glass.ui.Size;
import com.sun.glass.ui.Timer;
import com.sun.glass.ui.View;
import com.sun.glass.ui.Window;
+import com.sun.javafx.util.Logging;
+import com.sun.glass.utils.NativeLibLoader;
+import sun.util.logging.PlatformLogger;
import java.io.File;
+import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
+import java.lang.annotation.Native;
-final class GtkApplication extends Application implements InvokeLaterDispatcher.InvokeLaterSubmitter {
+final class GtkApplication extends Application implements
+ InvokeLaterDispatcher.InvokeLaterSubmitter {
+ private static final String SWT_INTERNAL_CLASS =
+ "org.eclipse.swt.internal.gtk.OS";
+ private static final int forcedGtkVersion;
static {
+ //check for SWT-GTK lib presence
+ Class<?> OS = AccessController.
+ doPrivileged((PrivilegedAction<Class<?>>) () -> {
+ try {
+ return Class.forName(SWT_INTERNAL_CLASS, true,
+ ClassLoader.getSystemClassLoader());
+ } catch (Exception e) {}
+ try {
+ return Class.forName(SWT_INTERNAL_CLASS, true,
+ Thread.currentThread().getContextClassLoader());
+ } catch (Exception e) {}
+ return null;
+ });
+ if (OS != null) {
+ PlatformLogger logger = Logging.getJavaFXLogger();
+ logger.fine("SWT-GTK library found. Try to obtain GTK version.");
+ Method method = AccessController.
+ doPrivileged((PrivilegedAction<Method>) () -> {
+ try {
+ return OS.getMethod("gtk_major_version");
+ } catch (Exception e) {
+ return null;
+ }
+ });
+ int ver = 0;
+ if (method != null) {
+ try {
+ ver = ((Number)method.invoke(OS)).intValue();
+ } catch (Exception e) {
+ logger.warning("Method gtk_major_version() of " +
+ "the org.eclipse.swt.internal.gtk.OS class " +
+ "returns error. SWT GTK version cannot be detected. " +
+ "GTK3 will be used as default.");
+ ver = 3;
+ }
+ }
+ if (ver < 2 || ver > 3) {
+ logger.warning("SWT-GTK uses unsupported major GTK version "
+ + ver + ". GTK3 will be used as default.");
+ ver = 3;
+ }
+ forcedGtkVersion = ver;
+ } else {
+ forcedGtkVersion = 0;
+ }
+
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
Application.loadNativeLibrary();
return null;
});
}
@@ -59,15 +114,57 @@
public static long visualID = 0;
private final InvokeLaterDispatcher invokeLaterDispatcher;
GtkApplication() {
- // Check whether the Display is valid and throw an exception if not.
- // We use UnsupportedOperationException rather than HeadlessException
- // so as not to introduce a dependency on AWT.
- if (!isDisplayValid()) {
+
+ final int gtkVersion = forcedGtkVersion == 0 ?
+ AccessController.doPrivileged((PrivilegedAction<Integer>) () -> {
+ String v = System.getProperty("jdk.gtk.version","2");
+ int ret = 0;
+ if ("3".equals(v) || v.startsWith("3.")) {
+ ret = 3;
+ } else if ("2".equals(v) || v.startsWith("2.")) {
+ ret = 2;
+ }
+ return ret;
+ }) : forcedGtkVersion;
+
+ boolean gtkVersionVerbose =
+ AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
+ return Boolean.getBoolean("jdk.gtk.verbose");
+
+ });
+
+ int libraryToLoad = _queryLibrary(gtkVersion, gtkVersionVerbose);
+
+ AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+ if (libraryToLoad == QUERY_NO_DISPLAY) {
throw new UnsupportedOperationException("Unable to open DISPLAY");
+ } else if (libraryToLoad == QUERY_USE_CURRENT) {
+ if (gtkVersionVerbose) {
+ System.out.println("Glass GTK library to load is already loaded");
+ }
+ } else if (libraryToLoad == QUERY_LOAD_GTK2) {
+ if (gtkVersionVerbose) {
+ System.out.println("Glass GTK library to load is glassgtk2");
+ }
+ NativeLibLoader.loadLibrary("glassgtk2");
+ } else if (libraryToLoad == QUERY_LOAD_GTK3) {
+ if (gtkVersionVerbose) {
+ System.out.println("Glass GTK library to load is glassgtk3");
+ }
+ NativeLibLoader.loadLibrary("glassgtk3");
+ } else {
+ throw new UnsupportedOperationException("Internal Error");
+ }
+ return null;
+ });
+
+ int version = _initGTK(gtkVersion, gtkVersionVerbose);
+ if (version == -1) {
+ throw new RuntimeException("Error loading GTK libraries");
}
// Embedded in SWT, with shared event thread
boolean isEventThread = AccessController
.doPrivileged((PrivilegedAction<Boolean>) () -> Boolean.getBoolean("javafx.embed.isEventThread"));
@@ -77,13 +174,22 @@
} else {
invokeLaterDispatcher = null;
}
}
- private static boolean isDisplayValid() {
- return _isDisplayValid();
- }
+ @Native private static final int QUERY_ERROR = -2;
+ @Native private static final int QUERY_NO_DISPLAY = -1;
+ @Native private static final int QUERY_USE_CURRENT = 1;
+ @Native private static final int QUERY_LOAD_GTK2 = 2;
+ @Native private static final int QUERY_LOAD_GTK3 = 3;
+ /*
+ * check the system and return an indication of which library to load
+ * return values are the QUERY_ constants
+ */
+ private static native int _queryLibrary(int version, boolean verbose);
+
+ private static native int _initGTK(int version, boolean verbose);
private void initDisplay() {
Map ds = getDeviceDetails();
if (ds != null) {
Object value;
@@ -154,12 +260,10 @@
@Override public boolean shouldUpdateWindow() {
return true;
}
- private static native boolean _isDisplayValid();
-
private native void _terminateLoop();
private native void _init(long eventProc, boolean disableGrab);
private native void _runLoop(Runnable launchable, boolean noErrorTrap);
< prev index next >