more renaming fixes
[org.ibex.core.git] / src / org / ibex / plat / Darwin.java
1 // Copyright 2004 Adam Megacz, see the COPYING file for licensing [LGPL]
2 // Authors: Brian Alliet and Evan Jones
3
4 package org.ibex.plat;
5
6 import gnu.gcj.RawData;
7 import org.ibex.util.*;
8 import org.ibex.js.*;
9 import org.ibex.graphics.*;
10 import org.ibex.core.*;
11 import org.ibex.net.*;
12
13 public class Darwin extends POSIX {
14     private static final Class openGLClass = OpenGL.class;
15     static Darwin singleton;
16     private CarbonOpenGL openGL;
17     boolean jaguar; // true if we are on OS X >= 10.2
18     
19     // General Methods
20     protected String _getAltKeyName() { return "Option"; }
21     protected boolean _needsAutoClick() { return false; }
22     protected boolean _needsAutoDoubleClick() { return false; }
23     protected String getDescriptiveName() { return "GCJ Darwin Binary"; }
24     protected boolean _isCaseSensitive() { return false; /* Well, not always, could be UFS */ }
25     
26     
27     // Native Methods
28     protected int    _getScreenWidth() { return cgScreenWidth(); }
29     protected int    _getScreenHeight() { return cgScreenHeight(); }
30     private native static int cgScreenWidth();
31     private native static int cgScreenHeight();
32     protected native void   _newBrowserWindow(String url);
33     protected native HTTP.Proxy   natDetectProxy();
34     private   native void    natInit();
35
36     private native String natGetClipBoard();
37     private native void natSetClipBoard(String text);
38     protected void _setClipBoard(final String text) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetClipBoard(text); } }); }
39     protected String _getClipBoard() {
40         final Semaphore sem = new Semaphore();
41         final String[] result = new String[1]; // Kind of like a pointer
42         CarbonMessage.add(new CarbonMessage() { public void perform() { result[0] = natGetClipBoard(); sem.release(); } });
43         sem.block();
44         return result[0];
45     }
46     
47     private static class FileDialogHelper {
48         public FileDialogHelper(boolean save) { this.save = save; }
49         public boolean save;
50         public Semaphore sem = new Semaphore();
51         public String fileName;
52         public String saveName;
53     }
54     private native void natFileDialog(FileDialogHelper helper, String suggestedFileName, boolean write);
55     protected String _fileDialog(final String fn, final boolean w) {
56         final FileDialogHelper helper = new FileDialogHelper(w);
57         CarbonMessage.add(new CarbonMessage() { public void perform() { natFileDialog(helper,fn,w); } });
58         helper.sem.block();
59         if(w)
60             return helper.fileName + "/" + helper.saveName;
61         else
62             return helper.fileName;
63     }
64
65     
66     static void abort(String err) {
67         throw new Error(err);
68     }
69     
70     public Darwin() {
71         synchronized(Darwin.class) {
72             if(singleton != null) abort("Tried to instansiate Darwin more than once");
73             singleton = this;
74         }
75     }
76     
77     protected synchronized HTTP.Proxy _detectProxy() {
78         return natDetectProxy();
79     }
80     
81     private static native final boolean isJaguar();
82     
83     public void postInit() {
84         jaguar = isJaguar();
85         try {
86             openGL = new CarbonOpenGL();
87             openGL.init();
88         } catch(OpenGL.NotSupportedException e) {
89             Log.info(this,"WARNING: OpenGL support not available: " + e);
90             // FEATURE: fall back to quartz 2d
91             throw new Error("No OpenGL support");
92         }
93         natInit();
94     }
95     
96     protected Scheduler _getScheduler() { return new DarwinScheduler(); }
97     protected native void runApplicationEventLoop();
98     private class DarwinScheduler extends org.ibex.util.Scheduler {
99         public void run() {
100             new Thread() { public void run() { defaultRun(); } }.start();
101             runApplicationEventLoop();
102         }
103     }
104     
105     private final class CarbonOpenGL extends OpenGL {
106         public RawData rawPixelFormat;
107         public RawData rawSharedContext;
108         public int maxAglSurfaceTexSize;
109         public int maxSurfaceWidth;
110         public int maxSurfaceHeight;
111         
112         private native boolean initPixelFormat();
113         private native void initSharedContext();
114         
115         public CarbonOpenGL() throws NotSupportedException {
116             if(!jaguar)
117                 throw new NotSupportedException("OpenGL requires Mac OS X 10.2 or greater");
118             if(!initPixelFormat())
119                 throw new NotSupportedException("Couldn't get an acceptable pixel format");
120             initSharedContext();
121         }
122         
123         public void init() throws NotSupportedException {
124             super.init();
125             maxAglSurfaceTexSize = rectangularTextures ? maxRectTexSize : maxTexSize;
126             if(renderer.startsWith("ATI Radeon 7500")) {
127                 maxAglSurfaceTexSize = Math.min(rectangularTextures ? 1600 : 1024,maxAglSurfaceTexSize);
128                 Log.info(this,"Working around Radeon 7500 bug: maxAglSurfaceTexSize: " + maxAglSurfaceTexSize);
129             }
130             maxSurfaceWidth = maxSurfaceHeight = maxAglSurfaceTexSize;
131         }
132         protected native void activateSharedContext();
133     }
134     
135     static abstract class CarbonSurface extends Surface.DoubleBufferedSurface {  
136         RawData rawWindowRef;
137         int modifiers;
138         int winWidth;
139         int winHeight;
140         
141         boolean pendingResize;
142          
143         private native void natSetInvisible(boolean i);
144         public void setInvisible(final boolean i) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetInvisible(i); } }); }
145         private native void nat_setMaximized(boolean b);
146         public void _setMaximized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMaximized(b); } }); }
147         private native void nat_setMinimized(boolean b);
148         public void _setMinimized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMinimized(b); } }); }
149         private native void natSetIcon(Picture p);
150         public void setIcon(final Picture p) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetIcon(p); } }); }
151         private native void natSetTitleBarText(String s);
152         public void setTitleBarText(final String s) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetTitleBarText(s); } }); }
153         private native void natSetSize(int w, int h);
154         public void _setSize(final int w, final int h) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetSize(w,h); } }); }
155         private native void natSetLocation();
156         public void setLocation() { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLocation(); } }); }
157         private native void natToFront();
158         public void toFront() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToFront(); } }); }
159         private native void natToBack();
160         public void toBack() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToBack(); } }); }
161         private native void natSetLimits(int minWidth, int minHeight, int maxWidth, int maxHeight);
162         public void setLimits(final int mnw, final int mnh, final int mxw, final int mxh) {
163             if(Darwin.singleton.jaguar)
164                 CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLimits(mnw,mnh,mxw,mxh); } });
165         }
166         private native void natSyncCursor(int n);
167         public void syncCursor() {
168             int n;
169             if(cursor.equals("default")) n = 0;
170             else if(cursor.equals("wait")) n = 1;
171             else if(cursor.equals("crosshair")) n = 2;
172             else if(cursor.equals("text")) n = 3;
173             else if(cursor.equals("hand")) n = 4;
174             else if(cursor.equals("move")) n = 5;
175             else if(cursor.equals("east") || cursor.equals("west")) n = 6;
176             else n = 0; 
177             final int n_ = n;
178             CarbonMessage.add(new CarbonMessage() { public void perform() { natSyncCursor(n_); } });
179         }
180        
181         /* Drawing stuff */
182         public abstract void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
183
184         public final void _dispose() { CarbonMessage.add(new CarbonMessage() { public void perform() { natDispose(); } }); }
185         public native void natDispose();
186         
187         public final native void natInit(boolean framed);
188         
189         public CarbonSurface(Box root, final boolean framed) {
190             super(root);
191             final Semaphore sem = new Semaphore();
192             CarbonMessage.add(new CarbonMessage() { public void perform() { CarbonSurface.this.natInit(framed); sem.release(); } });
193             sem.block();
194         }
195         
196         public void needsReshape() { }
197         protected static native void blitLock();
198         protected static native void blitUnlock();
199         protected static native void blitWait();
200     }
201     
202     static class GLCarbonPixelBuffer extends OpenGL.GLPixelBuffer {
203         RawData rawCTX;
204         RawData rawWindowRef;
205         int textureName;
206         boolean rectTexture;
207         CarbonOpenGL gl;
208         
209         private native void natInit();
210         private static native void natCleanup(RawData rawWindowRef, RawData rawCTX);
211         
212         
213         private static final int fixupDimension(CarbonOpenGL gl, int n) {
214             if(!gl.rectangularTextures) n = OpenGL.roundToPowerOf2(n);
215             return Math.min(n,gl.maxAglSurfaceTexSize);
216         }
217         public GLCarbonPixelBuffer(int w, int h, final CarbonOpenGL gl) {
218             super(fixupDimension(gl,w),fixupDimension(gl,h));
219             this.gl = gl;
220             rectTexture = gl.hasRectangularTextures();
221             final Semaphore sem = new Semaphore();
222             CarbonMessage.add(new CarbonMessage() { public void perform() { GLCarbonPixelBuffer.this.natInit(); sem.release(); } });
223             sem.block();
224         }
225         public native void activateContext();
226         protected void finalize() {
227             CarbonMessage.add(new CarbonMessage() { public void perform() { natCleanup(rawWindowRef,rawCTX); } });
228             gl.deleteTexture(textureName);
229         }
230     }
231     
232     static class GLCarbonSurface extends CarbonSurface {
233         RawData rawCTX;
234         CarbonOpenGL gl;
235         boolean needsReshape;
236                 
237         private final native void natInit();
238         private final native void flush();
239         private final native void clear();
240         
241         public GLCarbonSurface(Box root, boolean framed, CarbonOpenGL gl) {
242             super(root,framed);
243             this.gl = gl;
244             natInit();
245         }
246         
247         public void setLimits(int mnw,int mnh, int mxw, int mxh) {
248             mxw = Math.min(mxw,gl.maxSurfaceWidth);
249             mxh = Math.min(mxh,gl.maxSurfaceHeight);
250             super.setLimits(mnw,mnh,mxw,mxh);
251         }
252         
253         public void _setSize(int w, int h) {
254             w = Math.min(w,gl.maxSurfaceWidth);
255             h = Math.min(h,gl.maxSurfaceWidth);
256             super._setSize(w,h);
257         }
258         
259         private native void natBlit(GLCarbonPixelBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2);
260         public void blit(PixelBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2) {
261             natBlit((GLCarbonPixelBuffer)db,sx,sy,dx,dy,dx2,dy2);
262         }
263         
264         
265         // The blit_lock ensures the window size does not change through the entire blit operation.
266         public void render() {
267             /*
268             blitLock();
269             while(pendingResize) blitWait();
270             */
271             if(needsReshape) {
272                 needsReshape = false;
273                 
274                 reshape(winWidth,winHeight);
275                 clear();
276                 Dirty(0,0,winWidth,winHeight);
277             }
278             super.render();
279             flush();
280             /*
281             blitUnlock();
282             */
283         }
284         
285         private native void reshape(int w, int h);
286         // blit_lock is assumed to be held
287         public void needsReshape() { needsReshape = true; }
288
289         public native void natDispose();
290     }
291
292     /*private class QZCarbonPixelBuffer extends PixelBuffer {
293         
294         public QZCarbonPixelBuffer(int width, int height) {
295         }
296     }
297        private class QZCarbonSurface extends CarbonSurface {
298         public QZCarbonSurface(Box root, boolean framed) {
299             super(b,root);
300         }
301         public native void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
302     }
303     
304     private class QZCarbonPicture extends Picture {
305         int width;
306         int height;
307         
308         public final int getWidth() { return width; }
309         public final int getHeight() { return height; }
310                 
311         public QZCarbonPicture(int w, int h) {
312             this.width = w;
313             this.height = h;
314         }
315     }*/
316     
317     protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) {
318         if(openGL != null)
319             return new GLCarbonPixelBuffer(w,h,openGL);
320         else
321             return /*new QZCarbonPixelBuffer(w,h)*/ null;
322     }
323     protected Surface _createSurface(Box b, boolean framed) {
324         if(openGL != null)
325             return new GLCarbonSurface(b,framed, openGL);
326         else
327             return /*new QZCarbonSufrace(b,framed)*/ null;
328     }
329     protected Picture _createPicture(JS r) {
330         if(openGL != null)
331             return openGL._createPicture(r, true);
332         else
333             return /*new QZCarbonPicture(data,w,h);*/ null;
334     }
335     protected org.ibex.graphics.Font.Glyph  _createGlyph(org.ibex.graphics.Font f, char c) {
336         if(openGL != null)
337             return openGL._createGlyph(f, c);
338         else
339             return super.createGlyph(f, c);
340     }
341     
342     /* A message that is sent through the carbon event queue */
343     private static abstract class CarbonMessage {
344         public abstract void perform();
345         
346         static { natInit(); }
347         public static native void natInit();
348         public static native void add(CarbonMessage m);
349     }
350 }