import java.awt.*; import java.awt.event.*; import java.awt.image.*; /** * This test checks for the following driver issue: * ATI Issue #2: Swing apps are all garbled on Linux */ public class VolatileToScreen extends Frame { private static final int TESTW = 200; private static final int TESTH = 200; private static boolean done; private static int actualW, actualH; private static volatile BufferedImage capture; // detect lower corners to exclude them from comparison // it is necessary on mac Aqua etc. private static int xCornerTolerance = 3; private static int yCornerTolerance = 3; private static boolean isLowerCorner(int x1, int y1, int x2, int y2, int x, int y) { return (x < x1+xCornerTolerance && y > y2-yCornerTolerance) || (x > x2-xCornerTolerance && y > y2-yCornerTolerance); } private static void doCapture(Frame test) { // Grab the screen region try { Robot robot = new Robot(); Point pt1 = test.getLocationOnScreen(); Rectangle rect = new Rectangle(pt1.x, pt1.y, test.getWidth(), test.getHeight()); capture = robot.createScreenCapture(rect); } catch (Exception e) { e.printStackTrace(); } } private void renderTestPattern(Graphics g, int w, int h) { g.setColor(Color.red); g.fillRect(0, 0, w, h); g.setColor(Color.blue); g.fillRect(0, 0, 10, 10); g.fillRect(w-10, 0, 10, 10); g.fillRect(w-10, h-10, 10, 10); g.fillRect(0, h-10, 10, 10); } public BufferedImage createReferenceImage(int w, int h) { BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics g = bi.createGraphics(); renderTestPattern(g, w, h); g.dispose(); return bi; } public void paint(Graphics g) { Insets insets = getInsets(); int x = insets.left; int y = insets.top; int w = getWidth() - (insets.left + insets.right); int h = getHeight() - (insets.top + insets.bottom); actualW = w; actualH = h; //System.err.println("frame width=" + getWidth()); //System.err.println("frame height=" + getHeight()); //System.err.println("insets: " + insets); g.setColor(Color.white); g.fillRect(x, y, w, h); VolatileImage img = createVolatileImage(w, h); img.validate(getGraphicsConfiguration()); Graphics2D og = img.createGraphics(); renderTestPattern(og, w, h); og.dispose(); g.drawImage(img, x, y, null); img.flush(); img = null; try{Thread.sleep(1000);}catch(Exception exx){} Toolkit.getDefaultToolkit().sync(); synchronized (this) { if (!done) { doCapture(this); done = true; } notifyAll(); } } public Dimension getPreferredSize() { return new Dimension(TESTW, TESTH); } public static void main(String[] args) { boolean show = (args.length == 1) && ("-show".equals(args[0])); VolatileToScreen test = new VolatileToScreen(); test.pack(); test.setVisible(true); // Wait until the component's been painted synchronized (test) { while (!done) { try { test.wait(); } catch (InterruptedException e) { throw new RuntimeException("Failed: Interrupted"); } } } Point pt1 = test.getLocationOnScreen(); Insets insets = test.getInsets(); int x1 = insets.left; int y1 = insets.top; int w = actualW; int h = actualH; if (!show) { test.dispose(); } if (capture == null) { throw new RuntimeException("Failed: capture is null"); } // Compare onscreen results with test pattern rendered into // a BufferedImage BufferedImage ref = test.createReferenceImage(w, h); for (int y = 0; y < ref.getHeight(); y++) { for (int x = 0; x < ref.getWidth(); x++) { if(isLowerCorner(0, 0, ref.getWidth(), ref.getHeight(), x, y)) { continue; } int expected = ref.getRGB(x, y); int actual = capture.getRGB(x1+x, y1+y); if (actual != expected) { throw new RuntimeException("Test failed at x="+x+" y="+y+ " (expected="+ Integer.toHexString(expected) + " actual="+ Integer.toHexString(actual) + ")"); } } } } }