/* * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.internal; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.ui.JBColor; import com.intellij.ui.ScreenUtil; import org.jetbrains.annotations.NotNull; import java.awt.*; import java.util.ArrayList; import javax.swing.Action; import javax.swing.JComponent; /** * @author Sergey.Malenkov */ public class DumpScreenConfigurationAction extends DumbAwareAction { private static final Logger LOG = Logger.getInstance(DumpScreenConfigurationAction.class); @Override public void actionPerformed(AnActionEvent event) { new ScreenDialog(event).show(); } private static Rectangle minimize(Rectangle bounds) { return new Rectangle(bounds.x / 10, bounds.y / 10, bounds.width / 10, bounds.height / 10); } private static void append(StringBuilder sb, GraphicsDevice device) { append(sb, "id", device.getIDstring()); append(sb, "type", getTypeName(device.getType())); append(sb, device.getDisplayMode()); GraphicsConfiguration configuration = device.getDefaultConfiguration(); append(sb, "outer", configuration.getBounds()); append(sb, "inner", ScreenUtil.getScreenRectangle(configuration)); append(sb, "default image", configuration.getImageCapabilities()); BufferCapabilities capabilities = configuration.getBufferCapabilities(); append(sb, "front buffer image", capabilities.getFrontBufferCapabilities()); append(sb, "back buffer image", capabilities.getBackBufferCapabilities()); sb.append("page flipping: ").append(capabilities.getFlipContents()); if (capabilities.isFullScreenRequired()) { sb.append("; full-screen exclusive mode is required"); } if (capabilities.isMultiBufferAvailable()) { sb.append("; more than two buffers can be used"); } sb.append("\n"); } private static void append(StringBuilder sb, String name, String text) { sb.append(name).append(": ").append(text).append("\n"); } private static void append(StringBuilder sb, String name, Rectangle bounds) { sb.append(name); sb.append(": x=").append(bounds.x); sb.append(", y=").append(bounds.y); sb.append(", width=").append(bounds.width); sb.append(", height=").append(bounds.height); sb.append("\n"); } private static void append(StringBuilder sb, DisplayMode mode) { sb.append("mode: ").append(mode.getWidth()).append("x").append(mode.getHeight()); sb.append("; bit depth=").append(mode.getBitDepth()); sb.append("; refresh rate=").append(mode.getRefreshRate()); sb.append("\n"); } private static void append(StringBuilder sb, String name, ImageCapabilities capabilities) { if (capabilities != null) { sb.append(name).append(": accelerated=").append(capabilities.isAccelerated()); if (capabilities.isTrueVolatile()) { sb.append("; true volatile"); } sb.append("\n"); } } private static String getTypeName(int type) { if (type == 0) return "raster screen"; if (type == 1) return "printer"; if (type == 2) return "image buffer"; return "unknown: " + type; } private static final class ScreenDialog extends DialogWrapper { private ScreenDialog(AnActionEvent event) { super(event.getProject()); init(); setOKButtonText("Dump"); setTitle("Screen Configuration"); } @Override protected JComponent createCenterPanel() { return new ScreenView(); } @NotNull @Override protected Action[] createActions() { return new Action[]{getOKAction(), getCancelAction()}; } @Override protected void doOKAction() { StringBuilder sb = new StringBuilder(); GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); append(sb, "number of devices", Integer.toString(devices.length)); for (GraphicsDevice device : devices) { append(sb.append("\n"), device); } LOG.warn(sb.toString()); super.doOKAction(); } } private static final class ScreenInfo { private final Rectangle myOuterBounds = new Rectangle(); private final Rectangle myInnerBounds = new Rectangle(); private boolean update(GraphicsConfiguration configuration) { boolean updated = false; Rectangle outer = minimize(configuration.getBounds()); if (!myOuterBounds.equals(outer)) { myOuterBounds.setBounds(outer); updated = true; } Rectangle inner = minimize(ScreenUtil.getScreenRectangle(configuration)); if (!myInnerBounds.equals(inner)) { myInnerBounds.setBounds(inner); updated = true; } return updated; } } private static final class ScreenView extends JComponent { private final ArrayList<ScreenInfo> myScreenList = new ArrayList<>(); private final Rectangle myBounds = new Rectangle(); private boolean update() { boolean updated = false; GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); while (devices.length > myScreenList.size()) { myScreenList.add(new ScreenInfo()); updated = true; } while (devices.length < myScreenList.size()) { myScreenList.remove(devices.length); updated = true; } for (int i = 0; i < devices.length; i++) { if (myScreenList.get(i).update(devices[i].getDefaultConfiguration())) { updated = true; } } if (updated) { int minX = 0; int maxX = 0; int minY = 0; int maxY = 0; for (ScreenInfo info : myScreenList) { int x = info.myOuterBounds.x; if (minX > x) { minX = x; } x += info.myOuterBounds.width; if (maxX < x) { maxX = x; } int y = info.myOuterBounds.y; if (minY > y) { minY = y; } y += info.myOuterBounds.height; if (maxY < y) { maxY = y; } } myBounds.setBounds(minX, minY, maxX - minX, maxY - minY); } return updated; } @Override protected void paintComponent(Graphics g) { if (update()) { setPreferredSize(myBounds.getSize()); setMinimumSize(myBounds.getSize()); revalidate(); repaint(); } g = g.create(); if (g instanceof Graphics2D) { UISettings.setupAntialiasing(g); } for (int i = 0; i < myScreenList.size(); i++) { ScreenInfo info = myScreenList.get(i); Rectangle bounds = info.myOuterBounds; int x = bounds.x - myBounds.x + getX(); int y = bounds.y - myBounds.y + getY(); g.setColor(JBColor.BLUE); g.fillRect(x, y, bounds.width, bounds.height); bounds = info.myInnerBounds; x = bounds.x - myBounds.x + getX(); y = bounds.y - myBounds.y + getY(); g.setColor(JBColor.BLACK); g.fillRect(x, y, bounds.width, bounds.height); String id = String.valueOf(i + 1); int size = Math.min(bounds.width << 1, bounds.height); g.setColor(JBColor.WHITE); g.setFont(new Font("Monospaced", Font.BOLD, size)); FontMetrics fm = g.getFontMetrics(); x += (bounds.width - fm.stringWidth(id)) / 2; y += (bounds.height - fm.getHeight()) / 2; g.drawString(id, x, y + size); } g.dispose(); } } }