2003/09/19 05:26:47
[org.ibex.core.git] / src / org / xwt / Surface.java
index 082bb8b..5f44098 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL]
+// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
 package org.xwt;
 
 import org.bouncycastle.util.encoders.Base64;
@@ -51,9 +51,6 @@ public abstract class Surface {
     /** true iff all surfaces created from now on should be scarred */
     public static boolean scarAllSurfacesFromNowOn = false;
 
-
-    // Public Members and State Variables /////////////////////////////////////////////////////////
-
     /** false if the surface has never been rendered; used to determine if the surface should be repositioned to be centered on the screen */
     public boolean centerSurfaceOnRender = true;
 
@@ -74,18 +71,15 @@ public abstract class Surface {
      */
     public String cursor = "default";
 
-    /** The width of the surface's drawable area, in real time */
-    public int width = 0;
-
-    /** The height of the surface's drawable area, in real time */
-    public int height = 0;
-
     /** The Box at the root of this surface */
     public Box root;
 
     /** The number of SizeChange/PosChange traps triggered since the last successful render -- used to detect infinite loops */
     public int sizePosChangesSinceLastRender = 0;
 
+
+    // Used For Simulating Clicks and DoubleClicks /////////////////////////////////////////////////
+
     /** the x-position of the mouse the last time a Press message was enqueued */
     int last_press_x = Integer.MAX_VALUE;
 
@@ -124,6 +118,7 @@ public abstract class Surface {
 
     /** Sets the surface's x and y position. */
     public abstract void setLocation(int x, int y);
+    public void setLocation() { setLocation(root.x, root.y); }
 
     /** Sets the surface's title bar text, if applicable */
     public abstract void setTitleBarText(String s);
@@ -132,7 +127,7 @@ public abstract class Surface {
     public abstract void setIcon(Picture i);
 
     /** copies a region from the doublebuffer to this surface */
-    public abstract void blit(DoubleBuffer source, int sx, int sy, int dx, int dy, int dx2, int dy2);
+    public abstract void blit(PixelBuffer source, int sx, int sy, int dx, int dy, int dx2, int dy2);
 
     /** Destroy the surface */
     public abstract void _dispose();
@@ -221,7 +216,7 @@ public abstract class Surface {
             outer: for(int i=0; i<keywatchers.size(); i++) {
                 Box b = (Box)keywatchers.elementAt(i);
                 for(Box cur = b; cur != null; cur = cur.getParent())
-                    if (cur.invisible) continue outer;
+                    if ((cur.flags & cur.INVISIBLE_FLAG) != 0) continue outer;
                 b.put("KeyPressed", key);
             }
             Platform.clipboardReadEnabled = false;
@@ -238,7 +233,7 @@ public abstract class Surface {
             outer: for(int i=0; i<keywatchers.size(); i++) {
                 Box b = (Box)keywatchers.elementAt(i);
                 for(Box cur = b; cur != null; cur = cur.getParent())
-                    if (cur.invisible) continue outer;
+                    if ((cur.flags & cur.INVISIBLE_FLAG) != 0) continue outer;
                 b.put("KeyReleased", key);
             }
         }});
@@ -275,20 +270,21 @@ public abstract class Surface {
         }});
     }
 
