Commit 1a16b1ed authored by Emmanuel Bourg's avatar Emmanuel Bourg

New upstream version 11+19

parent 474456e2
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.openjfx</groupId>
<artifactId>javafx</artifactId>
<version>@VERSION@</version>
<packaging>pom</packaging>
<name>openjfx</name>
<description>OpenJFX JavaFX</description>
<properties>
<javafx.version>@VERSION@</javafx.version>
</properties>
<dependencyManagement>
</dependencyManagement>
<profiles>
<profile>
<id>linux</id>
<activation>
<os>
<name>linux</name>
</os>
</activation>
<properties>
<javafx.platform>linux</javafx.platform>
</properties>
</profile>
<profile>
<id>macosx</id>
<activation>
<os>
<name>mac os x</name>
</os>
</activation>
<properties>
<javafx.platform>mac</javafx.platform>
</properties>
</profile>
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<properties>
<javafx.platform>win</javafx.platform>
</properties>
</profile>
<profile>
<id>javafx.platform.custom</id>
<activation>
<property>
<name>javafx.platform</name>
</property>
</activation>
<properties>
<javafx.platform>${javafx.platform}</javafx.platform>
</properties>
</profile>
</profiles>
</project>
......@@ -25,10 +25,20 @@
package com.sun.glass.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.AccessController;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public class NativeLibLoader {
......@@ -36,7 +46,20 @@ public class NativeLibLoader {
public static synchronized void loadLibrary(String libname) {
if (!loaded.contains(libname)) {
loadLibraryInternal(libname);
StackWalker walker = AccessController.doPrivileged((PrivilegedAction<StackWalker>) () ->
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE));
Class caller = walker.getCallerClass();
loadLibraryInternal(libname, null, caller);
loaded.add(libname);
}
}
public static synchronized void loadLibrary(String libname, List<String> dependencies) {
if (!loaded.contains(libname)) {
StackWalker walker = AccessController.doPrivileged((PrivilegedAction<StackWalker>) () ->
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE));
Class caller = walker.getCallerClass();
loadLibraryInternal(libname, dependencies, caller);
loaded.add(libname);
}
}
......@@ -87,7 +110,7 @@ public class NativeLibLoader {
return paths;
}
private static void loadLibraryInternal(String libraryName) {
private static void loadLibraryInternal(String libraryName, List<String> dependencies, Class caller) {
// Look for the library in the same directory as the jar file
// containing this class.
// If that fails, then try System.loadLibrary.
......@@ -130,6 +153,10 @@ public class NativeLibLoader {
+ libraryName + ") succeeded");
}
} catch (UnsatisfiedLinkError ex2) {
// if the library is available in the jar, copy it to cache and load it from there
if (loadLibraryFromResource(libraryName, dependencies, caller)) {
return;
}
//On iOS we link all libraries staticaly. Presence of library
//is recognized by existence of JNI_OnLoad_libraryname() C function.
//If libraryname contains hyphen, it needs to be translated
......@@ -150,6 +177,119 @@ public class NativeLibLoader {
}
}
/**
* If there is a library with the platform-correct name at the
* root of the resources in this jar, use that.
*/
private static boolean loadLibraryFromResource(String libraryName, List<String> dependencies, Class caller) {
return installLibraryFromResource(libraryName, dependencies, caller, true);
}
/**
* If there is a library with the platform-correct name at the
* root of the resources in this jar, install it. If load is true, also load it.
*/
private static boolean installLibraryFromResource(String libraryName, List<String> dependencies, Class caller, boolean load) {
try {
// first preload dependencies
if (dependencies != null) {
for (String dep: dependencies) {
boolean hasdep = installLibraryFromResource(dep, null, caller, false);
}
}
String reallib = "/"+libPrefix+libraryName+libSuffix;
InputStream is = caller.getResourceAsStream(reallib);
if (is != null) {
String fp = cacheLibrary(is, reallib, caller);
if (load) {
System.load(fp);
if (verbose) {
System.err.println("Loaded library " + reallib + " from resource");
}
} else if (verbose) {
System.err.println("Unpacked library " + reallib + " from resource");
}
return true;
}
} catch (Throwable t) {
// we should only be here if the resource exists in the module, but
// for some reasons it can't be loaded.
System.err.println("Loading library " + libraryName + " from resource failed: " + t);
t.printStackTrace();
}
return false;
}
private static String cacheLibrary(InputStream is, String name, Class caller) throws IOException {
String jfxVersion = System.getProperty("javafx.version", "versionless");
String userCache = System.getProperty("user.home") + "/.openjfx/cache/" + jfxVersion;
File cacheDir = new File(userCache);
if (cacheDir.exists()) {
if (!cacheDir.isDirectory()) {
throw new IOException ("Cache exists but is not a directory: "+cacheDir);
}
} else {
if (!cacheDir.mkdirs()) {
throw new IOException ("Can not create cache at "+cacheDir);
}
}
// we have a cache directory. Add the file here
File f = new File(cacheDir, name);
// if it exists, calculate checksum and keep if same as inputstream.
boolean write = true;
if (f.exists()) {
byte[] isHash;
byte[] fileHash;
try {
DigestInputStream dis = new DigestInputStream(is, MessageDigest.getInstance("MD5"));
dis.getMessageDigest().reset();
byte[] buffer = new byte[4096];
while (dis.read(buffer) != -1) { /* empty loop body is intentional */ }
isHash = dis.getMessageDigest().digest();
is.close();
is = caller.getResourceAsStream(name); // mark/reset not supported, we have to reread
}
catch (NoSuchAlgorithmException nsa) {
isHash = new byte[1];
}
fileHash = calculateCheckSum(f);
if (!Arrays.equals(isHash, fileHash)) {
Files.delete(f.toPath());
} else {
// hashes are the same, we already have the file.
write = false;
}
}
if (write) {
Path path = f.toPath();
Files.copy(is, path);
}
String fp = f.getAbsolutePath();
return fp;
}
static byte[] calculateCheckSum(File file) {
try {
// not looking for security, just a checksum. MD5 should be faster than SHA
try (final InputStream stream = new FileInputStream(file);
final DigestInputStream dis = new DigestInputStream(stream, MessageDigest.getInstance("MD5")); ) {
dis.getMessageDigest().reset();
byte[] buffer = new byte[4096];
while (dis.read(buffer) != -1) { /* empty loop body is intentional */ }
return dis.getMessageDigest().digest();
}
} catch (IllegalArgumentException | NoSuchAlgorithmException | IOException | SecurityException e) {
// IOException also covers MalformedURLException
// SecurityException means some untrusted applet
// Fall through...
}
return new byte[0];
}
/**
* Load the native library from the same directory as the jar file
* containing this class.
......@@ -223,4 +363,5 @@ public class NativeLibLoader {
throw (UnsatisfiedLinkError) new UnsatisfiedLinkError().initCause(e);
}
}
}
......@@ -101,8 +101,6 @@ public class JPEGImageLoader extends ImageLoaderImpl {
int outColorSpaceCode, int scaleNum, int scaleDenom);
private native boolean decompressIndirect(long structPointer, boolean reportProgress, byte[] array) throws IOException;
// Uncomment next line for direct ByteBuffers.
//private native ByteBuffer decompressDirect(long structPointer, boolean reportProgress) throws IOException;
static {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
......@@ -232,14 +230,24 @@ public class JPEGImageLoader extends ImageLoaderImpl {
outNumComponents = startDecompression(structPointer,
outColorSpaceCode, width, height);
// Uncomment next line for direct ByteBuffer.
//buffer = decompressDirect(structPointer, listeners != null && !listeners.isEmpty());
// Comment out next three lines to suppress indirect ByteBuffers.
byte[] array = new byte[outWidth*outHeight*outNumComponents];
if (outWidth < 0 || outHeight < 0 || outNumComponents < 0) {
throw new IOException("negative dimension.");
}
if (outWidth > (Integer.MAX_VALUE / outNumComponents)) {
throw new IOException("bad width.");
}
int scanlineStride = outWidth * outNumComponents;
if (scanlineStride > (Integer.MAX_VALUE / outHeight)) {
throw new IOException("bad height.");
}
byte[] array = new byte[scanlineStride*outHeight];
buffer = ByteBuffer.wrap(array);
decompressIndirect(structPointer, listeners != null && !listeners.isEmpty(), buffer.array());
} catch (IOException e) {
throw e;
} catch (Throwable t) {
throw new IOException(t);
} finally {
accessLock.unlock();
dispose();
......
......@@ -200,11 +200,6 @@ public abstract class Toolkit {
return TOOLKIT;
}
// This loading of msvcp140.dll and vcruntime140.dll (VS2017) is required on Windows platforms
if (PlatformUtil.isWindows()) {
loadMSWindowsLibraries();
}
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// Get the javafx.version and javafx.runtime.version from a preconstructed
// java class, VersionInfo, created at build time.
......@@ -212,6 +207,11 @@ public abstract class Toolkit {
return null;
});
// This loading of msvcp140.dll and vcruntime140.dll (VS2017) is required on Windows platforms
if (PlatformUtil.isWindows()) {
loadMSWindowsLibraries();
}
boolean userSpecifiedToolkit = true;
// Check a system property to see if there is a specific toolkit to use.
......
......@@ -886,10 +886,12 @@ class WindowStage extends GlassStage {
@Override
protected void setPlatformEnabled(boolean enabled) {
super.setPlatformEnabled(enabled);
platformWindow.setEnabled(enabled);
if (platformWindow != null) {
platformWindow.setEnabled(enabled);
}
if (enabled) {
// Check if window is really enabled - to handle nested case
if (platformWindow.isEnabled()) {
if (platformWindow != null && platformWindow.isEnabled()) {
requestToFront();
}
} else {
......
/*
* Copyright (c) 2010, 2016, 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
......@@ -44,6 +44,8 @@ import java.util.List;
import com.sun.javafx.PlatformUtil;
import java.security.AccessController;
import java.security.PrivilegedAction;
import com.sun.glass.utils.NativeLibLoader;
import com.sun.prism.impl.PrismSettings;
/**
* Some basic utilities which need to be in java (for shifting operations or
......@@ -961,4 +963,19 @@ public class Utils {
return new String(dst, 0, dstIndex);
}
public static synchronized void loadNativeSwingLibrary() {
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
String libName = "prism_common";
if (PrismSettings.verbose) {
System.out.println("Loading Prism common native library ...");
}
NativeLibLoader.loadLibrary(libName);
if (PrismSettings.verbose) {
System.out.println("\tsucceeded.");
}
return null;
});
}
}
......@@ -1597,6 +1597,8 @@ JNIEXPORT jint JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_startDecompr
return cinfo->output_components;
}
#define SAFE_TO_MULT(a, b) (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
JNIEXPORT jboolean JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_decompressIndirect
(JNIEnv *env, jobject this, jlong ptr, jboolean report_progress, jbyteArray barray) {
imageIODataPtr data = (imageIODataPtr) jlong_to_ptr(ptr);
......@@ -1607,6 +1609,17 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_decompre
JSAMPROW scanline_ptr = (JSAMPROW) malloc(bytes_per_row * sizeof (JSAMPLE));
int offset = 0;
if (!SAFE_TO_MULT(cinfo->output_width, cinfo->output_components) ||
!SAFE_TO_MULT(bytes_per_row, cinfo->output_height) ||
((*env)->GetArrayLength(env, barray) <
(bytes_per_row * cinfo->output_height)))
{
ThrowByName(env,
"java/lang/OutOfMemoryError",
"Reading JPEG Stream");
return JNI_FALSE;
}
if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
ThrowByName(env,
"java/io/IOException",
......@@ -1691,69 +1704,3 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_decompre
RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
return JNI_TRUE;
}
/*
* Remove "if 0" to compile direct ByteBuffer call.
*/
#if 0
JNIEXPORT jobject JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_decompressDirect
(JNIEnv *env, jobject this, jlong ptr, jboolean report_progress) {
imageIODataPtr data = (imageIODataPtr) jlong_to_ptr(ptr);
j_decompress_ptr cinfo = (j_decompress_ptr) data->jpegObj;
struct jpeg_source_mgr *src = cinfo->src;
sun_jpeg_error_ptr jerr;
int bytes_per_row = cinfo->output_width * cinfo->output_components;
JSAMPROW scanline_ptr;
int len = cinfo->output_height * bytes_per_row * sizeof (JSAMPLE);
JSAMPROW buf = malloc(len);
int offset = 0;
int num_scanlines;
if (buf == NULL) {
ThrowByName(env,
"java/lang/OutOfMemoryError",
"Reading JPEG Stream");
return NULL;
}
/* Establish the setjmp return context for sun_jpeg_error_exit to use. */
jerr = (sun_jpeg_error_ptr) cinfo->err;
if (setjmp(jerr->setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error
while reading. */
RELEASE_ARRAYS(env, data, src->next_input_byte);
if (!(*env)->ExceptionOccurred(env)) {
char buffer[JMSG_LENGTH_MAX];
(*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
buffer);
ThrowByName(env, "java/io/IOException", buffer);
}
if (buf != NULL) {
free(buf);
}
return NULL;
}
while (cinfo->output_scanline < cinfo->output_height) {
if (report_progress == JNI_TRUE) {
(*env)->CallVoidMethod(env, this,
JPEGImageLoader_updateImageProgressID,
cinfo->output_scanline);
}
scanline_ptr = (JSAMPROW) (buf + offset);
num_scanlines = jpeg_read_scanlines(cinfo, &scanline_ptr, 1);
if (num_scanlines == 1) {
offset += bytes_per_row;
}
}
if (report_progress == JNI_TRUE) {
(*env)->CallVoidMethod(env, this,
JPEGImageLoader_updateImageProgressID,
cinfo->output_height);
}
jpeg_finish_decompress(cinfo);
return (*env)->NewDirectByteBuffer(env, buf, len);
}
#endif
/*
* Copyright (c) 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
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <jni.h>
/*
* Class com_sun_javafx_embed_swing_newimpl_SwingNodeInteropN
* Method: overrideNativeWindowHandle
* Signature (Ljava/lang/Class;JLjava/lang/Runnable)Ljdk.swing.interop.LightweightFrameWrapper;
*/
JNIEXPORT void JNICALL
Java_com_sun_javafx_embed_swing_newimpl_SwingNodeInteropN_overrideNativeWindowHandle(
JNIEnv *env, jclass cls, jclass lwFrameClass, jobject lwFrame, jlong id, jobject runnable) {
jmethodID cons;
if (lwFrameClass == NULL) {
return;
}
cons = (*env)->GetMethodID(env, lwFrameClass, "overrideNativeWindowHandle",
"(JLjava/lang/Runnable;)V");
if (cons == NULL || (*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallVoidMethod(env, lwFrame, cons, id, runnable);
}
......@@ -36,6 +36,7 @@ import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
......@@ -104,15 +105,35 @@ public class NativeMediaManager {
*/
try {
AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
ArrayList<String> dependencies = new ArrayList<>();
if (HostUtils.isWindows() || HostUtils.isMacOSX()) {
NativeLibLoader.loadLibrary("glib-lite");
}
if (!HostUtils.isLinux() && !HostUtils.isIOS()) {
NativeLibLoader.loadLibrary("gstreamer-lite");
} else {
dependencies.add("gstreamer-lite");
}
NativeLibLoader.loadLibrary("jfxmedia");
if (HostUtils.isLinux()) {
dependencies.add("fxplugins");
dependencies.add("avplugin");
dependencies.add("avplugin-54");
dependencies.add("avplugin-56");
dependencies.add("avplugin-57");
dependencies.add("avplugin-ffmpeg-56");
dependencies.add("avplugin-ffmpeg-57");
}
if (HostUtils.isMacOSX()) {
dependencies.add("fxplugins");
dependencies.add("glib-lite");
dependencies.add("jfxmedia_avf");
}
if (HostUtils.isWindows()) {
dependencies.add("fxplugins");
dependencies.add("glib-lite");
}
NativeLibLoader.loadLibrary("jfxmedia", dependencies);
return null;
});
} catch (PrivilegedActionException pae) {
......
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 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
......@@ -23,21 +23,15 @@
* questions.
*/
package javafx.embed.swing;
package com.sun.javafx.embed.swing;
import com.sun.javafx.embed.EmbeddedSceneDSInterface;
import com.sun.javafx.tk.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import javafx.scene.input.TransferMode;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import javafx.scene.input.Clipboard;
import javafx.scene.input.DataFormat;
......@@ -46,7 +40,7 @@ import javafx.scene.input.DataFormat;
* The data can be populated either from AWT Transferable
* or from FX Clipboard.
*/
class CachingTransferable implements Transferable {
public class CachingTransferable implements Transferable {
@Override
public Object getTransferData(final DataFlavor flavor) throws UnsupportedEncodingException
......@@ -70,7 +64,7 @@ class CachingTransferable implements Transferable {
private Map<String, Object> mimeType2Data = Collections.EMPTY_MAP;
void updateData(Transferable t, boolean fetchData) {
public void updateData(Transferable t, boolean fetchData) {
final Map<String, DataFlavor> mimeType2DataFlavor =
DataFlavorUtils.adjustSwingDataFlavors(
t.getTransferDataFlavors());
......@@ -106,7 +100,7 @@ class CachingTransferable implements Transferable {
}
}
void updateData(Clipboard cb, boolean fetchData) {
public void updateData(Clipboard cb, boolean fetchData) {
mimeType2Data = new HashMap<>();
for (DataFormat f : cb.getContentTypes()) {
mimeType2Data.put(DataFlavorUtils.getMimeType(f),
......
/*
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 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
......@@ -23,31 +23,26 @@
* questions.
*/
package javafx.embed.swing;
import javafx.scene.input.DataFormat;
import java.io.ByteArrayOutputStream;
import java.util.Set;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Collections;
import java.util.ArrayList;
package com.sun.javafx.embed.swing;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javafx.scene.input.DataFormat;
final class DataFlavorUtils {
......
/*
* Copyright (c) 2014, 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
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.