Path: blob/master/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java
41153 views
/*1* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.awt;2627import java.awt.AWTError;28import java.awt.GraphicsConfiguration;29import java.awt.GraphicsDevice;30import java.awt.peer.ComponentPeer;31import java.lang.ref.WeakReference;32import java.util.ArrayList;33import java.util.ListIterator;3435import sun.awt.windows.WToolkit;36import sun.java2d.SunGraphicsEnvironment;37import sun.java2d.SurfaceManagerFactory;38import sun.java2d.WindowsSurfaceManagerFactory;39import sun.java2d.d3d.D3DGraphicsDevice;40import sun.java2d.windows.WindowsFlags;4142/**43* This is an implementation of a GraphicsEnvironment object for the44* default local GraphicsEnvironment used by the Java Runtime Environment45* for Windows.46*47* @see GraphicsDevice48* @see GraphicsConfiguration49*/5051public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment {5253static final float debugScaleX;54static final float debugScaleY;5556static {57// Ensure awt is loaded already. Also, this forces static init58// of WToolkit and Toolkit, which we depend upon59WToolkit.loadLibraries();60// setup flags before initializing native layer61WindowsFlags.initFlags();62initDisplayWrapper();6364// Install correct surface manager factory.65SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory());6667double sx = -1;68double sy = -1;69if (isUIScaleEnabled()) {70sx = getScaleFactor("sun.java2d.win.uiScaleX");71sy = getScaleFactor("sun.java2d.win.uiScaleY");72if (sx <= 0 || sy <= 0) {73double s = getDebugScale();74sx = s;75sy = s;76}77}7879debugScaleX = (float) sx;80debugScaleY = (float) sy;81}8283/**84* Initializes native components of the graphics environment. This85* includes everything from the native GraphicsDevice elements to86* the DirectX rendering layer.87*/88private static native void initDisplay();8990private static boolean displayInitialized; // = false;91public static void initDisplayWrapper() {92if (!displayInitialized) {93displayInitialized = true;94initDisplay();95}96}9798public Win32GraphicsEnvironment() {99}100101protected native int getNumScreens();102private native int getDefaultScreen();103104public GraphicsDevice getDefaultScreenDevice() {105GraphicsDevice[] screens = getScreenDevices();106if (screens.length == 0) {107throw new AWTError("no screen devices");108}109int index = getDefaultScreen();110return screens[0 < index && index < screens.length ? index : 0];111}112113/**114* Returns the number of pixels per logical inch along the screen width.115* In a system with multiple display monitors, this value is the same for116* all monitors.117* @return number of pixels per logical inch in X direction118*/119public native int getXResolution();120/**121* Returns the number of pixels per logical inch along the screen height.122* In a system with multiple display monitors, this value is the same for123* all monitors.124* @return number of pixels per logical inch in Y direction125*/126public native int getYResolution();127128129/*130* ----DISPLAY CHANGE SUPPORT----131*/132133// list of invalidated graphics devices (those which were removed)134private ArrayList<WeakReference<Win32GraphicsDevice>> oldDevices;135/*136* From DisplayChangeListener interface.137* Called from WToolkit and executed on the event thread when the138* display settings are changed.139*/140@Override141public void displayChanged() {142// getNumScreens() will return the correct current number of screens143GraphicsDevice[] newDevices = new GraphicsDevice[getNumScreens()];144GraphicsDevice[] oldScreens = screens;145// go through the list of current devices and determine if they146// could be reused, or will have to be replaced147if (oldScreens != null) {148for (int i = 0; i < oldScreens.length; i++) {149if (!(screens[i] instanceof Win32GraphicsDevice)) {150// REMIND: can we ever have anything other than Win32GD?151assert (false) : oldScreens[i];152continue;153}154Win32GraphicsDevice gd = (Win32GraphicsDevice)oldScreens[i];155// devices may be invalidated from the native code when the156// display change happens (device add/removal also causes a157// display change)158if (!gd.isValid()) {159if (oldDevices == null) {160oldDevices =161new ArrayList<WeakReference<Win32GraphicsDevice>>();162}163oldDevices.add(new WeakReference<Win32GraphicsDevice>(gd));164} else if (i < newDevices.length) {165// reuse the device166newDevices[i] = gd;167}168}169oldScreens = null;170}171// create the new devices (those that weren't reused)172for (int i = 0; i < newDevices.length; i++) {173if (newDevices[i] == null) {174newDevices[i] = makeScreenDevice(i);175}176}177// install the new array of devices178// Note: no synchronization here, it doesn't matter if a thread gets179// a new or an old array this time around180screens = newDevices;181for (GraphicsDevice gd : screens) {182if (gd instanceof DisplayChangedListener) {183((DisplayChangedListener)gd).displayChanged();184}185}186// re-invalidate all old devices. It's needed because those in the list187// may become "invalid" again - if the current default device is removed,188// for example. Also, they need to be notified about display189// changes as well.190if (oldDevices != null) {191int defScreen = getDefaultScreen();192for (ListIterator<WeakReference<Win32GraphicsDevice>> it =193oldDevices.listIterator(); it.hasNext();)194{195Win32GraphicsDevice gd = it.next().get();196if (gd != null) {197gd.invalidate(defScreen);198gd.displayChanged();199} else {200// no more references to this device, remove it201it.remove();202}203}204}205// notify SunDisplayChanger list (e.g. VolatileSurfaceManagers and206// CachingSurfaceManagers) about the display change event207displayChanger.notifyListeners();208// note: do not call super.displayChanged, we've already done everything209}210211212/*213* ----END DISPLAY CHANGE SUPPORT----214*/215216protected GraphicsDevice makeScreenDevice(int screennum) {217GraphicsDevice device = null;218if (WindowsFlags.isD3DEnabled()) {219device = D3DGraphicsDevice.createDevice(screennum);220}221if (device == null) {222device = new Win32GraphicsDevice(screennum);223}224return device;225}226227public boolean isDisplayLocal() {228return true;229}230231@Override232public boolean isFlipStrategyPreferred(ComponentPeer peer) {233GraphicsConfiguration gc;234if (peer != null && (gc = peer.getGraphicsConfiguration()) != null) {235GraphicsDevice gd = gc.getDevice();236if (gd instanceof D3DGraphicsDevice) {237return ((D3DGraphicsDevice)gd).isD3DEnabledOnDevice();238}239}240return false;241}242243private static volatile boolean isDWMCompositionEnabled;244/**245* Returns true if dwm composition is currently enabled, false otherwise.246*247* @return true if dwm composition is enabled, false otherwise248*/249public static boolean isDWMCompositionEnabled() {250return isDWMCompositionEnabled;251}252253/**254* Called from the native code when DWM composition state changed.255* May be called multiple times during the lifetime of the application.256* REMIND: we may want to create a listener mechanism for this.257*258* Note: called on the Toolkit thread, no user code or locks are allowed.259*260* @param enabled indicates the state of dwm composition261*/262private static void dwmCompositionChanged(boolean enabled) {263isDWMCompositionEnabled = enabled;264}265266/**267* Used to find out if the OS is Windows Vista or later.268*269* @return {@code true} if the OS is Vista or later, {@code false} otherwise270*/271public static native boolean isVistaOS();272}273274275