-    protected final void SizeChange(int width, int height) {
-        this.width = width;
-        this.height = height;
+    protected final void SizeChange(final int width, final int height) {
+        MessageQueue.add(new Message() { public void perform() {
+            if (width == root.width && height == root.height) return;
+            root.width = width;
+            root.height = height;
+            root.needs_reflow = true;
+        }});
         abort = true;
-        long lastResizeTime = System.currentTimeMillis();
-        lastResizeTimeTop = (int)(lastResizeTime >> 32);
-        lastResizeTimeBottom = (int)(lastResizeTime & 0xffffffff);
-        Refresh();
     }
 
-    protected final void PosChange(int x, int y) {
-        if (x != root.x) root.put("x", new Integer(x));
-        if (y != root.y) root.put("y", new Integer(y));
-        new SimpleMessage("PosChange", Boolean.TRUE, root);
+    protected final void PosChange(final int x, final int y) {
+        MessageQueue.add(new Message() { public void perform() {
+            root.put("x", new Integer(x));
+            root.put("y", new Integer(y));
+        }});
     }
 
     protected final void Close() { new SimpleMessage("Close", Boolean.TRUE, root); }
@@ -299,14 +295,8 @@ public abstract class Surface {
 
     // the following value is split into two int's to work around GCJ bug java/6393
 
-    /** used in conjunction with Platform.supressDirtyOnResize() */
-    private int lastResizeTimeTop = 0;
-    private int lastResizeTimeBottom = 0;
-
     /** This is how subclasses signal a 'shallow dirty', indicating that although the backbuffer is valid, the screen is not */
     public final void Dirty(int x, int y, int w, int h) {
-        long lastResizeTime = (((long)lastResizeTimeTop) << 32) | (long)lastResizeTimeBottom;
-        if (Platform.supressDirtyOnResize() && System.currentTimeMillis() - lastResizeTime < 100 && (w >= width - 1 || h >= height - 1)) return;
         screenDirtyRegions.dirty(x, y, w, h);
         Refresh();
     }
@@ -315,7 +305,7 @@ public abstract class Surface {
     // Private Instance Data /////////////////////////////////////////////////////////////////////////////////////////////
 
     /** The automatic double buffer for the root box */
-    DoubleBuffer backbuffer = null;
+    PixelBuffer backbuffer = null;
 
     /** Dirty regions on the backbuffer which need to be rebuilt using Box.render() */
     private DirtyList backbufferDirtyRegions = new DirtyList();
@@ -330,10 +320,10 @@ public abstract class Surface {
     static volatile boolean abort = false;
 
     /** a solid red 10x10 double buffer */
-    private DoubleBuffer showRenderBuf = null;
+    private PixelBuffer showRenderBuf = null;
 
     /** a striped 100x100 double buffer */
-    private DoubleBuffer showRenderBuf2 = null;
+    private PixelBuffer showRenderBuf2 = null;
 
     /** true iff this window should be scarred */
     private boolean scarred = true;
@@ -356,17 +346,16 @@ public abstract class Surface {
     }
 
     /** wrapper for setSize() which makes sure to dirty the place where the scar used to be */
-    void _setSize(int width, int height) {
+    void setSize() {
         if (scarred) {
-            width = Math.max(width, scarPicture.getWidth());
-            height = Math.max(height, scarPicture.getHeight());
+            root.width = Math.max(root.width, scarPicture.getWidth());
+            root.height = Math.max(root.height, scarPicture.getHeight());
             dirty(hscar,
                   root.height - vscar - scarPicture.getHeight(),
-                  scarPicture.getWidth(), scarPicture.getHeight());
+                  scarPicture.getWidth(),
+                  scarPicture.getHeight());
         }
-        setSize(width, height);
-        this.width = width;
-        this.height = height;
+        setSize(root.width, root.height);
     }
 
     /** Indicates that the Surface is no longer needed */
@@ -388,7 +377,6 @@ public abstract class Surface {
 
     /** Indicates that the backbuffer region x,y,w,h is no longer correct and must be regenerated */
     public void dirty(int x, int y, int w, int h) {
-        x = 0; y = 0; w = 1000; h = 1000;
         backbufferDirtyRegions.dirty(x, y, w, h);
         Refresh();
     }
@@ -411,7 +399,7 @@ public abstract class Surface {
         } while(abort);
 
         // this is a bit dangerous since we're passing ourselves to another method before subclasses' ctors have run...        
-        backbuffer = Platform.createDoubleBuffer(Platform.getScreenWidth(), Platform.getScreenHeight(), this);
+        backbuffer = Platform.createPixelBuffer(Platform.getScreenWidth(), Platform.getScreenHeight(), this);
 
         root.dirty();
         Refresh();
@@ -420,22 +408,6 @@ public abstract class Surface {
     /** runs the prerender() and render() pipelines in the root Box to regenerate the backbuffer, then blits it to the screen */
     public synchronized void render() {
 
-        // if the window size changed as a result of a user action, we have to update the root box's size
-        if (root.width != width || root.height != height) {
-
-            // since the scar will be moving, dirty the place it used to be
-            if (scarred) dirty(hscar,
-                               root.height - vscar - scarPicture.getHeight(),
-                               scarPicture.getWidth(), scarPicture.getHeight());
-
-            // sort of ugly; we can't use set() here because it will cause an infinite mutual recursion
-            root.width = (int)width;
-            root.height = (int)height;
-
-            root.needs_reflow = true;
-            root.put("SizeChange", Boolean.TRUE);
-        }
-
         // make sure the root is properly sized
         do {
             abort = false;
@@ -449,8 +421,8 @@ public abstract class Surface {
 
         if (centerSurfaceOnRender) {
             centerSurfaceOnRender = false;
-            int x = (Platform.getScreenWidth() - width) / 2;
-            int y = (Platform.getScreenHeight() - height) / 2;
+            int x = (Platform.getScreenWidth() - root.width) / 2;
+            int y = (Platform.getScreenHeight() - root.height) / 2;
             setLocation(x, y);
             root.x = x;
             root.y = y;
@@ -466,25 +438,25 @@ public abstract class Surface {
             int h = dirt[i][3];
             if (x < 0) x = 0;
             if (y < 0) y = 0;
-            if (x+w > width) w = width - x;
-            if (y+h > height) h = height - y;
+            if (x+w > root.width) w = root.width - x;
+            if (y+h > root.height) h = root.height - y;
             if (w <= 0 || h <= 0) continue;
 
-            root.render(x, y, w, h, backbuffer);
+            root.render(0, 0, x, y, w, h, backbuffer);
             
             // if any area under the scar was repainted, rescar that area
             if (scarred && x < hscar + scarPicture.getWidth() &&
-                y + h > height - scarPicture.getHeight() - vscar) {
+                y + h > root.height - scarPicture.getHeight() - vscar) {
                 int _x1 = Math.max(x, hscar);
                 int _x2 = Math.min(x + w, hscar + scarPicture.getWidth());
-                int _y1 = Math.max(y, height - scarPicture.getHeight() - vscar);
-                int _y2 = Math.min(y + h, height - vscar);
+                int _y1 = Math.max(y, root.height - scarPicture.getHeight() - vscar);
+                int _y2 = Math.min(y + h, root.height - vscar);
                 
                 backbuffer.drawPicture(scarPicture, _x1, _y1, _x2, _y2,
                                        _x1 - (hscar),
-                                       _y1 - (height - scarPicture.getHeight() - vscar),
+                                       _y1 - (root.height - scarPicture.getHeight() - vscar),
                                        _x2 - (hscar),
-                                       _y2 - (height - scarPicture.getHeight() - vscar)
+                                       _y2 - (root.height - scarPicture.getHeight() - vscar)
                                        );
             }
 
@@ -520,7 +492,7 @@ public abstract class Surface {
 
         int[][] dirt = screenDirtyRegions.flush();
         if (Main.showRenders && dirt != null && dirt.length > 0 && a == -1)
-            blit(backbuffer, 0, 0, 0, 0, width, height);
+            blit(backbuffer, 0, 0, 0, 0, root.width, root.height);
 
         for(int i = 0; dirt != null && i < dirt.length; i++) {
             if (dirt[i] == null) continue;
@@ -546,9 +518,9 @@ public abstract class Surface {
             
             if (Main.showRenders) {
                 if (showRenderBuf == null) {
-                    showRenderBuf = Platform.createDoubleBuffer(10, 10, this);
+                    showRenderBuf = Platform.createPixelBuffer(10, 10, this);
                     showRenderBuf.fillRect(0, 0, 10, 10, 0x00FF0000);
-                    showRenderBuf2 = Platform.createDoubleBuffer(100, 100, this);
+                    showRenderBuf2 = Platform.createPixelBuffer(100, 100, this);
                     for(int y1 = 0; y1<100; y1++)
                         for(int x1 = 0; x1<100; x1++)
                             if ((x1 + y1) % 5 == 0)