X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fplat%2FDarwin.java;h=211c88cb3f35d1d2aa638d847cfd3233db4c08c6;hb=d5ed44dae8660a62e24b4e7d535f3ee8f8e791ed;hp=cc755d15122758e249d2c5dbd0c5a147e64de2c9;hpb=798082a9cf2856f50f91483da37b5d9661355f00;p=org.ibex.core.git diff --git a/src/org/xwt/plat/Darwin.java b/src/org/xwt/plat/Darwin.java index cc755d1..211c88c 100644 --- a/src/org/xwt/plat/Darwin.java +++ b/src/org/xwt/plat/Darwin.java @@ -1,8 +1,348 @@ -// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] +// Copyright 2004 Adam Megacz, see the COPYING file for licensing [LGPL] +// Authors: Brian Alliet and Evan Jones + package org.xwt.plat; +import gnu.gcj.RawData; +import org.xwt.util.*; +import org.xwt.js.*; import org.xwt.*; +import java.util.*; + +public class Darwin extends POSIX { + static Darwin singleton; + private CarbonOpenGL openGL; + boolean jaguar; // true if we are on OS X >= 10.2 + + // General Methods + protected String _getAltKeyName() { return "Option"; } + protected boolean _needsAutoClick() { return false; } + protected boolean _needsAutoDoubleClick() { return false; } + protected String getDescriptiveName() { return "GCJ Darwin Binary"; } + protected boolean _isCaseSensitive() { return false; /* Well, not always, could be UFS */ } + + + // Native Methods + protected int _getScreenWidth() { return cgScreenWidth(); } + protected int _getScreenHeight() { return cgScreenHeight(); } + private native static int cgScreenWidth(); + private native static int cgScreenHeight(); + protected native void _newBrowserWindow(String url); + protected native HTTP.Proxy natDetectProxy(); + private native void natInit(); + + private native String natGetClipBoard(); + private native void natSetClipBoard(String text); + protected void _setClipBoard(final String text) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetClipBoard(text); } }); } + protected String _getClipBoard() { + final Semaphore sem = new Semaphore(); + final String[] result = new String[1]; // Kind of like a pointer + CarbonMessage.add(new CarbonMessage() { public void perform() { result[0] = natGetClipBoard(); sem.release(); } }); + sem.block(); + return result[0]; + } + + private static class FileDialogHelper { + public FileDialogHelper(boolean save) { this.save = save; } + public boolean save; + public Semaphore sem = new Semaphore(); + public String fileName; + public String saveName; + } + private native void natFileDialog(FileDialogHelper helper, String suggestedFileName, boolean write); + protected String _fileDialog(final String fn, final boolean w) { + final FileDialogHelper helper = new FileDialogHelper(w); + CarbonMessage.add(new CarbonMessage() { public void perform() { natFileDialog(helper,fn,w); } }); + helper.sem.block(); + if(w) + return helper.fileName + "/" + helper.saveName; + else + return helper.fileName; + } + + + static void abort(String err) { + throw new Error(err); + } + + public Darwin() { + synchronized(Darwin.class) { + if(singleton != null) abort("Tried to instansiate Darwin more than once"); + singleton = this; + } + } + + protected synchronized HTTP.Proxy _detectProxy() { + return natDetectProxy(); + } + + private static native final boolean isJaguar(); + + public void postInit() { + jaguar = isJaguar(); + try { + openGL = new CarbonOpenGL(); + openGL.init(); + } catch(OpenGL.NotSupportedException e) { + Log.info(this,"WARNING: OpenGL support not available: " + e); + // FEATURE: fall back to quartz 2d + throw new Error("No OpenGL support"); + } + natInit(); + } + + protected Scheduler _getScheduler() { return new DarwinScheduler(); } + protected native void runApplicationEventLoop(); + private class DarwinScheduler extends org.xwt.Scheduler { + public void run() { + new Thread() { public void run() { defaultRun(); } }.start(); + runApplicationEventLoop(); + } + } + + private final class CarbonOpenGL extends OpenGL { + public RawData rawPixelFormat; + public RawData rawSharedContext; + public int maxAglSurfaceTexSize; + public int maxSurfaceWidth; + public int maxSurfaceHeight; + + private native boolean initPixelFormat(); + private native void initSharedContext(); + + public CarbonOpenGL() throws NotSupportedException { + if(!jaguar) + throw new NotSupportedException("OpenGL requires Mac OS X 10.2 or greater"); + if(!initPixelFormat()) + throw new NotSupportedException("Couldn't get an acceptable pixel format"); + initSharedContext(); + } + + public void init() throws NotSupportedException { + super.init(); + maxAglSurfaceTexSize = rectangularTextures ? maxRectTexSize : maxTexSize; + if(renderer.startsWith("ATI Radeon 7500")) { + maxAglSurfaceTexSize = Math.min(rectangularTextures ? 1600 : 1024,maxAglSurfaceTexSize); + Log.info(this,"Working around Radeon 7500 bug: maxAglSurfaceTexSize: " + maxAglSurfaceTexSize); + } + maxSurfaceWidth = maxSurfaceHeight = maxAglSurfaceTexSize; + } + protected native void activateSharedContext(); + } + + static abstract class CarbonSurface extends Surface.DoubleBufferedSurface { + RawData rawWindowRef; + int modifiers; + int winWidth; + int winHeight; + + boolean pendingResize; + + private native void natSetInvisible(boolean i); + public void setInvisible(final boolean i) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetInvisible(i); } }); } + private native void nat_setMaximized(boolean b); + public void _setMaximized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMaximized(b); } }); } + private native void nat_setMinimized(boolean b); + public void _setMinimized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMinimized(b); } }); } + private native void natSetIcon(Picture p); + public void setIcon(final Picture p) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetIcon(p); } }); } + private native void natSetTitleBarText(String s); + public void setTitleBarText(final String s) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetTitleBarText(s); } }); } + private native void natSetSize(int w, int h); + public void _setSize(final int w, final int h) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetSize(w,h); } }); } + private native void natSetLocation(); + public void setLocation() { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLocation(); } }); } + private native void natToFront(); + public void toFront() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToFront(); } }); } + private native void natToBack(); + public void toBack() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToBack(); } }); } + private native void natSetLimits(int minWidth, int minHeight, int maxWidth, int maxHeight); + public void setLimits(final int mnw, final int mnh, final int mxw, final int mxh) { + if(Darwin.singleton.jaguar) + CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLimits(mnw,mnh,mxw,mxh); } }); + } + private native void natSyncCursor(int n); + public void syncCursor() { + int n; + if(cursor.equals("default")) n = 0; + else if(cursor.equals("wait")) n = 1; + else if(cursor.equals("crosshair")) n = 2; + else if(cursor.equals("text")) n = 3; + else if(cursor.equals("hand")) n = 4; + else if(cursor.equals("move")) n = 5; + else if(cursor.equals("east") || cursor.equals("west")) n = 6; + else n = 0; + final int n_ = n; + CarbonMessage.add(new CarbonMessage() { public void perform() { natSyncCursor(n_); } }); + } + + /* Drawing stuff */ + public abstract void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2); + + public final void _dispose() { CarbonMessage.add(new CarbonMessage() { public void perform() { natDispose(); } }); } + public native void natDispose(); + + public final native void natInit(boolean framed); + + public CarbonSurface(Box root, final boolean framed) { + super(root); + final Semaphore sem = new Semaphore(); + CarbonMessage.add(new CarbonMessage() { public void perform() { CarbonSurface.this.natInit(framed); sem.release(); } }); + sem.block(); + } + + public void needsReshape() { } + protected static native void blitLock(); + protected static native void blitUnlock(); + protected static native void blitWait(); + } + + static class GLCarbonPixelBuffer extends OpenGL.GLPixelBuffer { + RawData rawCTX; + RawData rawWindowRef; + int textureName; + boolean rectTexture; + CarbonOpenGL gl; + + private native void natInit(); + private static native void natCleanup(RawData rawWindowRef, RawData rawCTX); + + + private static final int fixupDimension(CarbonOpenGL gl, int n) { + if(!gl.rectangularTextures) n = OpenGL.roundToPowerOf2(n); + return Math.min(n,gl.maxAglSurfaceTexSize); + } + public GLCarbonPixelBuffer(int w, int h, final CarbonOpenGL gl) { + super(fixupDimension(gl,w),fixupDimension(gl,h)); + this.gl = gl; + rectTexture = gl.hasRectangularTextures(); + final Semaphore sem = new Semaphore(); + CarbonMessage.add(new CarbonMessage() { public void perform() { GLCarbonPixelBuffer.this.natInit(); sem.release(); } }); + sem.block(); + } + public native void activateContext(); + protected void finalize() { + CarbonMessage.add(new CarbonMessage() { public void perform() { natCleanup(rawWindowRef,rawCTX); } }); + gl.deleteTexture(textureName); + } + } + + static class GLCarbonSurface extends CarbonSurface { + RawData rawCTX; + CarbonOpenGL gl; + boolean needsReshape; + + private final native void natInit(); + private final native void flush(); + private final native void clear(); + + public GLCarbonSurface(Box root, boolean framed, CarbonOpenGL gl) { + super(root,framed); + this.gl = gl; + natInit(); + } + + public void setLimits(int mnw,int mnh, int mxw, int mxh) { + mxw = Math.min(mxw,gl.maxSurfaceWidth); + mxh = Math.min(mxh,gl.maxSurfaceHeight); + super.setLimits(mnw,mnh,mxw,mxh); + } + + public void _setSize(int w, int h) { + w = Math.min(w,gl.maxSurfaceWidth); + h = Math.min(h,gl.maxSurfaceWidth); + super._setSize(w,h); + } + + private native void natBlit(GLCarbonPixelBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2); + public void blit(PixelBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2) { + natBlit((GLCarbonPixelBuffer)db,sx,sy,dx,dy,dx2,dy2); + } + + + // The blit_lock ensures the window size does not change through the entire blit operation. + public void render() { + /* + blitLock(); + while(pendingResize) blitWait(); + */ + if(needsReshape) { + needsReshape = false; + + reshape(winWidth,winHeight); + clear(); + Dirty(0,0,winWidth,winHeight); + } + super.render(); + flush(); + /* + blitUnlock(); + */ + } + + private native void reshape(int w, int h); + // blit_lock is assumed to be held + public void needsReshape() { needsReshape = true; } + + public native void natDispose(); + } -/** All Darwin-derived operating systems (Mac OS X, OpenDarwin) */ -public abstract class Darwin extends X11 { + /*private class QZCarbonPixelBuffer extends PixelBuffer { + + public QZCarbonPixelBuffer(int width, int height) { + } + } + private class QZCarbonSurface extends CarbonSurface { + public QZCarbonSurface(Box root, boolean framed) { + super(b,root); + } + public native void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2); + } + + private class QZCarbonPicture extends Picture { + int width; + int height; + + public final int getWidth() { return width; } + public final int getHeight() { return height; } + + public QZCarbonPicture(int w, int h) { + this.width = w; + this.height = h; + } + }*/ + + protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) { + if(openGL != null) + return new GLCarbonPixelBuffer(w,h,openGL); + else + return /*new QZCarbonPixelBuffer(w,h)*/ null; + } + protected Surface _createSurface(Box b, boolean framed) { + if(openGL != null) + return new GLCarbonSurface(b,framed, openGL); + else + return /*new QZCarbonSufrace(b,framed)*/ null; + } + protected Picture _createPicture(JS r) { + if(openGL != null) + return openGL._createPicture(r, true); + else + return /*new QZCarbonPicture(data,w,h);*/ null; + } + protected org.xwt.Font.Glyph _createGlyph(org.xwt.Font f, char c) { + if(openGL != null) + return openGL._createGlyph(f, c); + else + return super.createGlyph(f, c); + } + + /* A message that is sent through the carbon event queue */ + private static abstract class CarbonMessage { + public abstract void perform(); + + static { natInit(); } + public static native void natInit(); + public static native void add(CarbonMessage m); + } }