JRE-359 CGraphicsEnvironment.getDefaultScreenDevice() returns null
Moved CG api calls to AppKit thread
diff --git a/src/macosx/classes/sun/awt/CGraphicsEnvironment.java b/src/macosx/classes/sun/awt/CGraphicsEnvironment.java
index 77783d1..78c6454 100644
--- a/src/macosx/classes/sun/awt/CGraphicsEnvironment.java
+++ b/src/macosx/classes/sun/awt/CGraphicsEnvironment.java
@@ -27,8 +27,10 @@
import java.awt.*;
import java.util.*;
+import java.util.concurrent.Callable;
import sun.java2d.*;
+import sun.lwawt.macosx.CThreading;
/**
* This is an implementation of a GraphicsEnvironment object for the default
@@ -128,15 +130,18 @@
* @param displayId CoreGraphics displayId
* @param removed true if displayId was removed, false otherwise.
*/
+ @SuppressWarnings("unused")
void _displayReconfiguration(final int displayId, final boolean removed) {
synchronized (this) {
+ // We don't need to switch to AppKit, we're already there
+ mainDisplayID = getMainDisplayID();
if (removed && devices.containsKey(displayId)) {
final CGraphicsDevice gd = devices.remove(displayId);
- gd.invalidate(getMainDisplayID());
+ gd.invalidate(mainDisplayID);
gd.displayChanged();
}
}
- initDevices();
+ initDevices(mainDisplayID);
}
@Override
@@ -151,30 +156,58 @@
/**
* (Re)create all CGraphicsDevices, reuses a devices if it is possible.
*/
+ private void initDevices(int mainDisplID) {
+ synchronized (this) {
+ mainDisplayID = mainDisplID;
+ createDevices();
+ }
+ displayChanged();
+ }
+
private void initDevices() {
synchronized (this) {
- final Map<Integer, CGraphicsDevice> old = new HashMap<>(devices);
- devices.clear();
-
- mainDisplayID = getMainDisplayID();
// initialization of the graphics device may change
// list of displays on hybrid systems via an activation
// of discrete video.
// So, we initialize the main display first, and then
// retrieve actual list of displays.
- if (!old.containsKey(mainDisplayID)) {
- old.put(mainDisplayID, new CGraphicsDevice(mainDisplayID));
+ final Callable<Integer> command = CGraphicsEnvironment::getMainDisplayID;
+
+ try {
+ mainDisplayID = CThreading.executeOnAppKit(command);
+ } catch (Throwable throwable) {
+ throw new RuntimeException("Could not get main display ID");
}
- for (final int id : getDisplayIDs()) {
- devices.put(id, old.containsKey(id) ? old.get(id)
- : new CGraphicsDevice(id));
- }
+ createDevices();
+
}
displayChanged();
}
+ private void createDevices() {
+ final Map<Integer, CGraphicsDevice> old = new HashMap<>(devices);
+ devices.clear();
+
+ if (!old.containsKey(mainDisplayID)) {
+ old.put(mainDisplayID, new CGraphicsDevice(mainDisplayID));
+ }
+ final Callable<int[]> command = CGraphicsEnvironment::getDisplayIDs;
+
+ int[] displayIDs;
+ try {
+ displayIDs = CThreading.executeOnAppKit(command);
+ } catch (Throwable throwable) {
+ throw new RuntimeException("Could not get main display IDs");
+ }
+
+ for (final int id : displayIDs) {
+ devices.put(id, old.containsKey(id) ? old.get(id)
+ : new CGraphicsDevice(id));
+ }
+ }
+
@Override
public synchronized GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
CGraphicsDevice d = devices.get(mainDisplayID);