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 * @key randomness 54 */ 55 56 import java.awt.Button; 57 import java.awt.Checkbox; 58 import java.awt.CheckboxGroup; 59 import java.awt.Color; 60 import java.awt.Component; 61 import java.awt.Dialog; 62 import java.awt.DisplayMode; 63 import java.awt.Font; 64 import java.awt.Frame; 65 import java.awt.Graphics; 66 import java.awt.GraphicsConfiguration; 67 import java.awt.GraphicsDevice; 68 import java.awt.GraphicsEnvironment; 69 import java.awt.GridLayout; 70 import java.awt.Panel; 71 import java.awt.Rectangle; 72 import java.awt.Window; 73 import java.awt.event.ActionEvent; 74 import java.awt.event.ActionListener; 75 import java.awt.event.ItemEvent; 76 import java.awt.event.ItemListener; 77 import java.awt.event.MouseAdapter; 78 import java.awt.event.MouseEvent; 79 import java.awt.event.WindowAdapter; 80 import java.awt.event.WindowEvent; 81 import java.awt.image.BufferStrategy; 82 import java.util.HashMap; 83 import java.util.Random; 84 85 /** 86 */ 87 88 public class MultimonFullscreenTest extends Frame implements ActionListener { 89 GraphicsDevice defDev = GraphicsEnvironment.getLocalGraphicsEnvironment(). 90 getDefaultScreenDevice(); 91 GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment(). 92 getScreenDevices(); 93 HashMap<Button, GraphicsDevice> deviceMap; 94 95 private static boolean dmChange = false; 96 static boolean setNullOnDispose = false; 97 static boolean useFSFrame = true; 98 static boolean useFSWindow = false; 99 static boolean useFSDialog = false; 100 static boolean useBS = false; 101 static boolean runRenderLoop = false; 102 static boolean addHWChildren = false; 103 static volatile boolean done = true; 104 105 public MultimonFullscreenTest(String title) { 106 super(title); 107 addWindowListener(new WindowAdapter() { 108 public void windowClosing(WindowEvent e) { 109 System.exit(0); 110 } 111 }); 112 Panel p = new Panel(); 113 deviceMap = new HashMap<Button, GraphicsDevice>(gd.length); 114 int num = 0; 115 for (GraphicsDevice dev : gd) { 116 Button b; 117 if (dev == defDev) { 118 b = new Button("Primary screen: " + num); 119 System.out.println("Primary Dev : " + dev + " Bounds: " + 120 dev.getDefaultConfiguration().getBounds()); 121 } else { 122 b = new Button("Secondary screen " + num); 123 System.out.println("Secondary Dev : " + dev + " Bounds: " + 124 dev.getDefaultConfiguration().getBounds()); 125 } 126 b.addActionListener(this); 127 p.add(b); 128 deviceMap.put(b, dev); 129 num++; 130 } 131 add("South", p); 132 Panel p1 = new Panel(); 133 p1.setLayout(new GridLayout(2,0)); 134 Checkbox cb = new Checkbox("Change DM on entering FS"); 135 cb.addItemListener(new ItemListener() { 136 public void itemStateChanged(ItemEvent e) { 137 dmChange = ((Checkbox)e.getSource()).getState(); 138 } 139 }); 140 p1.add(cb); 141 // cb = new Checkbox("Exit FS on window dispose"); 142 // cb.addItemListener(new ItemListener() { 143 // public void itemStateChanged(ItemEvent e) { 144 // setNullOnDispose = ((Checkbox)e.getSource()).getState(); 145 // } 146 // }); 147 // p1.add(cb); 148 CheckboxGroup cbg = new CheckboxGroup(); 149 cb = new Checkbox("Use Frame to enter FS", cbg, true); 150 cb.addItemListener(new ItemListener() { 151 public void itemStateChanged(ItemEvent e) { 152 useFSFrame = true; 153 useFSWindow = false; 154 useFSDialog = false; 155 } 156 }); 157 p1.add(cb); 158 cb = new Checkbox("Use Window to enter FS", cbg, false); 159 cb.addItemListener(new ItemListener() { 160 public void itemStateChanged(ItemEvent e) { 161 useFSFrame = false; 162 useFSWindow = true; 163 useFSDialog = false; 164 } 165 }); 166 p1.add(cb); 167 cb = new Checkbox("Use Dialog to enter FS", cbg, false); 168 cb.addItemListener(new ItemListener() { 169 public void itemStateChanged(ItemEvent e) { 170 useFSFrame = false; 171 useFSWindow = false; 172 useFSDialog = true; 173 } 174 }); 175 p1.add(cb); 176 cb = new Checkbox("Run render loop"); 177 cb.addItemListener(new ItemListener() { 178 public void itemStateChanged(ItemEvent e) { 179 runRenderLoop = ((Checkbox)e.getSource()).getState(); 180 } 181 }); 182 p1.add(cb); 183 cb = new Checkbox("Use BufferStrategy in render loop"); 184 cb.addItemListener(new ItemListener() { 185 public void itemStateChanged(ItemEvent e) { 186 useBS = ((Checkbox)e.getSource()).getState(); 187 } 188 }); 189 p1.add(cb); 190 cb = new Checkbox("Add Children to FS window"); 191 cb.addItemListener(new ItemListener() { 192 public void itemStateChanged(ItemEvent e) { 193 addHWChildren = ((Checkbox)e.getSource()).getState(); 194 } 195 }); 196 p1.add(cb); 197 add("North", p1); 198 199 pack(); 200 setVisible(true); 201 } 202 203 Font f = new Font("Dialog", Font.BOLD, 24); 204 Random rnd = new Random(); 205 public void renderDimensions(Graphics g, Rectangle rectWndBounds, 206 GraphicsConfiguration gc) { 207 g.setColor(new Color(rnd.nextInt(0xffffff))); 208 g.fillRect(0, 0, rectWndBounds.width, rectWndBounds.height); 209 210 g.setColor(new Color(rnd.nextInt(0xffffff))); 211 Rectangle rectStrBounds; 212 213 g.setFont(f); 214 215 rectStrBounds = g.getFontMetrics(). 216 getStringBounds(rectWndBounds.toString(), g).getBounds(); 217 rectStrBounds.height += 30; 218 g.drawString(rectWndBounds.toString(), 50, rectStrBounds.height); 219 int oldHeight = rectStrBounds.height; 220 String isFSupported = "Exclusive Fullscreen mode supported: " + 221 gc.getDevice().isFullScreenSupported(); 222 rectStrBounds = g.getFontMetrics(). 223 getStringBounds(isFSupported, g).getBounds(); 224 rectStrBounds.height += (10 + oldHeight); 225 g.drawString(isFSupported, 50, rectStrBounds.height); 226 227 oldHeight = rectStrBounds.height; 228 String isDMChangeSupported = "Display Mode Change supported: " + 229 gc.getDevice().isDisplayChangeSupported(); 230 rectStrBounds = g.getFontMetrics(). 231 getStringBounds(isDMChangeSupported, g).getBounds(); 232 rectStrBounds.height += (10 + oldHeight); 233 g.drawString(isDMChangeSupported, 50, rectStrBounds.height); 234 235 oldHeight = rectStrBounds.height; 236 String usingBS = "Using BufferStrategy: " + useBS; 237 rectStrBounds = g.getFontMetrics(). 238 getStringBounds(usingBS, g).getBounds(); 239 rectStrBounds.height += (10 + oldHeight); 240 g.drawString(usingBS, 50, rectStrBounds.height); 241 242 final String m_strQuitMsg = "Double-click to dispose FullScreen Window"; 243 rectStrBounds = g.getFontMetrics(). 244 getStringBounds(m_strQuitMsg, g).getBounds(); 245 g.drawString(m_strQuitMsg, 246 (rectWndBounds.width - rectStrBounds.width) / 2, 247 (rectWndBounds.height - rectStrBounds.height) / 2); 248 249 250 } 251 252 public void actionPerformed(ActionEvent ae) { 253 GraphicsDevice dev = deviceMap.get(ae.getSource()); 254 System.err.println("Setting FS on device:"+dev); 255 final Window fsWindow; 256 257 if (useFSWindow) { 258 fsWindow = new Window(this, dev.getDefaultConfiguration()) { 259 public void paint(Graphics g) { 260 renderDimensions(g, getBounds(), 261 this.getGraphicsConfiguration()); 262 } 263 }; 264 } else if (useFSDialog) { 265 fsWindow = new Dialog((Frame)null, "FS Dialog on device "+dev, false, 266 dev.getDefaultConfiguration()); 267 fsWindow.add(new Component() { 268 public void paint(Graphics g) { 269 renderDimensions(g, getBounds(), 270 this.getGraphicsConfiguration()); 271 } 272 }); 273 } else { 274 fsWindow = new Frame("FS Frame on device "+dev, 275 dev.getDefaultConfiguration()) 276 { 277 public void paint(Graphics g) { 278 renderDimensions(g, getBounds(), 279 this.getGraphicsConfiguration()); 280 } 281 }; 282 if (addHWChildren) { 283 fsWindow.add("South", new Panel() { 284 public void paint(Graphics g) { 285 g.setColor(Color.red); 286 g.fillRect(0, 0, getWidth(), getHeight()); 287 } 288 }); 289 fsWindow.add("North", new Button("Button, sucka!")); 290 } 291 } 292 fsWindow.addMouseListener(new MouseAdapter() { 293 public void mouseClicked(MouseEvent e) { 294 if (e.getClickCount() > 1) { 295 done = true; 296 fsWindow.dispose(); 297 } 298 } 299 }); 300 301 fsWindow.addWindowListener(new WindowHandler()); 302 dev.setFullScreenWindow(fsWindow); 303 if (dmChange && dev.isDisplayChangeSupported()) { 304 DisplayMode dms[] = dev.getDisplayModes(); 305 DisplayMode myDM = null; 306 for (DisplayMode dm : dms) { 307 if (dm.getWidth() == 800 && dm.getHeight() == 600 && 308 (dm.getBitDepth() >= 16 || 309 dm.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) && 310 (dm.getRefreshRate() >= 60 || 311 dm.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN)) 312 { 313 myDM = dm; 314 break; 315 } 316 } 317 if (myDM != null) { 318 System.err.println("Setting Display Mode: "+ 319 myDM.getWidth() + "x" + myDM.getHeight() + "x" + 320 myDM.getBitDepth() + "@" + myDM.getRefreshRate() + 321 "Hz on device" + dev); 322 dev.setDisplayMode(myDM); 323 } else { 324 System.err.println("Can't find suitable display mode."); 325 } 326 } 327 done = false; 328 if (runRenderLoop) { 329 Thread updateThread = new Thread(new Runnable() { 330 public void run() { 331 BufferStrategy bs = null; 332 if (useBS) { 333 fsWindow.createBufferStrategy(2); 334 bs = fsWindow.getBufferStrategy(); 335 } 336 while (!done) { 337 if (useBS) { 338 Graphics g = bs.getDrawGraphics(); 339 renderDimensions(g, fsWindow.getBounds(), 340 fsWindow.getGraphicsConfiguration()); 341 bs.show(); 342 } else { 343 fsWindow.repaint(); 344 } 345 try { 346 Thread.sleep(1000); 347 } catch (InterruptedException e) {} 348 } 349 if (useBS) { 350 bs.dispose(); 351 } 352 } 353 }); 354 updateThread.start(); 355 } 356 } 357 358 public static void main(String args[]) { 359 for (String s : args) { 360 if (s.equalsIgnoreCase("-dm")) { 361 System.err.println("Do Display Change after entering FS mode"); 362 dmChange = true; 363 } else if (s.equalsIgnoreCase("-usewindow")) { 364 System.err.println("Using Window to enter FS mode"); 365 useFSWindow = true; 366 } else if (s.equalsIgnoreCase("-setnull")) { 367 System.err.println("Setting null FS window on dispose"); 368 setNullOnDispose = true; 369 } else { 370 System.err.println("Usage: MultimonFullscreenTest " + 371 "[-dm][-usewindow][-setnull]"); 372 } 373 374 } 375 MultimonFullscreenTest fs = 376 new MultimonFullscreenTest("Test Full Screen"); 377 } 378 class WindowHandler extends WindowAdapter { 379 public void windowClosing(WindowEvent we) { 380 done = true; 381 Window w = (Window)we.getSource(); 382 if (setNullOnDispose) { 383 w.getGraphicsConfiguration().getDevice().setFullScreenWindow(null); 384 } 385 w.dispose(); 386 } 387 } 388 }