Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java
32287 views
1
/*
2
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.awt;
27
28
import java.awt.AWTPermission;
29
import java.awt.DisplayMode;
30
import java.awt.GraphicsEnvironment;
31
import java.awt.GraphicsDevice;
32
import java.awt.GraphicsConfiguration;
33
import java.awt.Rectangle;
34
import java.awt.Window;
35
import java.security.AccessController;
36
import java.security.PrivilegedAction;
37
import java.util.ArrayList;
38
import java.util.HashSet;
39
import java.util.HashMap;
40
41
import sun.java2d.opengl.GLXGraphicsConfig;
42
import sun.java2d.xr.XRGraphicsConfig;
43
import sun.java2d.loops.SurfaceType;
44
45
import sun.misc.ThreadGroupUtils;
46
47
/**
48
* This is an implementation of a GraphicsDevice object for a single
49
* X11 screen.
50
*
51
* @see GraphicsEnvironment
52
* @see GraphicsConfiguration
53
*/
54
public class X11GraphicsDevice
55
extends GraphicsDevice
56
implements DisplayChangedListener
57
{
58
int screen;
59
HashMap x11ProxyKeyMap = new HashMap();
60
61
private static AWTPermission fullScreenExclusivePermission;
62
private static Boolean xrandrExtSupported;
63
private final Object configLock = new Object();
64
private SunDisplayChanger topLevels = new SunDisplayChanger();
65
private DisplayMode origDisplayMode;
66
private boolean shutdownHookRegistered;
67
68
public X11GraphicsDevice(int screennum) {
69
this.screen = screennum;
70
}
71
72
/*
73
* Initialize JNI field and method IDs for fields that may be
74
* accessed from C.
75
*/
76
private static native void initIDs();
77
78
static {
79
if (!GraphicsEnvironment.isHeadless()) {
80
initIDs();
81
}
82
}
83
84
/**
85
* Returns the X11 screen of the device.
86
*/
87
public int getScreen() {
88
return screen;
89
}
90
91
public Object getProxyKeyFor(SurfaceType st) {
92
synchronized (x11ProxyKeyMap) {
93
Object o = x11ProxyKeyMap.get(st);
94
if (o == null) {
95
o = new Object();
96
x11ProxyKeyMap.put(st, o);
97
}
98
return o;
99
}
100
}
101
102
/**
103
* Returns the X11 Display of this device.
104
* This method is also in MDrawingSurfaceInfo but need it here
105
* to be able to allow a GraphicsConfigTemplate to get the Display.
106
*/
107
public native long getDisplay();
108
109
/**
110
* Returns the type of the graphics device.
111
* @see #TYPE_RASTER_SCREEN
112
* @see #TYPE_PRINTER
113
* @see #TYPE_IMAGE_BUFFER
114
*/
115
public int getType() {
116
return TYPE_RASTER_SCREEN;
117
}
118
119
/**
120
* Returns the identification string associated with this graphics
121
* device.
122
*/
123
public String getIDstring() {
124
return ":0."+screen;
125
}
126
127
128
GraphicsConfiguration[] configs;
129
GraphicsConfiguration defaultConfig;
130
HashSet doubleBufferVisuals;
131
132
/**
133
* Returns all of the graphics
134
* configurations associated with this graphics device.
135
*/
136
public GraphicsConfiguration[] getConfigurations() {
137
if (configs == null) {
138
synchronized (configLock) {
139
makeConfigurations();
140
}
141
}
142
return configs.clone();
143
}
144
145
private void makeConfigurations() {
146
if (configs == null) {
147
int i = 1; // Index 0 is always the default config
148
int num = getNumConfigs(screen);
149
GraphicsConfiguration[] ret = new GraphicsConfiguration[num];
150
if (defaultConfig == null) {
151
ret [0] = getDefaultConfiguration();
152
}
153
else {
154
ret [0] = defaultConfig;
155
}
156
157
boolean glxSupported = X11GraphicsEnvironment.isGLXAvailable();
158
boolean xrenderSupported = X11GraphicsEnvironment.isXRenderAvailable();
159
160
boolean dbeSupported = isDBESupported();
161
if (dbeSupported && doubleBufferVisuals == null) {
162
doubleBufferVisuals = new HashSet();
163
getDoubleBufferVisuals(screen);
164
}
165
for ( ; i < num; i++) {
166
int visNum = getConfigVisualId(i, screen);
167
int depth = getConfigDepth (i, screen);
168
if (glxSupported) {
169
ret[i] = GLXGraphicsConfig.getConfig(this, visNum);
170
}
171
if (ret[i] == null) {
172
boolean doubleBuffer =
173
(dbeSupported &&
174
doubleBufferVisuals.contains(Integer.valueOf(visNum)));
175
176
if (xrenderSupported) {
177
ret[i] = XRGraphicsConfig.getConfig(this, visNum, depth, getConfigColormap(i, screen),
178
doubleBuffer);
179
} else {
180
ret[i] = X11GraphicsConfig.getConfig(this, visNum, depth,
181
getConfigColormap(i, screen),
182
doubleBuffer);
183
}
184
}
185
}
186
configs = ret;
187
}
188
}
189
190
/*
191
* Returns the number of X11 visuals representable as an
192
* X11GraphicsConfig object.
193
*/
194
public native int getNumConfigs(int screen);
195
196
/*
197
* Returns the visualid for the given index of graphics configurations.
198
*/
199
public native int getConfigVisualId (int index, int screen);
200
/*
201
* Returns the depth for the given index of graphics configurations.
202
*/
203
public native int getConfigDepth (int index, int screen);
204
205
/*
206
* Returns the colormap for the given index of graphics configurations.
207
*/
208
public native int getConfigColormap (int index, int screen);
209
210
211
// Whether or not double-buffering extension is supported
212
public static native boolean isDBESupported();
213
// Callback for adding a new double buffer visual into our set
214
private void addDoubleBufferVisual(int visNum) {
215
doubleBufferVisuals.add(Integer.valueOf(visNum));
216
}
217
// Enumerates all visuals that support double buffering
218
private native void getDoubleBufferVisuals(int screen);
219
220
/**
221
* Returns the default graphics configuration
222
* associated with this graphics device.
223
*/
224
public GraphicsConfiguration getDefaultConfiguration() {
225
if (defaultConfig == null) {
226
synchronized (configLock) {
227
makeDefaultConfiguration();
228
}
229
}
230
return defaultConfig;
231
}
232
233
private void makeDefaultConfiguration() {
234
if (defaultConfig == null) {
235
int visNum = getConfigVisualId(0, screen);
236
if (X11GraphicsEnvironment.isGLXAvailable()) {
237
defaultConfig = GLXGraphicsConfig.getConfig(this, visNum);
238
if (X11GraphicsEnvironment.isGLXVerbose()) {
239
if (defaultConfig != null) {
240
System.out.print("OpenGL pipeline enabled");
241
} else {
242
System.out.print("Could not enable OpenGL pipeline");
243
}
244
System.out.println(" for default config on screen " +
245
screen);
246
}
247
}
248
if (defaultConfig == null) {
249
int depth = getConfigDepth(0, screen);
250
boolean doubleBuffer = false;
251
if (isDBESupported() && doubleBufferVisuals == null) {
252
doubleBufferVisuals = new HashSet();
253
getDoubleBufferVisuals(screen);
254
doubleBuffer =
255
doubleBufferVisuals.contains(Integer.valueOf(visNum));
256
}
257
258
if (X11GraphicsEnvironment.isXRenderAvailable()) {
259
if (X11GraphicsEnvironment.isXRenderVerbose()) {
260
System.out.println("XRender pipeline enabled");
261
}
262
defaultConfig = XRGraphicsConfig.getConfig(this, visNum,
263
depth, getConfigColormap(0, screen),
264
doubleBuffer);
265
} else {
266
defaultConfig = X11GraphicsConfig.getConfig(this, visNum,
267
depth, getConfigColormap(0, screen),
268
doubleBuffer);
269
}
270
}
271
}
272
}
273
274
private static native void enterFullScreenExclusive(long window);
275
private static native void exitFullScreenExclusive(long window);
276
private static native boolean initXrandrExtension();
277
private static native DisplayMode getCurrentDisplayMode(int screen);
278
private static native void enumDisplayModes(int screen,
279
ArrayList<DisplayMode> modes);
280
private static native void configDisplayMode(int screen,
281
int width, int height,
282
int displayMode);
283
private static native void resetNativeData(int screen);
284
285
/**
286
* Returns true only if:
287
* - the Xrandr extension is present
288
* - the necessary Xrandr functions were loaded successfully
289
*/
290
private static synchronized boolean isXrandrExtensionSupported() {
291
if (xrandrExtSupported == null) {
292
xrandrExtSupported =
293
Boolean.valueOf(initXrandrExtension());
294
}
295
return xrandrExtSupported.booleanValue();
296
}
297
298
@Override
299
public boolean isFullScreenSupported() {
300
boolean fsAvailable = isXrandrExtensionSupported();
301
if (fsAvailable) {
302
SecurityManager security = System.getSecurityManager();
303
if (security != null) {
304
if (fullScreenExclusivePermission == null) {
305
fullScreenExclusivePermission =
306
new AWTPermission("fullScreenExclusive");
307
}
308
try {
309
security.checkPermission(fullScreenExclusivePermission);
310
} catch (SecurityException e) {
311
return false;
312
}
313
}
314
}
315
return fsAvailable;
316
}
317
318
@Override
319
public boolean isDisplayChangeSupported() {
320
return (isFullScreenSupported()
321
&& (getFullScreenWindow() != null)
322
&& !((X11GraphicsEnvironment) GraphicsEnvironment
323
.getLocalGraphicsEnvironment()).runningXinerama());
324
}
325
326
private static void enterFullScreenExclusive(Window w) {
327
X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
328
if (peer != null) {
329
enterFullScreenExclusive(peer.getWindow());
330
peer.setFullScreenExclusiveModeState(true);
331
}
332
}
333
334
private static void exitFullScreenExclusive(Window w) {
335
X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
336
if (peer != null) {
337
peer.setFullScreenExclusiveModeState(false);
338
exitFullScreenExclusive(peer.getWindow());
339
}
340
}
341
342
@Override
343
public synchronized void setFullScreenWindow(Window w) {
344
Window old = getFullScreenWindow();
345
if (w == old) {
346
return;
347
}
348
349
boolean fsSupported = isFullScreenSupported();
350
if (fsSupported && old != null) {
351
// enter windowed mode (and restore original display mode)
352
exitFullScreenExclusive(old);
353
if (isDisplayChangeSupported()) {
354
setDisplayMode(origDisplayMode);
355
}
356
}
357
358
super.setFullScreenWindow(w);
359
360
if (fsSupported && w != null) {
361
// save original display mode
362
if (origDisplayMode == null) {
363
origDisplayMode = getDisplayMode();
364
}
365
366
// enter fullscreen mode
367
enterFullScreenExclusive(w);
368
}
369
}
370
371
private DisplayMode getDefaultDisplayMode() {
372
GraphicsConfiguration gc = getDefaultConfiguration();
373
Rectangle r = gc.getBounds();
374
return new DisplayMode(r.width, r.height,
375
DisplayMode.BIT_DEPTH_MULTI,
376
DisplayMode.REFRESH_RATE_UNKNOWN);
377
}
378
379
@Override
380
public synchronized DisplayMode getDisplayMode() {
381
if (isFullScreenSupported()) {
382
DisplayMode mode = getCurrentDisplayMode(screen);
383
if (mode == null) {
384
mode = getDefaultDisplayMode();
385
}
386
return mode;
387
} else {
388
if (origDisplayMode == null) {
389
origDisplayMode = getDefaultDisplayMode();
390
}
391
return origDisplayMode;
392
}
393
}
394
395
@Override
396
public synchronized DisplayMode[] getDisplayModes() {
397
if (!isFullScreenSupported()) {
398
return super.getDisplayModes();
399
}
400
ArrayList<DisplayMode> modes = new ArrayList<DisplayMode>();
401
enumDisplayModes(screen, modes);
402
DisplayMode[] retArray = new DisplayMode[modes.size()];
403
return modes.toArray(retArray);
404
}
405
406
@Override
407
public synchronized void setDisplayMode(DisplayMode dm) {
408
if (!isDisplayChangeSupported()) {
409
super.setDisplayMode(dm);
410
return;
411
}
412
Window w = getFullScreenWindow();
413
if (w == null) {
414
throw new IllegalStateException("Must be in fullscreen mode " +
415
"in order to set display mode");
416
}
417
if (getDisplayMode().equals(dm)) {
418
return;
419
}
420
if (dm == null ||
421
(dm = getMatchingDisplayMode(dm)) == null)
422
{
423
throw new IllegalArgumentException("Invalid display mode");
424
}
425
426
if (!shutdownHookRegistered) {
427
// register a shutdown hook so that we return to the
428
// original DisplayMode when the VM exits (if the application
429
// is already in the original DisplayMode at that time, this
430
// hook will have no effect)
431
shutdownHookRegistered = true;
432
PrivilegedAction<Void> a = () -> {
433
ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
434
Runnable r = () -> {
435
Window old = getFullScreenWindow();
436
if (old != null) {
437
exitFullScreenExclusive(old);
438
if (isDisplayChangeSupported()) {
439
setDisplayMode(origDisplayMode);
440
}
441
}
442
};
443
Thread t = new Thread(rootTG, r,"Display-Change-Shutdown-Thread-"+screen);
444
t.setContextClassLoader(null);
445
Runtime.getRuntime().addShutdownHook(t);
446
return null;
447
};
448
AccessController.doPrivileged(a);
449
}
450
451
// switch to the new DisplayMode
452
configDisplayMode(screen,
453
dm.getWidth(), dm.getHeight(),
454
dm.getRefreshRate());
455
456
// update bounds of the fullscreen window
457
w.setBounds(0, 0, dm.getWidth(), dm.getHeight());
458
459
// configDisplayMode() is synchronous, so the display change will be
460
// complete by the time we get here (and it is therefore safe to call
461
// displayChanged() now)
462
((X11GraphicsEnvironment)
463
GraphicsEnvironment.getLocalGraphicsEnvironment()).displayChanged();
464
}
465
466
private synchronized DisplayMode getMatchingDisplayMode(DisplayMode dm) {
467
if (!isDisplayChangeSupported()) {
468
return null;
469
}
470
DisplayMode[] modes = getDisplayModes();
471
for (DisplayMode mode : modes) {
472
if (dm.equals(mode) ||
473
(dm.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN &&
474
dm.getWidth() == mode.getWidth() &&
475
dm.getHeight() == mode.getHeight() &&
476
dm.getBitDepth() == mode.getBitDepth()))
477
{
478
return mode;
479
}
480
}
481
return null;
482
}
483
484
/**
485
* From the DisplayChangedListener interface; called from
486
* X11GraphicsEnvironment when the display mode has been changed.
487
*/
488
public synchronized void displayChanged() {
489
// On X11 the visuals do not change, and therefore we don't need
490
// to reset the defaultConfig, config, doubleBufferVisuals,
491
// neither do we need to reset the native data.
492
493
// pass on to all top-level windows on this screen
494
topLevels.notifyListeners();
495
}
496
497
/**
498
* From the DisplayChangedListener interface; devices do not need
499
* to react to this event.
500
*/
501
public void paletteChanged() {
502
}
503
504
/**
505
* Add a DisplayChangeListener to be notified when the display settings
506
* are changed. Typically, only top-level containers need to be added
507
* to X11GraphicsDevice.
508
*/
509
public void addDisplayChangedListener(DisplayChangedListener client) {
510
topLevels.add(client);
511
}
512
513
/**
514
* Remove a DisplayChangeListener from this X11GraphicsDevice.
515
*/
516
public void removeDisplayChangedListener(DisplayChangedListener client) {
517
topLevels.remove(client);
518
}
519
520
public String toString() {
521
return ("X11GraphicsDevice[screen="+screen+"]");
522
}
523
}
524
525