1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the GNU General Public License version 2 ("the License").
3 // You may not use this file except in compliance with the License.
5 // Authors: Brian Alliet and Evan Jones
9 import gnu.gcj.RawData;
10 import org.ibex.util.*;
12 import org.ibex.graphics.*;
13 import org.ibex.core.*;
14 import org.ibex.net.*;
16 public class Darwin extends POSIX {
17 public static void main(String[] s) throws Exception { org.ibex.core.Main.main(s); }
18 private static final Class openGLClass = OpenGL.class;
19 static Darwin singleton;
20 private CarbonOpenGL openGL;
21 boolean jaguar; // true if we are on OS X >= 10.2
24 protected String _getAltKeyName() { return "Option"; }
25 protected boolean _needsAutoClick() { return false; }
26 protected boolean _needsAutoDoubleClick() { return false; }
27 protected String getDescriptiveName() { return "GCJ Darwin Binary"; }
28 protected boolean _isCaseSensitive() { return false; /* Well, not always, could be UFS */ }
32 protected int _getScreenWidth() { return cgScreenWidth(); }
33 protected int _getScreenHeight() { return cgScreenHeight(); }
34 private native static int cgScreenWidth();
35 private native static int cgScreenHeight();
36 protected native void _newBrowserWindow(String url);
37 protected native HTTP.Proxy natDetectProxy();
38 private native void natInit();
40 private native String natGetClipBoard();
41 private native void natSetClipBoard(String text);
42 protected void _setClipBoard(final String text) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetClipBoard(text); } }); }
43 protected String _getClipBoard() {
44 final Semaphore sem = new Semaphore();
45 final String[] result = new String[1]; // Kind of like a pointer
46 CarbonMessage.add(new CarbonMessage() { public void perform() { result[0] = natGetClipBoard(); sem.release(); } });
51 private static class FileDialogHelper {
52 public FileDialogHelper(boolean save) { this.save = save; }
54 public Semaphore sem = new Semaphore();
55 public String fileName;
56 public String saveName;
58 private native void natFileDialog(FileDialogHelper helper, String suggestedFileName, boolean write);
59 protected String _fileDialog(final String fn, final boolean w) {
60 final FileDialogHelper helper = new FileDialogHelper(w);
61 CarbonMessage.add(new CarbonMessage() { public void perform() { natFileDialog(helper,fn,w); } });
64 return helper.fileName + "/" + helper.saveName;
66 return helper.fileName;
70 static void abort(String err) {
75 synchronized(Darwin.class) {
76 if(singleton != null) abort("Tried to instansiate Darwin more than once");
81 protected synchronized HTTP.Proxy _detectProxy() {
82 return natDetectProxy();
85 private static native final boolean isJaguar();
87 public void postInit() {
90 openGL = new CarbonOpenGL();
92 } catch(OpenGL.NotSupportedException e) {
93 Log.info(this,"WARNING: OpenGL support not available: " + e);
94 // FEATURE: fall back to quartz 2d
95 throw new Error("No OpenGL support");
100 protected Scheduler _getScheduler() { return new DarwinScheduler(); }
101 protected native void runApplicationEventLoop();
102 private class DarwinScheduler extends org.ibex.core.Scheduler {
104 new Thread() { public void run() { defaultRun(); } }.start();
105 runApplicationEventLoop();
109 private final class CarbonOpenGL extends OpenGL {
110 public RawData rawPixelFormat;
111 public RawData rawSharedContext;
112 public int maxAglSurfaceTexSize;
113 public int maxSurfaceWidth;
114 public int maxSurfaceHeight;
116 private native boolean initPixelFormat();
117 private native void initSharedContext();
119 public CarbonOpenGL() throws NotSupportedException {
121 throw new NotSupportedException("OpenGL requires Mac OS X 10.2 or greater");
122 if(!initPixelFormat())
123 throw new NotSupportedException("Couldn't get an acceptable pixel format");
127 public void init() throws NotSupportedException {
129 maxAglSurfaceTexSize = rectangularTextures ? maxRectTexSize : maxTexSize;
130 if(renderer.startsWith("ATI Radeon 7500")) {
131 maxAglSurfaceTexSize = Math.min(rectangularTextures ? 1600 : 1024,maxAglSurfaceTexSize);
132 Log.info(this,"Working around Radeon 7500 bug: maxAglSurfaceTexSize: " + maxAglSurfaceTexSize);
134 maxSurfaceWidth = maxSurfaceHeight = maxAglSurfaceTexSize;
136 protected native void activateSharedContext();
139 static abstract class CarbonSurface extends Surface.DoubleBufferedSurface {
140 RawData rawWindowRef;
145 boolean pendingResize;
147 private native void natSetInvisible(boolean i);
148 public void setInvisible(final boolean i) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetInvisible(i); } }); }
149 private native void nat_setMaximized(boolean b);
150 public void _setMaximized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMaximized(b); } }); }
151 private native void nat_setMinimized(boolean b);
152 public void _setMinimized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMinimized(b); } }); }
153 private native void natSetIcon(Picture p);
154 public void setIcon(final Picture p) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetIcon(p); } }); }
155 private native void natSetTitleBarText(String s);
156 public void setTitleBarText(final String s) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetTitleBarText(s); } }); }
157 private native void natSetSize(int w, int h);
158 public void _setSize(final int w, final int h) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetSize(w,h); } }); }
159 private native void natSetLocation();
160 public void setLocation() { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLocation(); } }); }
161 private native void natToFront();
162 public void toFront() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToFront(); } }); }
163 private native void natToBack();
164 public void toBack() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToBack(); } }); }
165 private native void natSetLimits(int minWidth, int minHeight, int maxWidth, int maxHeight);
166 public void setLimits(final int mnw, final int mnh, final int mxw, final int mxh) {
167 if(Darwin.singleton.jaguar)
168 CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLimits(mnw,mnh,mxw,mxh); } });
170 private native void natSyncCursor(int n);
171 public void syncCursor() {
173 if(cursor.equals("default")) n = 0;
174 else if(cursor.equals("wait")) n = 1;
175 else if(cursor.equals("crosshair")) n = 2;
176 else if(cursor.equals("text")) n = 3;
177 else if(cursor.equals("hand")) n = 4;
178 else if(cursor.equals("move")) n = 5;
179 else if(cursor.equals("east") || cursor.equals("west")) n = 6;
182 CarbonMessage.add(new CarbonMessage() { public void perform() { natSyncCursor(n_); } });
186 public abstract void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
188 public final void _dispose() { CarbonMessage.add(new CarbonMessage() { public void perform() { natDispose(); } }); }
189 public native void natDispose();
191 public final native void natInit(boolean framed);
193 public CarbonSurface(Box root, final boolean framed) {
195 final Semaphore sem = new Semaphore();
196 CarbonMessage.add(new CarbonMessage() { public void perform() { CarbonSurface.this.natInit(framed); sem.release(); } });
200 public void needsReshape() { }
201 protected static native void blitLock();
202 protected static native void blitUnlock();
203 protected static native void blitWait();
206 static class GLCarbonPixelBuffer extends OpenGL.GLPixelBuffer {
208 RawData rawWindowRef;
213 private native void natInit();
214 private static native void natCleanup(RawData rawWindowRef, RawData rawCTX);
217 private static final int fixupDimension(CarbonOpenGL gl, int n) {
218 if(!gl.rectangularTextures) n = OpenGL.roundToPowerOf2(n);
219 return Math.min(n,gl.maxAglSurfaceTexSize);
221 public GLCarbonPixelBuffer(int w, int h, final CarbonOpenGL gl) {
222 super(fixupDimension(gl,w),fixupDimension(gl,h));
224 rectTexture = gl.hasRectangularTextures();
225 final Semaphore sem = new Semaphore();
226 CarbonMessage.add(new CarbonMessage() { public void perform() { GLCarbonPixelBuffer.this.natInit(); sem.release(); } });
229 public native void activateContext();
230 protected void finalize() {
231 CarbonMessage.add(new CarbonMessage() { public void perform() { natCleanup(rawWindowRef,rawCTX); } });
232 gl.deleteTexture(textureName);
236 static class GLCarbonSurface extends CarbonSurface {
239 boolean needsReshape;
241 private final native void natInit();
242 private final native void flush();
243 private final native void clear();
245 public GLCarbonSurface(Box root, boolean framed, CarbonOpenGL gl) {
251 public void setLimits(int mnw,int mnh, int mxw, int mxh) {
252 mxw = Math.min(mxw,gl.maxSurfaceWidth);
253 mxh = Math.min(mxh,gl.maxSurfaceHeight);
254 super.setLimits(mnw,mnh,mxw,mxh);
257 public void _setSize(int w, int h) {
258 w = Math.min(w,gl.maxSurfaceWidth);
259 h = Math.min(h,gl.maxSurfaceWidth);
263 private native void natBlit(GLCarbonPixelBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2);
264 public void blit(PixelBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2) {
265 natBlit((GLCarbonPixelBuffer)db,sx,sy,dx,dy,dx2,dy2);
269 // The blit_lock ensures the window size does not change through the entire blit operation.
270 public void render() {
273 while(pendingResize) blitWait();
276 needsReshape = false;
278 reshape(winWidth,winHeight);
280 Dirty(0,0,winWidth,winHeight);
289 private native void reshape(int w, int h);
290 // blit_lock is assumed to be held
291 public void needsReshape() { needsReshape = true; }
293 public native void natDispose();
296 /*private class QZCarbonPixelBuffer extends PixelBuffer {
298 public QZCarbonPixelBuffer(int width, int height) {
301 private class QZCarbonSurface extends CarbonSurface {
302 public QZCarbonSurface(Box root, boolean framed) {
305 public native void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
308 private class QZCarbonPicture extends Picture {
312 public final int getWidth() { return width; }
313 public final int getHeight() { return height; }
315 public QZCarbonPicture(int w, int h) {
321 protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) {
323 return new GLCarbonPixelBuffer(w,h,openGL);
325 return /*new QZCarbonPixelBuffer(w,h)*/ null;
327 protected Surface _createSurface(Box b, boolean framed) {
329 return new GLCarbonSurface(b,framed, openGL);
331 return /*new QZCarbonSufrace(b,framed)*/ null;
333 protected Picture _createPicture(JS r) {
335 return openGL._createPicture(r, true);
337 return /*new QZCarbonPicture(data,w,h);*/ null;
339 protected org.ibex.graphics.Font.Glyph _createGlyph(org.ibex.graphics.Font f, char c) {
341 return openGL._createGlyph(f, c);
343 return super.createGlyph(f, c);
346 /* A message that is sent through the carbon event queue */
347 private static abstract class CarbonMessage {
348 public abstract void perform();
350 static { natInit(); }
351 public static native void natInit();
352 public static native void add(CarbonMessage m);