1
2
3
4 package org.xwt.plat;
5
6 import gnu.gcj.RawData;
7 import org.xwt.util.*;
8 import org.xwt.*;
9 import java.util.*;
10
11 public class Carbon extends POSIX {
12 static Carbon singleton;
13 private CarbonOpenGL openGL;
14 boolean jaguar;
15
16
17 protected int _stringWidth(String font, String text) { return (int)Math.round(6.5 * text.length()); }
18 protected int _getMaxAscent(String font) { return 10; }
19 protected int _getMaxDescent(String font) { return 2; }
20
21
22 protected String _getAltKeyName() { return "Option"; }
23 protected boolean _needsAutoClick() { return false; }
24 protected boolean _needsAutoDoubleClick() { return false; }
25 protected String getDescriptiveName() { return "GCJ Carbon Binary"; }
26 protected boolean _isCaseSensitive() { return false; }
27
28
29
30 protected int _getScreenWidth() { return cgScreenWidth(); }
31 protected int _getScreenHeight() { return cgScreenHeight(); }
32 private native static int cgScreenWidth();
33 private native static int cgScreenHeight();
34 protected native void _newBrowserWindow(String url);
35 protected native Proxy natDetectProxy();
36 private native void natInit();
37 protected native void _exit();
38
39 private native String natGetClipBoard();
40 private native void natSetClipBoard(String text);
41 protected void _setClipBoard(final String text) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetClipBoard(text); } }); }
42 protected String _getClipBoard() {
43 final Semaphore sem = new Semaphore();
44 final String[] result = new String[1];
45 CarbonMessage.add(new CarbonMessage() { public void perform() { result[0] = natGetClipBoard(); sem.release(); } });
46 sem.block();
47 return result[0];
48 }
49
50 private static class FileDialogHelper {
51 public FileDialogHelper(boolean save) { this.save = save; }
52 public boolean save;
53 public Semaphore sem = new Semaphore();
54 public String fileName;
55 public String saveName;
56 public RawData rawUPP;
57 }
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); } });
62 helper.sem.block();
63 if(w)
64 return helper.fileName + "/" + helper.saveName;
65 else
66 return helper.fileName;
67 }
68
69
70
71 protected native void _running();
72
73 static void abort(String err) {
74 throw new Error(err);
75 }
76
77 public Carbon() {
78 synchronized(Carbon.class) {
79 if(singleton != null) abort("Tried to instansiate Carbon more than once");
80 singleton = this;
81 }
82 }
83
84 protected synchronized Proxy _detectProxy() {
85 return natDetectProxy();
86 }
87
88 private static native final boolean isJaguar();
89
90 public void init() {
91 super.init();
92 jaguar = isJaguar();
93 try {
94 openGL = new CarbonOpenGL();
95 openGL.init();
96 } catch(OpenGL.NotSupportedException e) {
97 Log.log(this,"WARNING: OpenGL support not available: " + e);
98
99 throw new Error("No OpenGL support");
100 }
101 natInit();
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.log(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 {
135 RawData rawWindowRef;
136 RawData rawEventHandlerUPP;
137 int modifiers;
138
139 private native void natSetInvisible(boolean i);
140 public void setInvisible(final boolean i) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetInvisible(i); } }); }
141 private native void nat_setMaximized(boolean b);
142 public void _setMaximized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMaximized(b); } }); }
143 private native void nat_setMinimized(boolean b);
144 public void _setMinimized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMinimized(b); } }); }
145 private native void natSetIcon(Picture p);
146 public void setIcon(final Picture p) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetIcon(p); } }); }
147 private native void natSetTitleBarText(String s);
148 public void setTitleBarText(final String s) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetTitleBarText(s); } }); }
149 private native void natSetSize(int w, int h);
150 public void setSize(final int w, final int h) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetSize(w,h); } }); }
151 private native void natSetLocation(int x, int y);
152 public void setLocation(final int x, final int y) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLocation(x,y); } }); }
153 private native void natToFront();
154 public void toFront() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToFront(); } }); }
155 private native void natToBack();
156 public void toBack() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToBack(); } }); }
157 private native void natSetLimits(int minWidth, int minHeight, int maxWidth, int maxHeight);
158 public void setLimits(final int mnw, final int mnh, final int mxw, final int mxh) {
159 if(Carbon.singleton.jaguar)
160 CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLimits(mnw,mnh,mxw,mxh); } });
161 }
162 private native void natSyncCursor(int n);
163 public void syncCursor() {
164 int n;
165 if(cursor.equals("default")) n = 0;
166 else if(cursor.equals("wait")) n = 1;
167 else if(cursor.equals("crosshair")) n = 2;
168 else if(cursor.equals("text")) n = 3;
169 else if(cursor.equals("hand")) n = 4;
170 else if(cursor.equals("move")) n = 5;
171 else if(cursor.equals("east") || cursor.equals("west")) n = 6;
172 else n = 0;
173 final int n_ = n;
174 CarbonMessage.add(new CarbonMessage() { public void perform() { natSyncCursor(n_); } });
175 }
176
177 public void _sizeChange(int w, int h) { SizeChange(w,h); }
178
179
180 public abstract void blit(DoubleBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
181
182 public final void _dispose() { CarbonMessage.add(new CarbonMessage() { public void perform() { natDispose(); } }); }
183 public native void natDispose();
184
185 public final native void natInit(boolean framed);
186
187 public CarbonSurface(Box root, final boolean framed) {
188 super(root);
189 final Semaphore sem = new Semaphore();
190 CarbonMessage.add(new CarbonMessage() { public void perform() { CarbonSurface.this.natInit(framed); sem.release(); } });
191 sem.block();
192 }
193
194 public void reshape(int w, int h) { }
195 }
196
197 static class GLCarbonDoubleBuffer extends OpenGL.GLDoubleBuffer {
198 RawData rawCTX;
199 RawData rawWindowRef;
200 int textureName;
201 boolean rectTexture;
202 CarbonOpenGL gl;
203
204 private native void natInit();
205 private static native void natCleanup(RawData rawWindowRef, RawData rawCTX);
206
207
208 private static final int fixupDimension(CarbonOpenGL gl, int n) {
209 if(!gl.rectangularTextures) n = OpenGL.roundToPowerOf2(n);
210 return Math.min(n,gl.maxAglSurfaceTexSize);
211 }
212 public GLCarbonDoubleBuffer(int w, int h, final CarbonOpenGL gl) {
213 super(fixupDimension(gl,w),fixupDimension(gl,h));
214 this.gl = gl;
215 rectTexture = gl.hasRectangularTextures();
216 final Semaphore sem = new Semaphore();
217 CarbonMessage.add(new CarbonMessage() { public void perform() { GLCarbonDoubleBuffer.this.natInit(); sem.release(); } });
218 sem.block();
219 }
220 public native void activateContext();
221 protected void finalize() {
222 CarbonMessage.add(new CarbonMessage() { public void perform() { natCleanup(rawWindowRef,rawCTX); } });
223 gl.deleteTexture(textureName);
224 }
225 }
226
227 static class GLCarbonSurface extends CarbonSurface {
228 RawData rawCTX;
229 CarbonOpenGL gl;
230 boolean sizeChange;
231
232 private final native void natInit();
233
234 public GLCarbonSurface(Box root, boolean framed, CarbonOpenGL gl) {
235 super(root,framed);
236 this.gl = gl;
237 natInit();
238 }
239
240 public void setLimits(int mnw,int mnh, int mxw, int mxh) {
241 mxw = Math.min(mxw,gl.maxSurfaceWidth);
242 mxh = Math.min(mxh,gl.maxSurfaceHeight);
243 super.setLimits(mnw,mnh,mxw,mxh);
244 }
245 public void _sizeChange(int w, int h) {
246 sizeChange = true;
247 super._sizeChange(w,h);
248 }
249
250 public void setSize(int w, int h) {
251 sizeChange = true;
252 w = Math.min(w,gl.maxSurfaceWidth);
253 h = Math.min(h,gl.maxSurfaceWidth);
254 super.setSize(w,h);
255 }
256
257 private native void natBlit(GLCarbonDoubleBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2);
258 public synchronized void blit(DoubleBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2) {
259 natBlit((GLCarbonDoubleBuffer)db,sx,sy,dx,dy,dx2,dy2);
260 }
261
262 private native void natReshape(int w, int h);
263 public synchronized void reshape(int w, int h) { natReshape(w,h); }
264
265 public native void natDispose();
266 }
267
268
293
294 protected DoubleBuffer _createDoubleBuffer(int w, int h, Surface owner) {
295 if(openGL != null)
296 return new GLCarbonDoubleBuffer(w,h,openGL);
297 else
298 return null;
299 }
300 protected Surface _createSurface(Box b, boolean framed) {
301 if(openGL != null)
302 return new GLCarbonSurface(b,framed, openGL);
303 else
304 return null;
305 }
306 protected Picture _createPicture(int[] data, int w, int h) {
307 if(openGL != null)
308 return openGL.createPicture(data,w,h);
309 else
310 return null;
311 }
312
313
314 private static abstract class CarbonMessage {
315 public abstract void perform();
316
317 static { natInit(); }
318 public static native void natInit();
319 public static native void add(CarbonMessage m);
320 }
321 }
322