Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java
32287 views
1
/*
2
* Copyright (c) 1997, 2010, 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.GraphicsDevice;
30
import java.awt.GraphicsConfiguration;
31
import java.awt.GraphicsEnvironment;
32
import java.awt.DisplayMode;
33
import java.awt.EventQueue;
34
import java.awt.Frame;
35
import java.awt.Rectangle;
36
import java.awt.Window;
37
import java.awt.event.WindowAdapter;
38
import java.awt.event.WindowEvent;
39
import java.awt.event.WindowListener;
40
import java.awt.image.ColorModel;
41
import java.util.ArrayList;
42
import java.util.Vector;
43
import java.awt.peer.WindowPeer;
44
import sun.awt.windows.WWindowPeer;
45
import sun.java2d.opengl.WGLGraphicsConfig;
46
import sun.java2d.windows.WindowsFlags;
47
48
/**
49
* This is an implementation of a GraphicsDevice object for a single
50
* Win32 screen.
51
*
52
* @see GraphicsEnvironment
53
* @see GraphicsConfiguration
54
*/
55
public class Win32GraphicsDevice extends GraphicsDevice implements
56
DisplayChangedListener {
57
int screen;
58
ColorModel dynamicColorModel; // updated with dev changes
59
ColorModel colorModel; // static for device
60
protected GraphicsConfiguration[] configs;
61
protected GraphicsConfiguration defaultConfig;
62
63
private final String idString;
64
protected String descString;
65
// Note that we do not synchronize access to this variable - it doesn't
66
// really matter if a thread does an operation on graphics device which is
67
// about to become invalid (or already become) - we are prepared to deal
68
// with this on the native level.
69
private boolean valid;
70
71
// keep track of top-level windows on this display
72
private SunDisplayChanger topLevels = new SunDisplayChanger();
73
// REMIND: we may disable the use of pixel formats for some accelerated
74
// pipelines which are mutually exclusive with opengl, for which
75
// pixel formats were added in the first place
76
protected static boolean pfDisabled;
77
private static AWTPermission fullScreenExclusivePermission;
78
// the original display mode we had before entering the fullscreen
79
// mode
80
private DisplayMode defaultDisplayMode;
81
// activation/deactivation listener for the full-screen window
82
private WindowListener fsWindowListener;
83
84
static {
85
86
// 4455041 - Even when ddraw is disabled, ddraw.dll is loaded when
87
// pixel format calls are made. This causes problems when a Java app
88
// is run as an NT service. To prevent the loading of ddraw.dll
89
// completely, sun.awt.nopixfmt should be set as well. Apps which use
90
// OpenGL w/ Java probably don't want to set this.
91
String nopixfmt = (String)java.security.AccessController.doPrivileged(
92
new sun.security.action.GetPropertyAction("sun.awt.nopixfmt"));
93
pfDisabled = (nopixfmt != null);
94
initIDs();
95
}
96
97
private static native void initIDs();
98
99
native void initDevice(int screen);
100
101
public Win32GraphicsDevice(int screennum) {
102
this.screen = screennum;
103
// we cache the strings because we want toString() and getIDstring
104
// to reflect the original screen number (which may change if the
105
// device is removed)
106
idString = "\\Display"+screen;
107
// REMIND: may be should use class name?
108
descString = "Win32GraphicsDevice[screen=" + screen;
109
valid = true;
110
111
initDevice(screennum);
112
}
113
114
/**
115
* Returns the type of the graphics device.
116
* @see #TYPE_RASTER_SCREEN
117
* @see #TYPE_PRINTER
118
* @see #TYPE_IMAGE_BUFFER
119
*/
120
public int getType() {
121
return TYPE_RASTER_SCREEN;
122
}
123
124
/**
125
* Returns the Win32 screen of the device.
126
*/
127
public int getScreen() {
128
return screen;
129
}
130
131
/**
132
* Returns whether this is a valid devicie. Device can become
133
* invalid as a result of device removal event.
134
*/
135
public boolean isValid() {
136
return valid;
137
}
138
139
/**
140
* Called from native code when the device was removed.
141
*
142
* @param defaultScreen the current default screen
143
*/
144
protected void invalidate(int defaultScreen) {
145
valid = false;
146
screen = defaultScreen;
147
}
148
149
/**
150
* Returns the identification string associated with this graphics
151
* device.
152
*/
153
public String getIDstring() {
154
return idString;
155
}
156
157
158
/**
159
* Returns all of the graphics
160
* configurations associated with this graphics device.
161
*/
162
public GraphicsConfiguration[] getConfigurations() {
163
if (configs==null) {
164
if (WindowsFlags.isOGLEnabled() && isDefaultDevice()) {
165
defaultConfig = getDefaultConfiguration();
166
if (defaultConfig != null) {
167
configs = new GraphicsConfiguration[1];
168
configs[0] = defaultConfig;
169
return configs.clone();
170
}
171
}
172
173
int max = getMaxConfigs(screen);
174
int defaultPixID = getDefaultPixID(screen);
175
Vector v = new Vector( max );
176
if (defaultPixID == 0) {
177
// Workaround for failing GDI calls
178
defaultConfig = Win32GraphicsConfig.getConfig(this,
179
defaultPixID);
180
v.addElement(defaultConfig);
181
}
182
else {
183
for (int i = 1; i <= max; i++) {
184
if (isPixFmtSupported(i, screen)) {
185
if (i == defaultPixID) {
186
defaultConfig = Win32GraphicsConfig.getConfig(
187
this, i);
188
v.addElement(defaultConfig);
189
}
190
else {
191
v.addElement(Win32GraphicsConfig.getConfig(
192
this, i));
193
}
194
}
195
}
196
}
197
configs = new GraphicsConfiguration[v.size()];
198
v.copyInto(configs);
199
}
200
return configs.clone();
201
}
202
203
/**
204
* Returns the maximum number of graphics configurations available, or 1
205
* if PixelFormat calls fail or are disabled.
206
* This number is less than or equal to the number of graphics
207
* configurations supported.
208
*/
209
protected int getMaxConfigs(int screen) {
210
if (pfDisabled) {
211
return 1;
212
} else {
213
return getMaxConfigsImpl(screen);
214
}
215
}
216
217
private native int getMaxConfigsImpl(int screen);
218
219
/**
220
* Returns whether or not the PixelFormat indicated by index is
221
* supported. Supported PixelFormats support drawing to a Window
222
* (PFD_DRAW_TO_WINDOW), support GDI (PFD_SUPPORT_GDI), and in the
223
* case of an 8-bit format (cColorBits <= 8) uses indexed colors
224
* (iPixelType == PFD_TYPE_COLORINDEX).
225
* We use the index 0 to indicate that PixelFormat calls don't work, or
226
* are disabled. Do not call this function with an index of 0.
227
* @param index a PixelFormat index
228
*/
229
protected native boolean isPixFmtSupported(int index, int screen);
230
231
/**
232
* Returns the PixelFormatID of the default graphics configuration
233
* associated with this graphics device, or 0 if PixelFormats calls fail or
234
* are disabled.
235
*/
236
protected int getDefaultPixID(int screen) {
237
if (pfDisabled) {
238
return 0;
239
} else {
240
return getDefaultPixIDImpl(screen);
241
}
242
}
243
244
/**
245
* Returns the default PixelFormat ID from GDI. Do not call if PixelFormats
246
* are disabled.
247
*/
248
private native int getDefaultPixIDImpl(int screen);
249
250
/**
251
* Returns the default graphics configuration
252
* associated with this graphics device.
253
*/
254
public GraphicsConfiguration getDefaultConfiguration() {
255
if (defaultConfig == null) {
256
// first try to create a WGLGraphicsConfig if OGL is enabled
257
// REMIND: the WGL code does not yet work properly in multimon
258
// situations, so we will fallback on GDI if we are not on the
259
// default device...
260
if (WindowsFlags.isOGLEnabled() && isDefaultDevice()) {
261
int defPixID = WGLGraphicsConfig.getDefaultPixFmt(screen);
262
defaultConfig = WGLGraphicsConfig.getConfig(this, defPixID);
263
if (WindowsFlags.isOGLVerbose()) {
264
if (defaultConfig != null) {
265
System.out.print("OpenGL pipeline enabled");
266
} else {
267
System.out.print("Could not enable OpenGL pipeline");
268
}
269
System.out.println(" for default config on screen " +
270
screen);
271
}
272
}
273
274
// Fix for 4669614. Most apps are not concerned with PixelFormats,
275
// yet we ALWAYS used them for determining ColorModels and such.
276
// By passing in 0 as the PixelFormatID here, we signal that
277
// PixelFormats should not be used, thus avoid loading the opengl
278
// library. Apps concerned with PixelFormats can still use
279
// GraphicsConfiguration.getConfigurations().
280
// Note that calling native pixel format functions tends to cause
281
// problems between those functions (which are OpenGL-related)
282
// and our use of DirectX. For example, some Matrox boards will
283
// crash or hang calling these functions when any app is running
284
// in DirectX fullscreen mode. So avoiding these calls unless
285
// absolutely necessary is preferable.
286
if (defaultConfig == null) {
287
defaultConfig = Win32GraphicsConfig.getConfig(this, 0);
288
}
289
}
290
return defaultConfig;
291
}
292
293
public String toString() {
294
return valid ? descString + "]" : descString + ", removed]";
295
}
296
297
/**
298
* Returns true if this is the default GraphicsDevice for the
299
* GraphicsEnvironment.
300
*/
301
private boolean isDefaultDevice() {
302
return (this ==
303
GraphicsEnvironment.
304
getLocalGraphicsEnvironment().getDefaultScreenDevice());
305
}
306
307
private static boolean isFSExclusiveModeAllowed() {
308
SecurityManager security = System.getSecurityManager();
309
if (security != null) {
310
if (fullScreenExclusivePermission == null) {
311
fullScreenExclusivePermission =
312
new AWTPermission("fullScreenExclusive");
313
}
314
try {
315
security.checkPermission(fullScreenExclusivePermission);
316
} catch (SecurityException e) {
317
return false;
318
}
319
}
320
return true;
321
}
322
323
/**
324
* returns true unless we're not allowed to use fullscreen mode.
325
*/
326
@Override
327
public boolean isFullScreenSupported() {
328
return isFSExclusiveModeAllowed();
329
}
330
331
@Override
332
public synchronized void setFullScreenWindow(Window w) {
333
Window old = getFullScreenWindow();
334
if (w == old) {
335
return;
336
}
337
if (!isFullScreenSupported()) {
338
super.setFullScreenWindow(w);
339
return;
340
}
341
342
// Enter windowed mode.
343
if (old != null) {
344
// restore the original display mode
345
if (defaultDisplayMode != null) {
346
setDisplayMode(defaultDisplayMode);
347
// we set the default display mode to null here
348
// because the default mode could change during
349
// the life of the application (user can change it through
350
// the desktop properties dialog, for example), so
351
// we need to record it every time prior to
352
// entering the fullscreen mode.
353
defaultDisplayMode = null;
354
}
355
WWindowPeer peer = (WWindowPeer)old.getPeer();
356
if (peer != null) {
357
peer.setFullScreenExclusiveModeState(false);
358
// we used to destroy the buffers on exiting fs mode, this
359
// is no longer needed since fs change will cause a surface
360
// data replacement
361
synchronized(peer) {
362
exitFullScreenExclusive(screen, peer);
363
}
364
}
365
removeFSWindowListener(old);
366
}
367
super.setFullScreenWindow(w);
368
if (w != null) {
369
// always record the default display mode prior to going
370
// fullscreen
371
defaultDisplayMode = getDisplayMode();
372
addFSWindowListener(w);
373
// Enter full screen exclusive mode.
374
WWindowPeer peer = (WWindowPeer)w.getPeer();
375
if (peer != null) {
376
synchronized(peer) {
377
enterFullScreenExclusive(screen, peer);
378
// Note: removed replaceSurfaceData() call because
379
// changing the window size or making it visible
380
// will cause this anyway, and both of these events happen
381
// as part of switching into fullscreen mode.
382
}
383
peer.setFullScreenExclusiveModeState(true);
384
}
385
386
// fix for 4868278
387
peer.updateGC();
388
}
389
}
390
391
// Entering and exiting full-screen mode are done within a
392
// tree-lock and should never lock on any resources which are
393
// required by other threads which may have them and may require
394
// the tree-lock.
395
// REMIND: in the future these methods may need to become protected so that
396
// subclasses could override them and use appropriate api other than GDI
397
// for implementing these functions.
398
protected native void enterFullScreenExclusive(int screen, WindowPeer w);
399
protected native void exitFullScreenExclusive(int screen, WindowPeer w);
400
401
@Override
402
public boolean isDisplayChangeSupported() {
403
return (isFullScreenSupported() && getFullScreenWindow() != null);
404
}
405
406
@Override
407
public synchronized void setDisplayMode(DisplayMode dm) {
408
if (!isDisplayChangeSupported()) {
409
super.setDisplayMode(dm);
410
return;
411
}
412
if (dm == null || (dm = getMatchingDisplayMode(dm)) == null) {
413
throw new IllegalArgumentException("Invalid display mode");
414
}
415
if (getDisplayMode().equals(dm)) {
416
return;
417
}
418
Window w = getFullScreenWindow();
419
if (w != null) {
420
WWindowPeer peer = (WWindowPeer)w.getPeer();
421
configDisplayMode(screen, peer, dm.getWidth(), dm.getHeight(),
422
dm.getBitDepth(), dm.getRefreshRate());
423
// resize the fullscreen window to the dimensions of the new
424
// display mode
425
Rectangle screenBounds = getDefaultConfiguration().getBounds();
426
w.setBounds(screenBounds.x, screenBounds.y,
427
dm.getWidth(), dm.getHeight());
428
// Note: no call to replaceSurfaceData is required here since
429
// replacement will be caused by an upcoming display change event
430
} else {
431
throw new IllegalStateException("Must be in fullscreen mode " +
432
"in order to set display mode");
433
}
434
}
435
436
protected native DisplayMode getCurrentDisplayMode(int screen);
437
protected native void configDisplayMode(int screen, WindowPeer w, int width,
438
int height, int bitDepth,
439
int refreshRate);
440
protected native void enumDisplayModes(int screen, ArrayList modes);
441
442
@Override
443
public synchronized DisplayMode getDisplayMode() {
444
DisplayMode res = getCurrentDisplayMode(screen);
445
return res;
446
}
447
448
@Override
449
public synchronized DisplayMode[] getDisplayModes() {
450
ArrayList modes = new ArrayList();
451
enumDisplayModes(screen, modes);
452
int listSize = modes.size();
453
DisplayMode[] retArray = new DisplayMode[listSize];
454
for (int i = 0; i < listSize; i++) {
455
retArray[i] = (DisplayMode)modes.get(i);
456
}
457
return retArray;
458
}
459
460
protected synchronized DisplayMode getMatchingDisplayMode(DisplayMode dm) {
461
if (!isDisplayChangeSupported()) {
462
return null;
463
}
464
DisplayMode[] modes = getDisplayModes();
465
for (DisplayMode mode : modes) {
466
if (dm.equals(mode) ||
467
(dm.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN &&
468
dm.getWidth() == mode.getWidth() &&
469
dm.getHeight() == mode.getHeight() &&
470
dm.getBitDepth() == mode.getBitDepth()))
471
{
472
return mode;
473
}
474
}
475
return null;
476
}
477
478
/*
479
* From the DisplayChangeListener interface.
480
* Called from Win32GraphicsEnvironment when the display settings have
481
* changed.
482
*/
483
public void displayChanged() {
484
dynamicColorModel = null;
485
defaultConfig = null;
486
configs = null;
487
// pass on to all top-level windows on this display
488
topLevels.notifyListeners();
489
}
490
491
/**
492
* Part of the DisplayChangedListener interface: devices
493
* do not need to react to this event
494
*/
495
public void paletteChanged() {
496
}
497
498
/*
499
* Add a DisplayChangeListener to be notified when the display settings
500
* are changed. Typically, only top-level containers need to be added
501
* to Win32GraphicsDevice.
502
*/
503
public void addDisplayChangedListener(DisplayChangedListener client) {
504
topLevels.add(client);
505
}
506
507
/*
508
* Remove a DisplayChangeListener from this Win32GraphicsDevice
509
*/
510
public void removeDisplayChangedListener(DisplayChangedListener client) {
511
topLevels.remove(client);
512
}
513
514
/**
515
* Creates and returns the color model associated with this device
516
*/
517
private native ColorModel makeColorModel (int screen,
518
boolean dynamic);
519
520
/**
521
* Returns a dynamic ColorModel which is updated when there
522
* are any changes (e.g., palette changes) in the device
523
*/
524
public ColorModel getDynamicColorModel() {
525
if (dynamicColorModel == null) {
526
dynamicColorModel = makeColorModel(screen, true);
527
}
528
return dynamicColorModel;
529
}
530
531
/**
532
* Returns the non-dynamic ColorModel associated with this device
533
*/
534
public ColorModel getColorModel() {
535
if (colorModel == null) {
536
colorModel = makeColorModel(screen, false);
537
}
538
return colorModel;
539
}
540
541
/**
542
* WindowAdapter class responsible for de/iconifying full-screen window
543
* of this device.
544
*
545
* The listener restores the default display mode when window is iconified
546
* and sets it back to the one set by the user on de-iconification.
547
*/
548
private static class Win32FSWindowAdapter extends WindowAdapter {
549
private Win32GraphicsDevice device;
550
private DisplayMode dm;
551
552
Win32FSWindowAdapter(Win32GraphicsDevice device) {
553
this.device = device;
554
}
555
556
private void setFSWindowsState(Window other, int state) {
557
GraphicsDevice gds[] =
558
GraphicsEnvironment.getLocalGraphicsEnvironment().
559
getScreenDevices();
560
// check if the de/activation was caused by other
561
// fs window and ignore the event if that's the case
562
if (other != null) {
563
for (GraphicsDevice gd : gds) {
564
if (other == gd.getFullScreenWindow()) {
565
return;
566
}
567
}
568
}
569
// otherwise apply state to all fullscreen windows
570
for (GraphicsDevice gd : gds) {
571
Window fsw = gd.getFullScreenWindow();
572
if (fsw instanceof Frame) {
573
((Frame)fsw).setExtendedState(state);
574
}
575
}
576
}
577
578
@Override
579
public void windowDeactivated(WindowEvent e) {
580
setFSWindowsState(e.getOppositeWindow(), Frame.ICONIFIED);
581
}
582
583
@Override
584
public void windowActivated(WindowEvent e) {
585
setFSWindowsState(e.getOppositeWindow(), Frame.NORMAL);
586
}
587
588
@Override
589
public void windowIconified(WindowEvent e) {
590
// restore the default display mode for this device
591
DisplayMode ddm = device.defaultDisplayMode;
592
if (ddm != null) {
593
dm = device.getDisplayMode();
594
device.setDisplayMode(ddm);
595
}
596
}
597
598
@Override
599
public void windowDeiconified(WindowEvent e) {
600
// restore the user-set display mode for this device
601
if (dm != null) {
602
device.setDisplayMode(dm);
603
dm = null;
604
}
605
}
606
}
607
608
/**
609
* Adds a WindowListener to be used as
610
* activation/deactivation listener for the current full-screen window.
611
*
612
* @param w full-screen window
613
*/
614
protected void addFSWindowListener(final Window w) {
615
// Note: even though we create a listener for Window instances of
616
// fs windows they will not receive window events.
617
fsWindowListener = new Win32FSWindowAdapter(this);
618
619
// Fix for 6709453. Using invokeLater to avoid listening
620
// for the events already posted to the queue.
621
EventQueue.invokeLater(new Runnable() {
622
public void run() {
623
w.addWindowListener(fsWindowListener);
624
}
625
});
626
}
627
628
/**
629
* Removes the fs window listener.
630
*
631
* @param w full-screen window
632
*/
633
protected void removeFSWindowListener(Window w) {
634
w.removeWindowListener(fsWindowListener);
635
fsWindowListener = null;
636
}
637
}
638
639