1 // Copyright 2003 Adam Megacz, see the COPYING file for licensing [LGPL]
2 // Authors: Brian Alliet and Evan Jones
6 import gnu.gcj.RawData;
11 public class Darwin extends POSIX {
12 static Darwin singleton;
13 private CarbonOpenGL openGL;
14 boolean jaguar; // true if we are on OS X >= 10.2
17 protected String _getAltKeyName() { return "Option"; }
18 protected boolean _needsAutoClick() { return false; }
19 protected boolean _needsAutoDoubleClick() { return false; }
20 protected String getDescriptiveName() { return "GCJ Darwin Binary"; }
21 protected boolean _isCaseSensitive() { return false; /* Well, not always, could be UFS */ }
25 protected int _getScreenWidth() { return cgScreenWidth(); }
26 protected int _getScreenHeight() { return cgScreenHeight(); }
27 private native static int cgScreenWidth();
28 private native static int cgScreenHeight();
29 protected native void _newBrowserWindow(String url);
30 protected native HTTP.Proxy natDetectProxy();
31 private native void natInit();
33 private native String natGetClipBoard();
34 private native void natSetClipBoard(String text);
35 protected void _setClipBoard(final String text) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetClipBoard(text); } }); }
36 protected String _getClipBoard() {
37 final Semaphore sem = new Semaphore();
38 final String[] result = new String[1]; // Kind of like a pointer
39 CarbonMessage.add(new CarbonMessage() { public void perform() { result[0] = natGetClipBoard(); sem.release(); } });
44 private static class FileDialogHelper {
45 public FileDialogHelper(boolean save) { this.save = save; }
47 public Semaphore sem = new Semaphore();
48 public String fileName;
49 public String saveName;
51 private native void natFileDialog(FileDialogHelper helper, String suggestedFileName, boolean write);
52 protected String _fileDialog(final String fn, final boolean w) {
53 final FileDialogHelper helper = new FileDialogHelper(w);
54 CarbonMessage.add(new CarbonMessage() { public void perform() { natFileDialog(helper,fn,w); } });
57 return helper.fileName + "/" + helper.saveName;
59 return helper.fileName;
63 static void abort(String err) {
68 synchronized(Darwin.class) {
69 if(singleton != null) abort("Tried to instansiate Darwin more than once");
74 protected synchronized HTTP.Proxy _detectProxy() {
75 return natDetectProxy();
78 private static native final boolean isJaguar();
80 // Called by main thread after initialization, this is the event handler
81 protected native void runApplicationEventLoop();
87 openGL = new CarbonOpenGL();
89 } catch(OpenGL.NotSupportedException e) {
90 Log.log(this,"WARNING: OpenGL support not available: " + e);
91 // FEATURE: fall back to quartz 2d
92 throw new Error("No OpenGL support");
97 public void _running() { runApplicationEventLoop(); }
99 private final class CarbonOpenGL extends OpenGL {
100 public RawData rawPixelFormat;
101 public RawData rawSharedInterpreter;
102 public int maxAglSurfaceTexSize;
103 public int maxSurfaceWidth;
104 public int maxSurfaceHeight;
106 private native boolean initPixelFormat();
107 private native void initSharedInterpreter();
109 public CarbonOpenGL() throws NotSupportedException {
111 throw new NotSupportedException("OpenGL requires Mac OS X 10.2 or greater");
112 if(!initPixelFormat())
113 throw new NotSupportedException("Couldn't get an acceptable pixel format");
114 initSharedInterpreter();
117 public void init() throws NotSupportedException {
119 maxAglSurfaceTexSize = rectangularTextures ? maxRectTexSize : maxTexSize;
120 if(renderer.startsWith("ATI Radeon 7500")) {
121 maxAglSurfaceTexSize = Math.min(rectangularTextures ? 1600 : 1024,maxAglSurfaceTexSize);
122 Log.log(this,"Working around Radeon 7500 bug: maxAglSurfaceTexSize: " + maxAglSurfaceTexSize);
124 maxSurfaceWidth = maxSurfaceHeight = maxAglSurfaceTexSize;
126 protected native void activateSharedInterpreter();
129 static abstract class CarbonSurface extends Surface.DoubleBufferedSurface {
130 RawData rawWindowRef;
135 boolean pendingResize;
137 private native void natSetInvisible(boolean i);
138 public void setInvisible(final boolean i) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetInvisible(i); } }); }
139 private native void nat_setMaximized(boolean b);
140 public void _setMaximized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMaximized(b); } }); }
141 private native void nat_setMinimized(boolean b);
142 public void _setMinimized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMinimized(b); } }); }
143 private native void natSetIcon(Picture p);
144 public void setIcon(final Picture p) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetIcon(p); } }); }
145 private native void natSetTitleBarText(String s);
146 public void setTitleBarText(final String s) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetTitleBarText(s); } }); }
147 private native void natSetSize(int w, int h);
148 public void _setSize(final int w, final int h) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetSize(w,h); } }); }
149 private native void natSetLocation();
150 public void setLocation() { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLocation(); } }); }
151 private native void natToFront();
152 public void toFront() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToFront(); } }); }
153 private native void natToBack();
154 public void toBack() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToBack(); } }); }
155 private native void natSetLimits(int minWidth, int minHeight, int maxWidth, int maxHeight);
156 public void setLimits(final int mnw, final int mnh, final int mxw, final int mxh) {
157 if(Darwin.singleton.jaguar)
158 CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLimits(mnw,mnh,mxw,mxh); } });
160 private native void natSyncCursor(int n);
161 public void syncCursor() {
163 if(cursor.equals("default")) n = 0;
164 else if(cursor.equals("wait")) n = 1;
165 else if(cursor.equals("crosshair")) n = 2;
166 else if(cursor.equals("text")) n = 3;
167 else if(cursor.equals("hand")) n = 4;
168 else if(cursor.equals("move")) n = 5;
169 else if(cursor.equals("east") || cursor.equals("west")) n = 6;
172 CarbonMessage.add(new CarbonMessage() { public void perform() { natSyncCursor(n_); } });
176 public abstract void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
178 public final void _dispose() { CarbonMessage.add(new CarbonMessage() { public void perform() { natDispose(); } }); }
179 public native void natDispose();
181 public final native void natInit(boolean framed);
183 public CarbonSurface(Box root, final boolean framed) {
185 final Semaphore sem = new Semaphore();
186 CarbonMessage.add(new CarbonMessage() { public void perform() { CarbonSurface.this.natInit(framed); sem.release(); } });
190 public void needsReshape() { }
191 protected static native void blitLock();
192 protected static native void blitUnlock();
193 protected static native void blitWait();
196 static class GLCarbonPixelBuffer extends OpenGL.GLPixelBuffer {
198 RawData rawWindowRef;
203 private native void natInit();
204 private static native void natCleanup(RawData rawWindowRef, RawData rawCTX);
207 private static final int fixupDimension(CarbonOpenGL gl, int n) {
208 if(!gl.rectangularTextures) n = OpenGL.roundToPowerOf2(n);
209 return Math.min(n,gl.maxAglSurfaceTexSize);
211 public GLCarbonPixelBuffer(int w, int h, final CarbonOpenGL gl) {
212 super(fixupDimension(gl,w),fixupDimension(gl,h));
214 rectTexture = gl.hasRectangularTextures();
215 final Semaphore sem = new Semaphore();
216 CarbonMessage.add(new CarbonMessage() { public void perform() { GLCarbonPixelBuffer.this.natInit(); sem.release(); } });
219 public native void activateInterpreter();
220 protected void finalize() {
221 CarbonMessage.add(new CarbonMessage() { public void perform() { natCleanup(rawWindowRef,rawCTX); } });
222 gl.deleteTexture(textureName);
226 static class GLCarbonSurface extends CarbonSurface {
229 boolean needsReshape;
231 private final native void natInit();
232 private final native void flush();
233 private final native void clear();
235 public GLCarbonSurface(Box root, boolean framed, CarbonOpenGL gl) {
241 public void setLimits(int mnw,int mnh, int mxw, int mxh) {
242 mxw = Math.min(mxw,gl.maxSurfaceWidth);
243 mxh = Math.min(mxh,gl.maxSurfaceHeight);
244 super.setLimits(mnw,mnh,mxw,mxh);
247 public void _setSize(int w, int h) {
248 w = Math.min(w,gl.maxSurfaceWidth);
249 h = Math.min(h,gl.maxSurfaceWidth);
253 private native void natBlit(GLCarbonPixelBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2);
254 public void blit(PixelBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2) {
255 natBlit((GLCarbonPixelBuffer)db,sx,sy,dx,dy,dx2,dy2);
259 // The blit_lock ensures the window size does not change through the entire blit operation.
260 public void render_() {
262 while(pendingResize) blitWait();
264 needsReshape = false;
266 reshape(winWidth,winHeight);
268 Dirty(0,0,getWidth(),getHeight());
275 private native void reshape(int w, int h);
276 // blit_lock is assumed to be held
277 public void needsReshape() { needsReshape = true; }
279 public native void natDispose();
282 /*private class QZCarbonPixelBuffer extends PixelBuffer {
284 public QZCarbonPixelBuffer(int width, int height) {
287 private class QZCarbonSurface extends CarbonSurface {
288 public QZCarbonSurface(Box root, boolean framed) {
291 public native void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
294 private class QZCarbonPicture extends Picture {
298 public final int getWidth() { return width; }
299 public final int getHeight() { return height; }
301 public QZCarbonPicture(int w, int h) {
307 protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) {
309 return new GLCarbonPixelBuffer(w,h,openGL);
311 return /*new QZCarbonPixelBuffer(w,h)*/ null;
313 protected Surface _createSurface(Box b, boolean framed) {
315 return new GLCarbonSurface(b,framed, openGL);
317 return /*new QZCarbonSufrace(b,framed)*/ null;
319 protected Picture _createPicture(int[] data, int w, int h) {
321 return openGL.createPicture(data,w,h);
323 return /*new QZCarbonPicture(data,w,h);*/ null;
325 protected Picture _createAlphaOnlyPicture(byte[] data, int w, int h) {
327 return openGL.createAlphaOnlyPicture(data,w,h);
329 return super.createAlphaOnlyPicture(data,w,h);
332 /* A message that is sent through the carbon event queue */
333 private static abstract class CarbonMessage {
334 public abstract void perform();
336 static { natInit(); }
337 public static native void natInit();
338 public static native void add(CarbonMessage m);