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