1 /* 2 * Copyright (c) 1997, 2015, 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.AWTError; 29 import java.awt.GraphicsConfiguration; 30 import java.awt.GraphicsDevice; 31 import java.awt.peer.ComponentPeer; 32 import java.lang.ref.WeakReference; 33 import java.util.ArrayList; 34 import java.util.ListIterator; 35 36 import sun.awt.windows.WToolkit; 37 import sun.java2d.SunGraphicsEnvironment; 38 import sun.java2d.SurfaceManagerFactory; 39 import sun.java2d.WindowsSurfaceManagerFactory; 40 import sun.java2d.d3d.D3DGraphicsDevice; 41 import sun.java2d.windows.WindowsFlags; 42 43 /** 44 * This is an implementation of a GraphicsEnvironment object for the 45 * default local GraphicsEnvironment used by the Java Runtime Environment 46 * for Windows. 47 * 48 * @see GraphicsDevice 49 * @see GraphicsConfiguration 50 */ 51 52 public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment { 53 54 static { 55 // Ensure awt is loaded already. Also, this forces static init 56 // of WToolkit and Toolkit, which we depend upon 57 WToolkit.loadLibraries(); 58 // setup flags before initializing native layer 59 WindowsFlags.initFlags(); 60 initDisplayWrapper(); 61 62 // Install correct surface manager factory. 63 SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory()); 64 } 65 66 /** 67 * Initializes native components of the graphics environment. This 68 * includes everything from the native GraphicsDevice elements to 69 * the DirectX rendering layer. 70 */ 71 private static native void initDisplay(); 72 73 private static boolean displayInitialized; // = false; 74 public static void initDisplayWrapper() { 75 if (!displayInitialized) { 76 displayInitialized = true; 77 initDisplay(); 78 } 79 } 80 81 public Win32GraphicsEnvironment() { 82 } 83 84 protected native int getNumScreens(); 85 private native int getDefaultScreen(); 86 87 public GraphicsDevice getDefaultScreenDevice() { 88 GraphicsDevice[] screens = getScreenDevices(); 89 if (screens.length == 0) { 90 throw new AWTError("no screen devices"); 91 } 92 int index = getDefaultScreen(); 93 return screens[0 < index && index < screens.length ? index : 0]; 94 } 95 96 /** 97 * Returns the number of pixels per logical inch along the screen width. 98 * In a system with multiple display monitors, this value is the same for 99 * all monitors. 100 * @return number of pixels per logical inch in X direction 101 */ 102 public native int getXResolution(); 103 /** 104 * Returns the number of pixels per logical inch along the screen height. 105 * In a system with multiple display monitors, this value is the same for 106 * all monitors. 107 * @return number of pixels per logical inch in Y direction 108 */ 109 public native int getYResolution(); 110 111 112 /* 113 * ----DISPLAY CHANGE SUPPORT---- 114 */ 115 116 // list of invalidated graphics devices (those which were removed) 117 private ArrayList<WeakReference<Win32GraphicsDevice>> oldDevices; 118 /* 119 * From DisplayChangeListener interface. 120 * Called from WToolkit and executed on the event thread when the 121 * display settings are changed. 122 */ 123 @Override 124 public void displayChanged() { 125 // getNumScreens() will return the correct current number of screens 126 GraphicsDevice newDevices[] = new GraphicsDevice[getNumScreens()]; 127 GraphicsDevice oldScreens[] = screens; 128 // go through the list of current devices and determine if they 129 // could be reused, or will have to be replaced 130 if (oldScreens != null) { 131 for (int i = 0; i < oldScreens.length; i++) { 132 if (!(screens[i] instanceof Win32GraphicsDevice)) { 133 // REMIND: can we ever have anything other than Win32GD? 134 assert (false) : oldScreens[i]; 135 continue; 136 } 137 Win32GraphicsDevice gd = (Win32GraphicsDevice)oldScreens[i]; 138 // devices may be invalidated from the native code when the 139 // display change happens (device add/removal also causes a 140 // display change) 141 if (!gd.isValid()) { 142 if (oldDevices == null) { 143 oldDevices = 144 new ArrayList<WeakReference<Win32GraphicsDevice>>(); 145 } 146 oldDevices.add(new WeakReference<Win32GraphicsDevice>(gd)); 147 } else if (i < newDevices.length) { 148 // reuse the device 149 newDevices[i] = gd; 150 } 151 } 152 oldScreens = null; 153 } 154 // create the new devices (those that weren't reused) 155 for (int i = 0; i < newDevices.length; i++) { 156 if (newDevices[i] == null) { 157 newDevices[i] = makeScreenDevice(i); 158 } 159 } 160 // install the new array of devices 161 // Note: no synchronization here, it doesn't matter if a thread gets 162 // a new or an old array this time around 163 screens = newDevices; 164 for (GraphicsDevice gd : screens) { 165 if (gd instanceof DisplayChangedListener) { 166 ((DisplayChangedListener)gd).displayChanged(); 167 } 168 } 169 // re-invalidate all old devices. It's needed because those in the list 170 // may become "invalid" again - if the current default device is removed, 171 // for example. Also, they need to be notified about display 172 // changes as well. 173 if (oldDevices != null) { 174 int defScreen = getDefaultScreen(); 175 for (ListIterator<WeakReference<Win32GraphicsDevice>> it = 176 oldDevices.listIterator(); it.hasNext();) 177 { 178 Win32GraphicsDevice gd = it.next().get(); 179 if (gd != null) { 180 gd.invalidate(defScreen); 181 gd.displayChanged(); 182 } else { 183 // no more references to this device, remove it 184 it.remove(); 185 } 186 } 187 } 188 // Reset the static GC for the (possibly new) default screen 189 WToolkit.resetGC(); 190 191 // notify SunDisplayChanger list (e.g. VolatileSurfaceManagers and 192 // CachingSurfaceManagers) about the display change event 193 displayChanger.notifyListeners(); 194 // note: do not call super.displayChanged, we've already done everything 195 } 196 197 198 /* 199 * ----END DISPLAY CHANGE SUPPORT---- 200 */ 201 202 protected GraphicsDevice makeScreenDevice(int screennum) { 203 GraphicsDevice device = null; 204 if (WindowsFlags.isD3DEnabled()) { 205 device = D3DGraphicsDevice.createDevice(screennum); 206 } 207 if (device == null) { 208 device = new Win32GraphicsDevice(screennum); 209 } 210 return device; 211 } 212 213 public boolean isDisplayLocal() { 214 return true; 215 } 216 217 @Override 218 public boolean isFlipStrategyPreferred(ComponentPeer peer) { 219 GraphicsConfiguration gc; 220 if (peer != null && (gc = peer.getGraphicsConfiguration()) != null) { 221 GraphicsDevice gd = gc.getDevice(); 222 if (gd instanceof D3DGraphicsDevice) { 223 return ((D3DGraphicsDevice)gd).isD3DEnabledOnDevice(); 224 } 225 } 226 return false; 227 } 228 229 private static volatile boolean isDWMCompositionEnabled; 230 /** 231 * Returns true if dwm composition is currently enabled, false otherwise. 232 * 233 * @return true if dwm composition is enabled, false otherwise 234 */ 235 public static boolean isDWMCompositionEnabled() { 236 return isDWMCompositionEnabled; 237 } 238 239 /** 240 * Called from the native code when DWM composition state changed. 241 * May be called multiple times during the lifetime of the application. 242 * REMIND: we may want to create a listener mechanism for this. 243 * 244 * Note: called on the Toolkit thread, no user code or locks are allowed. 245 * 246 * @param enabled indicates the state of dwm composition 247 */ 248 private static void dwmCompositionChanged(boolean enabled) { 249 isDWMCompositionEnabled = enabled; 250 } 251 252 /** 253 * Used to find out if the OS is Windows Vista or later. 254 * 255 * @return {@code true} if the OS is Vista or later, {@code false} otherwise 256 */ 257 public static native boolean isVistaOS(); 258 }