// Copyright 2004 Adam Megacz, see the COPYING file for licensing [LGPL] package org.ibex.plat; import org.ibex.util.*; import java.util.*; import org.ibex.js.*; import org.ibex.graphics.*; import org.ibex.core.*; import org.ibex.net.*; /** Platform specific code for GCJ-compiled Win32 binaries */ public class Win32 extends GCJ { // Initialization //////////////////////////////////////////////////////////////////////////// // Win32 often asks for a DC/Handle when it doesn't really need one static int desktop_handle = 0; static int desktop_dc = 0; // Cursors static int wait_cursor = 0; static int default_cursor = 0; static int crosshair_cursor = 0; static int text_cursor = 0; static int move_cursor = 0; static int sizenesw_cursor = 0; static int sizens_cursor = 0; static int sizenwse_cursor = 0; static int sizewe_cursor = 0; static int hand_cursor = 0; /** reverse lookup from hwnd to Win32Surface */ public static Hashtable hwndToWin32SurfaceMap = new Hashtable(); /** lets us know that natInit() is finished */ public static Semaphore messagePumpStarted = new Semaphore(); /** ThreadId of the message pump thread, used to send it messages */ public static int messagePumpThread = 0; public static native String getTempPath(); public static native void natInit(); public static native void natPreInit(); protected native String _fileDialog(String suggestedFileName, boolean write); public Win32() { natPreInit(); } public void postInit() { new Thread() { public void run() { natInit(); } }.start(); messagePumpStarted.block(); } // Implementation of Platform methods ///////////////////////////////////////////////////////// protected native String _getEnv(String key); protected boolean _needsAutoClick() { return true; } protected String getDescriptiveName() { return "GCJ Win32 Binary"; } protected Surface _createSurface(Box b, boolean framed) { return new Win32Surface(b, framed); } protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) { return new Win32PixelBuffer(w, h, (Win32Surface)owner); } protected Picture _createPicture(JS r) { return new Win32Picture(r); } protected native int _getScreenWidth(); protected native int _getScreenHeight(); protected boolean _supressDirtyOnResize() { return false; } protected native void _criticalAbort(String message); protected native String _getClipBoard(); protected native void _setClipBoard(String s); protected boolean _isCaseSensitive() { return false; } private native void __detectProxy(String[] container); protected synchronized HTTP.Proxy _detectProxy() { String[] container = new String[] { null, null, null }; if (Log.on) Log.info(this, "accessing Win32 registry"); __detectProxy(container); if (container[2] == null && container[0] == null) { if (Log.on) Log.info(this, "no proxy settings in the Win32 registry"); return null; } if (Log.on) Log.info(this, "PAC Script URL: " + container[2]); if (Log.on) Log.info(this, "Proxy Server String: " + container[0]); if (Log.on) Log.info(this, "Proxy Override String: " + container[1]); HTTP.Proxy ret = new HTTP.Proxy(); if (container[2] != null) { // FIXME //ret.proxyAutoConfigFunction = HTTP.Proxy.getProxyAutoConfigFunction(container[2]); //if (ret.proxyAutoConfigFunction != null) return ret; } if (container[0] == null) return null; StringTokenizer st = new StringTokenizer(container[0], ";", false); while(st.hasMoreTokens()) try { String s = st.nextToken().trim(); String protocol, host; if (s.indexOf(':') == -1) { continue; } else if (s.indexOf("://") != -1) { protocol = s.substring(0, s.indexOf("://")); s = s.substring(s.indexOf("://") + 3); host = s.substring(0, s.indexOf(':')); } else if (s.indexOf('=') == -1) { protocol = "http"; host = s.substring(0, s.indexOf(':')); } else { protocol = s.substring(0, s.indexOf('=')); host = s.substring(s.indexOf('=') + 1, s.indexOf(':')); } int port = Integer.parseInt(s.substring(s.indexOf(':') + 1)); if (protocol.equals("http")) { ret.httpProxyHost = host; ret.httpProxyPort = port; } else if (protocol.equals("https")) { ret.httpsProxyHost = host; ret.httpsProxyPort = port; } else if (protocol.equals("socks")) { ret.socksProxyHost = host; ret.socksProxyPort = port; } } catch (NumberFormatException nfe) { } if (container[1] != null) { st = new StringTokenizer(container[1], ";", false); ret.excluded = new String[st.countTokens()]; for(int i=0; st.hasMoreTokens(); i++) ret.excluded[i] = st.nextToken(); } return ret; } protected native boolean _newBrowserWindow_(String url); protected void _newBrowserWindow(String url) { if (!_newBrowserWindow_(url)) if (Log.on) Log.info(this, "ShellExecuteEx() failed trying to open url " + url); } // Win32Surface //////////////////////////////////////////////////////////////////////////// public static class Win32Surface extends Surface { public PixelBuffer getPixelBuffer() { return null; } // FIXME // hack String cursor; /** used to block while waiting for the message pump thread to create a hwnd for us */ public Semaphore hwndCreated = new Semaphore(); /** nothing more than a method version of WndProc, so we can access instance members/methods */ public native int WndProc(int hwnd, int imsg, int wparam, int lparam); /** true iff the mouse is inside this window; used to determine if we should capture the mouse */ boolean inside = false; /** true iff we have 'captured' the mouse with SetCapture() */ boolean captured = false; public int hwnd = -1; public int hdc = 0; public int current_cursor = default_cursor; /** used to restore the cursor immediately before ReleaseCapture() */ public int previous_cursor = 0; public native void natInit(boolean framed); public Win32Surface(Box b, final boolean framed) { super(b); natInit(framed); hwndToWin32SurfaceMap.put(new Integer(hwnd), this); } public void syncCursor() { if (cursor.equals("default")) current_cursor = default_cursor; else if (cursor.equals("wait")) current_cursor = wait_cursor; else if (cursor.equals("crosshair")) current_cursor = crosshair_cursor; else if (cursor.equals("text")) current_cursor = text_cursor; else if (cursor.equals("move")) current_cursor = move_cursor; else if (cursor.equals("hand")) current_cursor = hand_cursor; else if (cursor.equals("east") || cursor.equals("west")) current_cursor = sizewe_cursor; else if (cursor.equals("north") || cursor.equals("south")) current_cursor = sizens_cursor; else if (cursor.equals("northwest") || cursor.equals("southeast")) current_cursor = sizenwse_cursor; else if (cursor.equals("northeast") || cursor.equals("southwest")) current_cursor = sizenesw_cursor; postCursorChange(); } public native void finalize(); public native void postCursorChange(); public native void toBack(); public native void toFront(); public native void _setMinimized(boolean m); public native void setInvisible(boolean i); public native void _setMaximized(boolean m); public native void _setSize(int w, int h); public native void setLocation(); public native void setTitleBarText(String s); public native void setIcon(Picture p); public native void _dispose(); public native void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2); } // Win32Picture //////////////////////////////////////////////////////////////////////////// public static class Win32Picture extends Picture { /** the Win32 bitmap version of this Picture */ int hbitmap = -1; /** dc of the bitmap */ int hdc = -1; /** true iff this Picture has translucent regions */ boolean hasalpha = false; /** true iff this Picture has transparent regions but no translucent regions */ boolean hasmask = true; /** if hasmask, this mask indicates which regions are transparent */ int hmask = -1; /** dc of the mask */ int maskdc = -1; public Win32Picture(JS r) { super(r); } public int getWidth() { return width; }; public int getHeight() { return height; }; public int[] getData() { return data; } boolean initialized = false; public void init() { if (!initialized && isLoaded) natInit(); initialized = true; } public native void natInit(); } // Win32PixelBuffer ////////////////////////////////////////////////////////////////////////// public static class Win32PixelBuffer implements PixelBuffer { public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int argb) { throw new Error("not implemented"); } public void drawPicture(Picture p, Affine a, Mesh h) { throw new Error("drawPicture() not implemented"); } public void drawGlyph(Font.Glyph source,Affine a,Mesh h,int rgb,int bg) { throw new Error("drawGlyph() not implemented"); } public void drawLine(int x1, int y1, int x2, int y2, int color) { } public void drawGlyph(Font.Glyph source, int dx1, int dy1, int cx1, int cy1, int cx2, int cy2, int rgb, int pc){} public void stroke(Mesh p, int color){} public void fill(Mesh p, Paint paint){} int w = 0; int h = 0; int clipx1 = 0; int clipy1 = 0; int clipx2 = 0; int clipy2 = 0; int hdc = -1; int hbitmap = -1; public int getHeight() { return h; } public int getWidth() { return w; } public native void natInit(); public Win32PixelBuffer(int w, int h, Win32Surface owner) { this.w = w; this.h = h; clipx2 = w; clipy2 = h; natInit(); } public native void fillRect(int x, int y, int x2, int y2, int color); public void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2) { ((Win32Picture)source).init(); drawPicture(source, dx, dy, cx1, cy1, cx2, cy2, 0, false); } public void drawGlyph(Font.Glyph source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int rgb) { Win32Picture p = ((Win32Picture)((Platform.DefaultGlyph)source).getPicture()); p.init(); drawPicture(p, dx, dy, cx1, cy1, cx2, cy2, rgb, true); } public native void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int rgb, boolean alphaOnly); 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); } } } }