X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fplat%2FDarwin.java;h=34030caf2e0105d24e334261ed3ccfb103bfad41;hb=c6069948906645d974f46bdb96617a9a6a504636;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..34030ca 100644 --- a/src/org/xwt/plat/Darwin.java +++ b/src/org/xwt/plat/Darwin.java @@ -1,8 +1,322 @@ -// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] +// Copyright 2003 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.*; +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 + + // TEMPORARY HACKS (remove these when we ditch platform fonts) + protected int _stringWidth(String font, String text) { return (int)Math.round(6.5 * text.length()); } + protected int _getMaxAscent(String font) { return 10; } + protected int _getMaxDescent(String font) { return 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 Proxy natDetectProxy(); + private native void natInit(); + protected native void _exit(); + + 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; + public RawData rawUPP; + } + 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; + } + + + // Called by main thread after initialization, this is the event handler + protected native void _running(); + + 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 Proxy _detectProxy() { + return natDetectProxy(); + } + + private static native final boolean isJaguar(); + private static native final void linkMe(); + + public void init() { + super.init(); + linkMe(); + jaguar = isJaguar(); + try { + openGL = new CarbonOpenGL(); + openGL.init(); + } catch(OpenGL.NotSupportedException e) { + Log.log(this,"WARNING: OpenGL support not available: " + e); + // FIXME: We need to fallback to Quartz2D + throw new Error("No OpenGL support"); + } + natInit(); + } + + 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.log(this,"Working around Radeon 7500 bug: maxAglSurfaceTexSize: " + maxAglSurfaceTexSize); + } + maxSurfaceWidth = maxSurfaceHeight = maxAglSurfaceTexSize; + } + protected native void activateSharedContext(); + } + + static abstract class CarbonSurface extends Surface { + RawData rawWindowRef; + RawData rawEventHandlerUPP; + int modifiers; + + 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(int x, int y); + public void setLocation(final int x, final int y) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLocation(x,y); } }); } + 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_); } }); + } + + public void _sizeChange(int w, int h) { SizeChange(w,h); } + + /* 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 reshape(int w, int h) { } + } + + static class GLCarbonPixelBuffer extends OpenGL.GLDoubleBuffer { + 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 sizeChange; + + private final native void natInit(); + + 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 _sizeChange(int w, int h) { + sizeChange = true; + super._sizeChange(w,h); + } + + public void setSize(int w, int h) { + sizeChange = true; + 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 synchronized 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); + } + + private native void natReshape(int w, int h); + public synchronized void reshape(int w, int h) { natReshape(w,h); } + + public native void natDispose(); + } -/** All Darwin-derived operating systems (Mac OS X, OpenDarwin) */ -public abstract class Darwin extends X11 { + /*private class QZCarbonPixelBuffer extends DoubleBuffer { + + 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 _createDoubleBuffer(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(int[] data, int w, int h) { + if(openGL != null) + return openGL.createPicture(data,w,h); + else + return /*new QZCarbonPicture(data,w,h);*/ null; + } + + /* 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); + } }