| /* |
| * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /** |
| * @test |
| * @bug 5041219 |
| * @bug 5101561 |
| * @bug 5035272 |
| * @bug 5096011 |
| * @bug 5101712 |
| * @bug 5098624 |
| * @summary Here are a few assertions worth verification: |
| * - the fullscreen window is positioned at 0,0 |
| * - the fs window appears on the correct screen |
| * - if the exclusive FS mode is supported, no other widndow should |
| * overlap the fs window (including the taskbar). |
| * You could, however, alt+tab out of a fullscreen window, or at least |
| * minimize it (if you've entered the fs mode with a Window, you'll need |
| * to minimize the owner frame). |
| * Note that there may be issues with FS exclusive mode with ddraw and |
| * multiple fullscreen windows (one per device). |
| * - if display mode is supported that it did change |
| * - that the original display mode is restored once |
| * the ws window is disposed |
| * All of the above should work with and w/o DirectDraw |
| * (-Dsun.java2d.noddraw=true) on windows, and w/ and w/o opengl on X11 |
| * (-Dsun.java2d.opengl=True). |
| * @run main/manual/othervm -Dsun.java2d.pmoffscreen=true MultimonFullscreenTest |
| * @run main/manual/othervm -Dsun.java2d.pmoffscreen=false MultimonFullscreenTest |
| * @run main/manual/othervm -Dsun.java2d.d3d=True MultimonFullscreenTest |
| * @run main/manual/othervm -Dsun.java2d.noddraw=true MultimonFullscreenTest |
| * @run main/manual/othervm -Dsun.java2d.opengl=True MultimonFullscreenTest |
| */ |
| |
| import java.awt.Button; |
| import java.awt.Checkbox; |
| import java.awt.CheckboxGroup; |
| import java.awt.Color; |
| import java.awt.Component; |
| import java.awt.Dialog; |
| import java.awt.DisplayMode; |
| import java.awt.Font; |
| import java.awt.Frame; |
| import java.awt.Graphics; |
| import java.awt.GraphicsConfiguration; |
| import java.awt.GraphicsDevice; |
| import java.awt.GraphicsEnvironment; |
| import java.awt.GridLayout; |
| import java.awt.Panel; |
| import java.awt.Rectangle; |
| import java.awt.Window; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.awt.event.ItemEvent; |
| import java.awt.event.ItemListener; |
| import java.awt.event.MouseAdapter; |
| import java.awt.event.MouseEvent; |
| import java.awt.event.WindowAdapter; |
| import java.awt.event.WindowEvent; |
| import java.awt.image.BufferStrategy; |
| import java.util.HashMap; |
| import java.util.Random; |
| |
| /** |
| */ |
| |
| public class MultimonFullscreenTest extends Frame implements ActionListener { |
| GraphicsDevice defDev = GraphicsEnvironment.getLocalGraphicsEnvironment(). |
| getDefaultScreenDevice(); |
| GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment(). |
| getScreenDevices(); |
| HashMap<Button, GraphicsDevice> deviceMap; |
| |
| private static boolean dmChange = false; |
| static boolean setNullOnDispose = false; |
| static boolean useFSFrame = true; |
| static boolean useFSWindow = false; |
| static boolean useFSDialog = false; |
| static boolean useBS = false; |
| static boolean runRenderLoop = false; |
| static boolean addHWChildren = false; |
| static volatile boolean done = true; |
| |
| public MultimonFullscreenTest(String title) { |
| super(title); |
| addWindowListener(new WindowAdapter() { |
| public void windowClosing(WindowEvent e) { |
| System.exit(0); |
| } |
| }); |
| Panel p = new Panel(); |
| deviceMap = new HashMap<Button, GraphicsDevice>(gd.length); |
| int num = 0; |
| for (GraphicsDevice dev : gd) { |
| Button b; |
| if (dev == defDev) { |
| b = new Button("Primary screen: " + num); |
| System.out.println("Primary Dev : " + dev + " Bounds: " + |
| dev.getDefaultConfiguration().getBounds()); |
| } else { |
| b = new Button("Secondary screen " + num); |
| System.out.println("Secondary Dev : " + dev + " Bounds: " + |
| dev.getDefaultConfiguration().getBounds()); |
| } |
| b.addActionListener(this); |
| p.add(b); |
| deviceMap.put(b, dev); |
| num++; |
| } |
| add("South", p); |
| Panel p1 = new Panel(); |
| p1.setLayout(new GridLayout(2,0)); |
| Checkbox cb = new Checkbox("Change DM on entering FS"); |
| cb.addItemListener(new ItemListener() { |
| public void itemStateChanged(ItemEvent e) { |
| dmChange = ((Checkbox)e.getSource()).getState(); |
| } |
| }); |
| p1.add(cb); |
| // cb = new Checkbox("Exit FS on window dispose"); |
| // cb.addItemListener(new ItemListener() { |
| // public void itemStateChanged(ItemEvent e) { |
| // setNullOnDispose = ((Checkbox)e.getSource()).getState(); |
| // } |
| // }); |
| // p1.add(cb); |
| CheckboxGroup cbg = new CheckboxGroup(); |
| cb = new Checkbox("Use Frame to enter FS", cbg, true); |
| cb.addItemListener(new ItemListener() { |
| public void itemStateChanged(ItemEvent e) { |
| useFSFrame = true; |
| useFSWindow = false; |
| useFSDialog = false; |
| } |
| }); |
| p1.add(cb); |
| cb = new Checkbox("Use Window to enter FS", cbg, false); |
| cb.addItemListener(new ItemListener() { |
| public void itemStateChanged(ItemEvent e) { |
| useFSFrame = false; |
| useFSWindow = true; |
| useFSDialog = false; |
| } |
| }); |
| p1.add(cb); |
| cb = new Checkbox("Use Dialog to enter FS", cbg, false); |
| cb.addItemListener(new ItemListener() { |
| public void itemStateChanged(ItemEvent e) { |
| useFSFrame = false; |
| useFSWindow = false; |
| useFSDialog = true; |
| } |
| }); |
| p1.add(cb); |
| cb = new Checkbox("Run render loop"); |
| cb.addItemListener(new ItemListener() { |
| public void itemStateChanged(ItemEvent e) { |
| runRenderLoop = ((Checkbox)e.getSource()).getState(); |
| } |
| }); |
| p1.add(cb); |
| cb = new Checkbox("Use BufferStrategy in render loop"); |
| cb.addItemListener(new ItemListener() { |
| public void itemStateChanged(ItemEvent e) { |
| useBS = ((Checkbox)e.getSource()).getState(); |
| } |
| }); |
| p1.add(cb); |
| cb = new Checkbox("Add Children to FS window"); |
| cb.addItemListener(new ItemListener() { |
| public void itemStateChanged(ItemEvent e) { |
| addHWChildren = ((Checkbox)e.getSource()).getState(); |
| } |
| }); |
| p1.add(cb); |
| add("North", p1); |
| |
| pack(); |
| setVisible(true); |
| } |
| |
| Font f = new Font("Dialog", Font.BOLD, 24); |
| Random rnd = new Random(); |
| public void renderDimensions(Graphics g, Rectangle rectWndBounds, |
| GraphicsConfiguration gc) { |
| g.setColor(new Color(rnd.nextInt(0xffffff))); |
| g.fillRect(0, 0, rectWndBounds.width, rectWndBounds.height); |
| |
| g.setColor(new Color(rnd.nextInt(0xffffff))); |
| Rectangle rectStrBounds; |
| |
| g.setFont(f); |
| |
| rectStrBounds = g.getFontMetrics(). |
| getStringBounds(rectWndBounds.toString(), g).getBounds(); |
| rectStrBounds.height += 30; |
| g.drawString(rectWndBounds.toString(), 50, rectStrBounds.height); |
| int oldHeight = rectStrBounds.height; |
| String isFSupported = "Exclusive Fullscreen mode supported: " + |
| gc.getDevice().isFullScreenSupported(); |
| rectStrBounds = g.getFontMetrics(). |
| getStringBounds(isFSupported, g).getBounds(); |
| rectStrBounds.height += (10 + oldHeight); |
| g.drawString(isFSupported, 50, rectStrBounds.height); |
| |
| oldHeight = rectStrBounds.height; |
| String isDMChangeSupported = "Display Mode Change supported: " + |
| gc.getDevice().isDisplayChangeSupported(); |
| rectStrBounds = g.getFontMetrics(). |
| getStringBounds(isDMChangeSupported, g).getBounds(); |
| rectStrBounds.height += (10 + oldHeight); |
| g.drawString(isDMChangeSupported, 50, rectStrBounds.height); |
| |
| oldHeight = rectStrBounds.height; |
| String usingBS = "Using BufferStrategy: " + useBS; |
| rectStrBounds = g.getFontMetrics(). |
| getStringBounds(usingBS, g).getBounds(); |
| rectStrBounds.height += (10 + oldHeight); |
| g.drawString(usingBS, 50, rectStrBounds.height); |
| |
| final String m_strQuitMsg = "Double-click to dispose FullScreen Window"; |
| rectStrBounds = g.getFontMetrics(). |
| getStringBounds(m_strQuitMsg, g).getBounds(); |
| g.drawString(m_strQuitMsg, |
| (rectWndBounds.width - rectStrBounds.width) / 2, |
| (rectWndBounds.height - rectStrBounds.height) / 2); |
| |
| |
| } |
| |
| public void actionPerformed(ActionEvent ae) { |
| GraphicsDevice dev = deviceMap.get(ae.getSource()); |
| System.err.println("Setting FS on device:"+dev); |
| final Window fsWindow; |
| |
| if (useFSWindow) { |
| fsWindow = new Window(this, dev.getDefaultConfiguration()) { |
| public void paint(Graphics g) { |
| renderDimensions(g, getBounds(), |
| this.getGraphicsConfiguration()); |
| } |
| }; |
| } else if (useFSDialog) { |
| fsWindow = new Dialog((Frame)null, "FS Dialog on device "+dev, false, |
| dev.getDefaultConfiguration()); |
| fsWindow.add(new Component() { |
| public void paint(Graphics g) { |
| renderDimensions(g, getBounds(), |
| this.getGraphicsConfiguration()); |
| } |
| }); |
| } else { |
| fsWindow = new Frame("FS Frame on device "+dev, |
| dev.getDefaultConfiguration()) |
| { |
| public void paint(Graphics g) { |
| renderDimensions(g, getBounds(), |
| this.getGraphicsConfiguration()); |
| } |
| }; |
| if (addHWChildren) { |
| fsWindow.add("South", new Panel() { |
| public void paint(Graphics g) { |
| g.setColor(Color.red); |
| g.fillRect(0, 0, getWidth(), getHeight()); |
| } |
| }); |
| fsWindow.add("North", new Button("Button, sucka!")); |
| } |
| } |
| fsWindow.addMouseListener(new MouseAdapter() { |
| public void mouseClicked(MouseEvent e) { |
| if (e.getClickCount() > 1) { |
| done = true; |
| fsWindow.dispose(); |
| } |
| } |
| }); |
| |
| fsWindow.addWindowListener(new WindowHandler()); |
| dev.setFullScreenWindow(fsWindow); |
| if (dmChange && dev.isDisplayChangeSupported()) { |
| DisplayMode dms[] = dev.getDisplayModes(); |
| DisplayMode myDM = null; |
| for (DisplayMode dm : dms) { |
| if (dm.getWidth() == 800 && dm.getHeight() == 600 && |
| (dm.getBitDepth() >= 16 || |
| dm.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) && |
| (dm.getRefreshRate() >= 60 || |
| dm.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN)) |
| { |
| myDM = dm; |
| break; |
| } |
| } |
| if (myDM != null) { |
| System.err.println("Setting Display Mode: "+ |
| myDM.getWidth() + "x" + myDM.getHeight() + "x" + |
| myDM.getBitDepth() + "@" + myDM.getRefreshRate() + |
| "Hz on device" + dev); |
| dev.setDisplayMode(myDM); |
| } else { |
| System.err.println("Can't find suitable display mode."); |
| } |
| } |
| done = false; |
| if (runRenderLoop) { |
| Thread updateThread = new Thread(new Runnable() { |
| public void run() { |
| BufferStrategy bs = null; |
| if (useBS) { |
| fsWindow.createBufferStrategy(2); |
| bs = fsWindow.getBufferStrategy(); |
| } |
| while (!done) { |
| if (useBS) { |
| Graphics g = bs.getDrawGraphics(); |
| renderDimensions(g, fsWindow.getBounds(), |
| fsWindow.getGraphicsConfiguration()); |
| bs.show(); |
| } else { |
| fsWindow.repaint(); |
| } |
| try { |
| Thread.sleep(1000); |
| } catch (InterruptedException e) {} |
| } |
| if (useBS) { |
| bs.dispose(); |
| } |
| } |
| }); |
| updateThread.start(); |
| } |
| } |
| |
| public static void main(String args[]) { |
| for (String s : args) { |
| if (s.equalsIgnoreCase("-dm")) { |
| System.err.println("Do Display Change after entering FS mode"); |
| dmChange = true; |
| } else if (s.equalsIgnoreCase("-usewindow")) { |
| System.err.println("Using Window to enter FS mode"); |
| useFSWindow = true; |
| } else if (s.equalsIgnoreCase("-setnull")) { |
| System.err.println("Setting null FS window on dispose"); |
| setNullOnDispose = true; |
| } else { |
| System.err.println("Usage: MultimonFullscreenTest " + |
| "[-dm][-usewindow][-setnull]"); |
| } |
| |
| } |
| MultimonFullscreenTest fs = |
| new MultimonFullscreenTest("Test Full Screen"); |
| } |
| class WindowHandler extends WindowAdapter { |
| public void windowClosing(WindowEvent we) { |
| done = true; |
| Window w = (Window)we.getSource(); |
| if (setNullOnDispose) { |
| w.getGraphicsConfiguration().getDevice().setFullScreenWindow(null); |
| } |
| w.dispose(); |
| } |
| } |
| } |