// Copyright 2004 Adam Megacz, see the COPYING file for licensing [LGPL] package org.ibex.plat; import gnu.gcj.RawData; import java.util.*; import org.ibex.js.*; import org.ibex.util.*; import org.ibex.graphics.*; import org.ibex.core.*; import org.ibex.net.*; /** Platform implementation for POSIX compliant operating systems with an X11 Server */ public class X11 extends POSIX { // Static Data /////////////////////////////////////////////////////////// /** * When the user reads from the clipboard, the main thread blocks * on this semaphore until we get an X11 SelectionNotify. Crude, * but effective. We know that only one thread will ever block on * this, since only one thread can ever be running JavaScript. */ public static Semaphore waiting_for_selection_event = new Semaphore(); /** our local (in-process) copy of the clipboard */ public static String clipboard = null; /** map from Window's (casted to jlong, wrapped in java.lang.Long) to X11Surface objects */ public static Hashtable windowToSurfaceMap = new Hashtable(); // General Methods /////////////////////////////////////////////////////// protected String _getAltKeyName() { return System.getProperty("os.name", "").indexOf("SunOS") != -1 ? "Meta" : "Alt"; } protected Picture _createPicture(JS r) { return new X11Picture(r); } protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) { return new X11PixelBuffer(w, h); } protected Surface _createSurface(Box b, boolean framed) { return new X11Surface(b, framed); } protected boolean _needsAutoClick() { return true; } protected native int _getScreenWidth(); protected native int _getScreenHeight(); protected native String _getClipBoard(); protected native void _setClipBoard(String s); protected boolean _needsAutoDoubleClick() { return true; } protected native String _fileDialog(String suggestedFileName, boolean write); protected native void eventThread(); private native void natInit(); public void postInit() { natInit(); (new Thread() { public void run() { eventThread(); } }).start(); } // X11Surface ///////////////////////////////////////////////////// /** Implements a Surface as an X11 Window */ public static class X11Surface extends Surface { public PixelBuffer getPixelBuffer() { return null; } // FIXME gnu.gcj.RawData window; gnu.gcj.RawData gc; boolean framed = false; Semaphore waitForCreation = new Semaphore(); public native void setInvisible(boolean i); public void _setMaximized(boolean m) { if (Log.on) Log.warn(this, "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); public native void setLocation(); public native void natInit(); public native void toFront(); public native void toBack(); public native void syncCursor(); public native void _dispose(); public native void setLimits(int minw, int minh, int maxw, int maxh); public native void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2); public native void dispatchEvent(gnu.gcj.RawData ev); public void setMinimumSize(int minx, int miny, boolean resizable) { setLimits(minx, miny, resizable ? Short.MAX_VALUE : minx, resizable ? Short.MAX_VALUE : miny); } public X11Surface(Box root, boolean framed) { super(root); this.framed = framed; natInit(); } } // Our Subclass of Picture /////////////////////////////////////////////// /** * Implements a Picture. No special X11 structure is created * unless the image has no alpha (in which case a * non-shared-pixmap PixelBuffer is created), or all-or-nothing * alpha (in which case a non-shared-pixmap PixelBuffer with a * stipple bitmap is created). */ public static class X11Picture extends Picture { public X11PixelBuffer doublebuf = null; public int getWidth() { return width; } public int getHeight() { return height; } boolean initialized = false; public X11Picture(JS r) { super(r); } public void init() { if (initialized) return; initialized = true; boolean needsStipple = false; // if we have any non-0x00, non-0xFF alphas, we can't double buffer ourselves for(int i=0; i= cx2 || cy1 >= cy2) return; X11Picture pic = (X11Picture)((Platform.DefaultGlyph)source).getPicture(); pic.init(); slowDrawPicture(pic, dx, dy, cx1, cy1, cx2, cy2, rgb, true); } public void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2) { cx1 = Math.max(dx, cx1); cy1 = Math.max(dy, cy1); cx2 = Math.min(dx + source.width, cx2); cy2 = Math.min(dy + source.height, cy2); if (cx1 >= cx2 || cy1 >= cy2) return; ((X11Picture)source).init(); if (((X11Picture)source).doublebuf != null) fastDrawPicture(source, dx, dy, cx1, cy1, cx2, cy2); else slowDrawPicture(source, dx, dy, cx1, cy1, cx2, cy2, 0, false); } /** fast path for image drawing (no scaling, all-or-nothing alpha) */ public native void fastDrawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2); /** slow path for image drawing */ public native void slowDrawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int rgb, boolean alphaOnly); public int getWidth() { return width; } public int getHeight() { return height; } public native void natInit(); public native void fillRect(int x, int y, int x2, int y2, int color); public native void finalize(); // FIXME: try to use os acceleration public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) { if (x1 == x3 && x2 == x4) { fillRect(x1, y1, x4, y2, argb); } else for(int y=y1; y _x2) { int _x0 = _x1; _x1 = _x2; _x2 = _x0; } fillRect(_x1, _y1, _x2, _y2, argb); } } } }