1 /* 2 * Copyright (c) 2005, 2008, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @bug 5041219 27 * @bug 5101561 28 * @bug 5035272 29 * @bug 5096011 30 * @bug 5101712 31 * @bug 5098624 32 * @summary Here are a few assertions worth verification: 33 * - the fullscreen window is positioned at 0,0 34 * - the fs window appears on the correct screen 35 * - if the exclusive FS mode is supported, no other widndow should 36 * overlap the fs window (including the taskbar). 37 * You could, however, alt+tab out of a fullscreen window, or at least 38 * minimize it (if you've entered the fs mode with a Window, you'll need 39 * to minimize the owner frame). 40 * Note that there may be issues with FS exclusive mode with ddraw and 41 * multiple fullscreen windows (one per device). 42 * - if display mode is supported that it did change 43 * - that the original display mode is restored once 44 * the ws window is disposed 45 * All of the above should work with and w/o DirectDraw 46 * (-Dsun.java2d.noddraw=true) on windows, and w/ and w/o opengl on X11 47 * (-Dsun.java2d.opengl=True). 48 * @run main/manual/othervm -Dsun.java2d.pmoffscreen=true MultimonFullscreenTest 49 * @run main/manual/othervm -Dsun.java2d.pmoffscreen=false MultimonFullscreenTest 50 * @run main/manual/othervm -Dsun.java2d.d3d=True MultimonFullscreenTest 51 * @run main/manual/othervm -Dsun.java2d.noddraw=true MultimonFullscreenTest 52 * @run main/manual/othervm -Dsun.java2d.opengl=True MultimonFullscreenTest 53 */ 54 55 import java.awt.Button; 56 import java.awt.Checkbox; 57 import java.awt.CheckboxGroup; 58 import java.awt.Color; 59 import java.awt.Component; 60 import java.awt.Dialog; 61 import java.awt.DisplayMode; 62 import java.awt.Font; 63 import java.awt.Frame; 64 import java.awt.Graphics; 65 import java.awt.GraphicsConfiguration; 66 import java.awt.GraphicsDevice; 67 import java.awt.GraphicsEnvironment; 68 import java.awt.GridLayout; 69 import java.awt.Panel; 70 import java.awt.Rectangle; 71 import java.awt.Window; 72 import java.awt.event.ActionEvent; 73 import java.awt.event.ActionListener; 74 import java.awt.event.ItemEvent; 75 import java.awt.event.ItemListener; 76 import java.awt.event.MouseAdapter; 77 import java.awt.event.MouseEvent; 78 import java.awt.event.WindowAdapter; 79 import java.awt.event.WindowEvent; 80 import java.awt.image.BufferStrategy; 81 import java.util.HashMap; 82 import java.util.Random; 83 84 /** 85 */ 86 87 public class MultimonFullscreenTest extends Frame implements ActionListener { 88 GraphicsDevice defDev = GraphicsEnvironment.getLocalGraphicsEnvironment(). 89 getDefaultScreenDevice(); 90 GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment(). 91 getScreenDevices(); 92 HashMap<Button, GraphicsDevice> deviceMap; 93 94 private static boolean dmChange = false; 95 static boolean setNullOnDispose = false; 96 static boolean useFSFrame = true; 97 static boolean useFSWindow = false; 98 static boolean useFSDialog = false; 99 static boolean useBS = false; 100 static boolean runRenderLoop = false; 101 static boolean addHWChildren = false; 102 static volatile boolean done = true; 103 MultimonFullscreenTest(String title)104 public MultimonFullscreenTest(String title) { 105 super(title); 106 addWindowListener(new WindowAdapter() { 107 public void windowClosing(WindowEvent e) { 108 System.exit(0); 109 } 110 }); 111 Panel p = new Panel(); 112 deviceMap = new HashMap<Button, GraphicsDevice>(gd.length); 113 int num = 0; 114 for (GraphicsDevice dev : gd) { 115 Button b; 116 if (dev == defDev) { 117 b = new Button("Primary screen: " + num); 118 System.out.println("Primary Dev : " + dev + " Bounds: " + 119 dev.getDefaultConfiguration().getBounds()); 120 } else { 121 b = new Button("Secondary screen " + num); 122 System.out.println("Secondary Dev : " + dev + " Bounds: " + 123 dev.getDefaultConfiguration().getBounds()); 124 } 125 b.addActionListener(this); 126 p.add(b); 127 deviceMap.put(b, dev); 128 num++; 129 } 130 add("South", p); 131 Panel p1 = new Panel(); 132 p1.setLayout(new GridLayout(2,0)); 133 Checkbox cb = new Checkbox("Change DM on entering FS"); 134 cb.addItemListener(new ItemListener() { 135 public void itemStateChanged(ItemEvent e) { 136 dmChange = ((Checkbox)e.getSource()).getState(); 137 } 138 }); 139 p1.add(cb); 140 // cb = new Checkbox("Exit FS on window dispose"); 141 // cb.addItemListener(new ItemListener() { 142 // public void itemStateChanged(ItemEvent e) { 143 // setNullOnDispose = ((Checkbox)e.getSource()).getState(); 144 // } 145 // }); 146 // p1.add(cb); 147 CheckboxGroup cbg = new CheckboxGroup(); 148 cb = new Checkbox("Use Frame to enter FS", cbg, true); 149 cb.addItemListener(new ItemListener() { 150 public void itemStateChanged(ItemEvent e) { 151 useFSFrame = true; 152 useFSWindow = false; 153 useFSDialog = false; 154 } 155 }); 156 p1.add(cb); 157 cb = new Checkbox("Use Window to enter FS", cbg, false); 158 cb.addItemListener(new ItemListener() { 159 public void itemStateChanged(ItemEvent e) { 160 useFSFrame = false; 161 useFSWindow = true; 162 useFSDialog = false; 163 } 164 }); 165 p1.add(cb); 166 cb = new Checkbox("Use Dialog to enter FS", cbg, false); 167 cb.addItemListener(new ItemListener() { 168 public void itemStateChanged(ItemEvent e) { 169 useFSFrame = false; 170 useFSWindow = false; 171 useFSDialog = true; 172 } 173 }); 174 p1.add(cb); 175 cb = new Checkbox("Run render loop"); 176 cb.addItemListener(new ItemListener() { 177 public void itemStateChanged(ItemEvent e) { 178 runRenderLoop = ((Checkbox)e.getSource()).getState(); 179 } 180 }); 181 p1.add(cb); 182 cb = new Checkbox("Use BufferStrategy in render loop"); 183 cb.addItemListener(new ItemListener() { 184 public void itemStateChanged(ItemEvent e) { 185 useBS = ((Checkbox)e.getSource()).getState(); 186 } 187 }); 188 p1.add(cb); 189 cb = new Checkbox("Add Children to FS window"); 190 cb.addItemListener(new ItemListener() { 191 public void itemStateChanged(ItemEvent e) { 192 addHWChildren = ((Checkbox)e.getSource()).getState(); 193 } 194 }); 195 p1.add(cb); 196 add("North", p1); 197 198 pack(); 199 setVisible(true); 200 } 201 202 Font f = new Font("Dialog", Font.BOLD, 24); 203 Random rnd = new Random(); renderDimensions(Graphics g, Rectangle rectWndBounds, GraphicsConfiguration gc)204 public void renderDimensions(Graphics g, Rectangle rectWndBounds, 205 GraphicsConfiguration gc) { 206 g.setColor(new Color(rnd.nextInt(0xffffff))); 207 g.fillRect(0, 0, rectWndBounds.width, rectWndBounds.height); 208 209 g.setColor(new Color(rnd.nextInt(0xffffff))); 210 Rectangle rectStrBounds; 211 212 g.setFont(f); 213 214 rectStrBounds = g.getFontMetrics(). 215 getStringBounds(rectWndBounds.toString(), g).getBounds(); 216 rectStrBounds.height += 30; 217 g.drawString(rectWndBounds.toString(), 50, rectStrBounds.height); 218 int oldHeight = rectStrBounds.height; 219 String isFSupported = "Exclusive Fullscreen mode supported: " + 220 gc.getDevice().isFullScreenSupported(); 221 rectStrBounds = g.getFontMetrics(). 222 getStringBounds(isFSupported, g).getBounds(); 223 rectStrBounds.height += (10 + oldHeight); 224 g.drawString(isFSupported, 50, rectStrBounds.height); 225 226 oldHeight = rectStrBounds.height; 227 String isDMChangeSupported = "Display Mode Change supported: " + 228 gc.getDevice().isDisplayChangeSupported(); 229 rectStrBounds = g.getFontMetrics(). 230 getStringBounds(isDMChangeSupported, g).getBounds(); 231 rectStrBounds.height += (10 + oldHeight); 232 g.drawString(isDMChangeSupported, 50, rectStrBounds.height); 233 234 oldHeight = rectStrBounds.height; 235 String usingBS = "Using BufferStrategy: " + useBS; 236 rectStrBounds = g.getFontMetrics(). 237 getStringBounds(usingBS, g).getBounds(); 238 rectStrBounds.height += (10 + oldHeight); 239 g.drawString(usingBS, 50, rectStrBounds.height); 240 241 final String m_strQuitMsg = "Double-click to dispose FullScreen Window"; 242 rectStrBounds = g.getFontMetrics(). 243 getStringBounds(m_strQuitMsg, g).getBounds(); 244 g.drawString(m_strQuitMsg, 245 (rectWndBounds.width - rectStrBounds.width) / 2, 246 (rectWndBounds.height - rectStrBounds.height) / 2); 247 248 249 } 250 actionPerformed(ActionEvent ae)251 public void actionPerformed(ActionEvent ae) { 252 GraphicsDevice dev = deviceMap.get(ae.getSource()); 253 System.err.println("Setting FS on device:"+dev); 254 final Window fsWindow; 255 256 if (useFSWindow) { 257 fsWindow = new Window(this, dev.getDefaultConfiguration()) { 258 public void paint(Graphics g) { 259 renderDimensions(g, getBounds(), 260 this.getGraphicsConfiguration()); 261 } 262 }; 263 } else if (useFSDialog) { 264 fsWindow = new Dialog((Frame)null, "FS Dialog on device "+dev, false, 265 dev.getDefaultConfiguration()); 266 fsWindow.add(new Component() { 267 public void paint(Graphics g) { 268 renderDimensions(g, getBounds(), 269 this.getGraphicsConfiguration()); 270 } 271 }); 272 } else { 273 fsWindow = new Frame("FS Frame on device "+dev, 274 dev.getDefaultConfiguration()) 275 { 276 public void paint(Graphics g) { 277 renderDimensions(g, getBounds(), 278 this.getGraphicsConfiguration()); 279 } 280 }; 281 if (addHWChildren) { 282 fsWindow.add("South", new Panel() { 283 public void paint(Graphics g) { 284 g.setColor(Color.red); 285 g.fillRect(0, 0, getWidth(), getHeight()); 286 } 287 }); 288 fsWindow.add("North", new Button("Button, sucka!")); 289 } 290 } 291 fsWindow.addMouseListener(new MouseAdapter() { 292 public void mouseClicked(MouseEvent e) { 293 if (e.getClickCount() > 1) { 294 done = true; 295 fsWindow.dispose(); 296 } 297 } 298 }); 299 300 fsWindow.addWindowListener(new WindowHandler()); 301 dev.setFullScreenWindow(fsWindow); 302 if (dmChange && dev.isDisplayChangeSupported()) { 303 DisplayMode dms[] = dev.getDisplayModes(); 304 DisplayMode myDM = null; 305 for (DisplayMode dm : dms) { 306 if (dm.getWidth() == 800 && dm.getHeight() == 600 && 307 (dm.getBitDepth() >= 16 || 308 dm.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) && 309 (dm.getRefreshRate() >= 60 || 310 dm.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN)) 311 { 312 myDM = dm; 313 break; 314 } 315 } 316 if (myDM != null) { 317 System.err.println("Setting Display Mode: "+ 318 myDM.getWidth() + "x" + myDM.getHeight() + "x" + 319 myDM.getBitDepth() + "@" + myDM.getRefreshRate() + 320 "Hz on device" + dev); 321 dev.setDisplayMode(myDM); 322 } else { 323 System.err.println("Can't find suitable display mode."); 324 } 325 } 326 done = false; 327 if (runRenderLoop) { 328 Thread updateThread = new Thread(new Runnable() { 329 public void run() { 330 BufferStrategy bs = null; 331 if (useBS) { 332 fsWindow.createBufferStrategy(2); 333 bs = fsWindow.getBufferStrategy(); 334 } 335 while (!done) { 336 if (useBS) { 337 Graphics g = bs.getDrawGraphics(); 338 renderDimensions(g, fsWindow.getBounds(), 339 fsWindow.getGraphicsConfiguration()); 340 bs.show(); 341 } else { 342 fsWindow.repaint(); 343 } 344 try { 345 Thread.sleep(1000); 346 } catch (InterruptedException e) {} 347 } 348 if (useBS) { 349 bs.dispose(); 350 } 351 } 352 }); 353 updateThread.start(); 354 } 355 } 356 main(String args[])357 public static void main(String args[]) { 358 for (String s : args) { 359 if (s.equalsIgnoreCase("-dm")) { 360 System.err.println("Do Display Change after entering FS mode"); 361 dmChange = true; 362 } else if (s.equalsIgnoreCase("-usewindow")) { 363 System.err.println("Using Window to enter FS mode"); 364 useFSWindow = true; 365 } else if (s.equalsIgnoreCase("-setnull")) { 366 System.err.println("Setting null FS window on dispose"); 367 setNullOnDispose = true; 368 } else { 369 System.err.println("Usage: MultimonFullscreenTest " + 370 "[-dm][-usewindow][-setnull]"); 371 } 372 373 } 374 MultimonFullscreenTest fs = 375 new MultimonFullscreenTest("Test Full Screen"); 376 } 377 class WindowHandler extends WindowAdapter { windowClosing(WindowEvent we)378 public void windowClosing(WindowEvent we) { 379 done = true; 380 Window w = (Window)we.getSource(); 381 if (setNullOnDispose) { 382 w.getGraphicsConfiguration().getDevice().setFullScreenWindow(null); 383 } 384 w.dispose(); 385 } 386 } 387 } 388