2002/06/04 04:46:52
[org.ibex.core.git] / src / org / xwt / plat / POSIX.java
index f331f9a..0be6ced 100644 (file)
@@ -1,15 +1,6 @@
 // Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
 package org.xwt.plat;
 
-// FIXME: protected void _newBrowserWindow(String url)
-// FIXME: When should I use RootWindow versus DefaultRootWindow?
-// FIXME: Solaris: xwt.altKeyName -> "Meta"
-// FIXME: minimize/taskbar icon
-// FIXME: 15bpp? can't assume depth/8 == bytespp
-// FIXME: check for x resource / memory leaks
-// FIXME: WM_HINTS flags: icon pixmap, icon window [[ have to wait until we have gnome/kde wm's installed ]]
-// FIXME: code-review POSIX.cc
-
 import java.awt.*;
 import java.awt.image.*;
 import gnu.gcj.RawData;
@@ -43,6 +34,7 @@ public class POSIX extends GCJ {
 
     // General Methods ///////////////////////////////////////////////////////
 
+    protected String _getAltKeyName() { return System.getProperty("os.name", "").indexOf("SunOS") != -1 ? "Meta" : "Alt"; }
     protected String[] _listFonts() { return fontList; }
     protected String getDescriptiveName() { return "GCJ Linux Binary"; }
     protected Picture _createPicture(int[] data, int w, int h) { return new POSIX.X11Picture(data, w, h); }
@@ -60,6 +52,34 @@ public class POSIX extends GCJ {
     protected native void eventThread();
     private native void natInit();
 
+    /** returns the $BROWSER environment variable, since System.getenv() is useless */
+    private static native String getBrowserEnvString();
+
+    /** spawns a process which is immune to SIGHUP */
+    private static native void spawnChildProcess(String[] command);
+
+    protected void _newBrowserWindow(String url) {
+        String browserString = getBrowserEnvString();
+        if (browserString == null) {
+            browserString = "netscape " + url;
+        } else if (browserString.indexOf("%s") != -1) {
+            browserString =
+                browserString.substring(0, browserString.indexOf("%s")) +
+                url + browserString.substring(browserString.indexOf("%s") + 2);
+        } else {
+            browserString += " " + url;
+        }
+
+        StringTokenizer st = new StringTokenizer(browserString, " ");
+        String[] cmd = new String[st.countTokens()];
+        for(int i=0; st.hasMoreTokens(); i++) {
+            cmd[i] = st.nextToken();
+            System.out.println(i + ":" + cmd[i]);
+        }
+
+        spawnChildProcess(cmd);
+    }
+
     public POSIX() { }
     public void init() {
         natInit();
@@ -77,9 +97,9 @@ public class POSIX extends GCJ {
         boolean framed = false;
         Semaphore waitForCreation = new Semaphore();
         
-        public void setIcon(Picture p) { /* FIXME */ }
-        public void setInvisible(boolean i) { /* FIXME */ }
+        public native void setInvisible(boolean i);
         public void _setMaximized(boolean m) { if (Log.on) Log.log(this, "POSIX/X11 can't maximize windows"); }
+        public native void setIcon(Picture p);
         public native void _setMinimized(boolean b);
         public native void setTitleBarText(String s);
         public native void setSize(int w, int h);
@@ -104,9 +124,13 @@ public class POSIX extends GCJ {
 
     // Our Subclass of Picture ///////////////////////////////////////////////
 
-    // FIXME: what if display server runs out of pixmap space? Think resource conservation...
-
-    /** Implements a Picture as an X11 Pixmap */
+    /**
+     *  Implements a Picture. No special X11 structure is created
+     *  unless the image has no alpha (in which case a
+     *  non-shared-pixmap DoubleBuffer is created), or all-or-nothing
+     *  alpha (in which case a non-shared-pixmap DoubleBuffer with a
+     *  stipple bitmap is created).
+     */
     public static class X11Picture implements Picture {
         
         int width;
@@ -121,21 +145,36 @@ public class POSIX extends GCJ {
             this.data = data;
             this.width = w;
             this.height = h;
+            boolean needsStipple = false;
 
             // if we have any non-0x00, non-0xFF alphas, we can't double buffer ourselves
             for(int i=0; i<w*h; i++)
-                if ((data[i] & 0xFF000000) != 0xFF000000 && (data[i] & 0xFF000000) != 0x00)
+                if ((data[i] & 0xFF000000) == 0xFF000000)
+                    needsStipple = true;
+                else if ((data[i] & 0xFF000000) != 0x00)
                     return;
 
-            X11DoubleBuffer b = new X11DoubleBuffer(w, h);
+            buildDoubleBuffer(needsStipple);
+        }
+
+        void buildDoubleBuffer(boolean needsStipple) {
+            if (doublebuf != null) return;
+            // no point in using a shared pixmap since we'll only write to this image once
+            X11DoubleBuffer b = new X11DoubleBuffer(width, height, false);
             b.drawPicture(this, 0, 0);
-            b.createStipple(this);
+            if (needsStipple) b.createStipple(this);
             doublebuf = b;
         }
 
     }
 
-    // FIXME: finalizer to free X resources
+    /**
+     *  An X11DoubleBuffer is implemented as an X11 pixmap. "Normal"
+     *  DoubleBuffers will use XShm shared pixmaps if
+     *  available. X11DoubleBuffers created to accelerate Pictures
+     *  with all-or-nothing alpha will not use shared pixmaps, however
+     *  (since they are only written to once.
+     */
     public static class X11DoubleBuffer implements DoubleBuffer {
 
         int clipx, clipy, clipw, cliph;
@@ -147,31 +186,22 @@ public class POSIX extends GCJ {
 
         /** Sets the DoubleBuffer's internal stipple to the alpha==0x00 regions of xpi */
         public native void createStipple(X11Picture xpi);
-
-        static int old_shmsize = 0;
-        static RawData shm_ximage;
-        static int shmsegs = 0;
-        int force_slowpath = 0;
-        RawData mxi = null;
-        int shared_pixmap = 0;
-
-        boolean usePixmap = false;
         
-        /** Pixmap (if any) representing this Picture */
-        RawData pm;
+        RawData pm;                    // Pixmap (if any) representing this Picture
+        boolean shared_pixmap = false; // true if pm is a ShmPixmap
+        RawData fake_ximage = null;    // a 'fake' XImage corresponding to the shared pixmap; gives us the address and depth parameters
+        RawData shm_segment = null;    // XShmSegmentInfo
 
-        /** Graphics Context on pm (never changes, so it's fast) */
-        RawData gc;
-
-        /** Graphics Context on pm, use this one if you need a clip/stipple */
-        RawData clipped_gc;
+        RawData gc;                    // Graphics Context on pm (never changes, so it's fast)
+        RawData clipped_gc;            // Graphics Context on pm, use this one if you need a clip/stipple
 
         /** DoubleBuffer mode */
-        public X11DoubleBuffer(int w, int h) {
+        public X11DoubleBuffer(int w, int h) { this(w, h, true); }
+        public X11DoubleBuffer(int w, int h, boolean shared_pixmap) {
             width = clipw = w;
             height = cliph = h;
             clipx = clipy = 0;
-            shared_pixmap = 1;
+            this.shared_pixmap = shared_pixmap;
             natInit();
         }
 
@@ -186,12 +216,25 @@ public class POSIX extends GCJ {
             drawPicture(source, x, y, x + source.getWidth(), y + source.getHeight(), 0, 0, source.getWidth(), source.getHeight());
         }
 
+        public void drawPicture(Picture source, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) {
+            if (!(dx2 - dx1 != sx2 - sx1 || dy2 - dy1 != sy2 - sy1) && ((X11Picture)source).doublebuf != null)
+                fastDrawPicture(source, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2);
+            else 
+                slowDrawPicture(source, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2);
+        }
+
+        /** fast path for image drawing (no scaling, all-or-nothing alpha) */
+        public native void fastDrawPicture(Picture source, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2);
+
+        /** slow path for image drawing */
+        public native void slowDrawPicture(Picture source, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2);
+
         public int getWidth() { return width; }
         public int getHeight() { return height; }
         public native void natInit();
-        public native void drawPicture(Picture source, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2);
         public native void fillRect(int x, int y, int x2, int y2, int color);
         public native void drawString(String font, String text, int x, int y, int color);
+        public native void finalize();
 
     }