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