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
13 #define __private_extern__
14 #include <mach-o/dyld.h>
19 #include <java/lang/Object.h>
20 #include <java/lang/Error.h>
22 #include <org/ibex/plat/Darwin.h>
23 #include <org/ibex/plat/Darwin$CarbonSurface.h>
24 #include <org/ibex/plat/Darwin$GLCarbonSurface.h>
25 #include <org/ibex/plat/Darwin$GLCarbonPixelBuffer.h>
26 #include <org/ibex/plat/Darwin$CarbonMessage.h>
27 #include <org/ibex/plat/Darwin$CarbonOpenGL.h>
28 #include <org/ibex/plat/Darwin$FileDialogHelper.h>
29 #include <org/ibex/plat/GCJ$Retainer.h>
30 #include <org/ibex/net/HTTP$Proxy.h>
31 #include <org/ibex/util/Semaphore.h>
36 #include "DarwinCarbonHeaders.h"
38 #define Ibex_CARBON_NO_BUNDLE_HACK
39 #ifdef Ibex_CARBON_NO_BUNDLE_HACK
41 OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn);
42 OSErr CPSSetFrontProcess(ProcessSerialNumber *psn);
46 static const mach_header* CarbonHandle = NULL;
47 static const mach_header* AGLHandle = NULL;
48 static const mach_header* SCHandle = NULL;
49 #define CARBON_LIBRARY_PATH "/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon"
50 #define AGL_LIBRARY_PATH "/System/Library/Frameworks/AGL.framework/Versions/A/AGL"
51 #define SC_LIBRARY_PATH "/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration"
53 static void* dlsym(char* symbol) {
54 if (CarbonHandle == NULL) CarbonHandle = NSAddImage(CARBON_LIBRARY_PATH, NSADDIMAGE_OPTION_NONE);
55 if (AGLHandle == NULL) AGLHandle = NSAddImage(AGL_LIBRARY_PATH, NSADDIMAGE_OPTION_NONE);
56 if (SCHandle == NULL) SCHandle = NSAddImage(SC_LIBRARY_PATH, NSADDIMAGE_OPTION_NONE);
57 void* ret = NSAddressOfSymbol(NSLookupSymbolInImage(CarbonHandle, symbol,
58 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND));
59 if (ret == NULL) ret = NSAddressOfSymbol(NSLookupSymbolInImage(AGLHandle, symbol,
60 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND));
61 if (ret == NULL) ret = NSAddressOfSymbol(NSLookupSymbolInImage(SCHandle, symbol,
62 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND));
63 /*printf("linking symbol %s to address %x\n", symbol, ret);
68 #define declare_weak(symbol) typeof(symbol) *symbol##_weak = NULL
70 (*((func##_weak != NULL) ? func##_weak : func##_weak = (typeof(func##_weak))dlsym("_" #func)))
72 declare_weak(GetRegionBounds);
73 declare_weak(RegisterToolboxObjectClass);
74 declare_weak(GetWindowProperty);
75 declare_weak(SetWindowProperty);
76 declare_weak(CreateCustomWindow);
77 declare_weak(InstallWindowContentPaintProc);
78 declare_weak(AEGetNthPtr);
79 declare_weak(CFArrayGetCount);
80 declare_weak(CFArrayGetTypeID);
81 declare_weak(CFArrayGetValueAtIndex);
82 declare_weak(CFDictionaryGetValue);
83 declare_weak(CFGetTypeID);
84 declare_weak(CFNumberGetTypeID);
85 declare_weak(CFNumberGetValue);
86 declare_weak(CFRelease);
87 declare_weak(CFStringCompare);
88 declare_weak(CFStringCreateWithCString);
89 declare_weak(CFStringCreateWithCharacters);
90 declare_weak(CFStringGetCharacters);
91 declare_weak(CFStringGetLength);
92 declare_weak(CFStringGetTypeID);
93 declare_weak(CFURLCopyScheme);
94 declare_weak(CFURLCreateWithString);
95 declare_weak(CGDisplayPixelsHigh);
96 declare_weak(CGDisplayPixelsWide);
97 declare_weak(CallNextEventHandler);
98 declare_weak(CollapseWindow);
99 declare_weak(ConstrainWindowToScreen);
100 declare_weak(CreateEvent);
101 declare_weak(CreateNewWindow);
102 declare_weak(DisposeEventHandlerUPP);
103 declare_weak(DisposeNavEventUPP);
104 declare_weak(DisposeWindow);
105 declare_weak(ExitToShell);
106 declare_weak(FSRefMakePath);
107 declare_weak(FrontWindow);
108 declare_weak(Gestalt);
109 declare_weak(GetApplicationEventTarget);
110 declare_weak(GetCurrentProcess);
111 declare_weak(GetCurrentScrap);
112 declare_weak(GetEventClass);
113 declare_weak(GetEventKind);
114 declare_weak(GetEventParameter);
115 declare_weak(GetMainEventQueue);
116 declare_weak(GetScrapFlavorData);
117 declare_weak(GetScrapFlavorSize);
118 declare_weak(GetWindowBounds);
119 declare_weak(GetWindowEventTarget);
120 declare_weak(GetWindowPort);
121 declare_weak(HideWindow);
122 declare_weak(InstallEventHandler);
123 declare_weak(IsWindowCollapsed);
124 declare_weak(LSOpenCFURLRef);
125 declare_weak(NavCreateGetFileDialog);
126 declare_weak(NavCreatePutFileDialog);
127 declare_weak(NavDialogDispose);
128 declare_weak(NavDialogGetReply);
129 declare_weak(NavDialogGetUserAction);
130 declare_weak(NavDialogRun);
131 declare_weak(NavDisposeReply);
132 declare_weak(NavGetDefaultDialogCreationOptions);
133 declare_weak(NewEventHandlerUPP);
134 declare_weak(NewNavEventUPP);
135 declare_weak(PostEventToQueue);
136 declare_weak(PutScrapFlavor);
137 declare_weak(QuitApplicationEventLoop);
138 declare_weak(ReleaseEvent);
139 declare_weak(RunApplicationEventLoop);
140 declare_weak(SCDynamicStoreCopyProxies);
141 declare_weak(SelectWindow);
142 declare_weak(SendBehind);
143 declare_weak(SetEventParameter);
144 declare_weak(SetThemeCursor);
145 declare_weak(SetWindowBounds);
146 declare_weak(SetWindowResizeLimits);
147 declare_weak(SetWindowTitleWithCFString);
148 declare_weak(ShowWindow);
149 declare_weak(ZoomWindowIdeal);
150 declare_weak(__CFStringMakeConstantString);
151 declare_weak(aglChoosePixelFormat);
152 declare_weak(aglCreateContext);
153 declare_weak(aglDestroyContext);
154 declare_weak(aglSetCurrentContext);
155 declare_weak(aglSetDrawable);
156 declare_weak(aglSurfaceTexture);
157 declare_weak(aglUpdateContext);
158 declare_weak(CPSEnableForegroundOperation);
159 declare_weak(CPSSetFrontProcess);
160 declare_weak(kCFAllocatorDefault);
161 declare_weak(NewWindowPaintUPP);
163 #define GetWindowEventTarget WC(GetWindowEventTarget)
164 #define InstallEventHandler WC(InstallEventHandler)
165 #define __CFStringMakeConstantString WC(__CFStringMakeConstantString)
167 using namespace org::ibex::plat;
168 using gnu::gcj::RawData;
169 using org::ibex::util::Semaphore;
170 using java::lang::Object;
172 namespace org { namespace ibex { namespace plat {
175 #pragma mark ----- Blit Locks ------
176 static pthread_mutex_t blit_mutex;
177 static pthread_cond_t blit_cond;
179 static inline void blit_lock() { if(pthread_mutex_lock(&blit_mutex) != 0) abort(); }
180 static inline void blit_unlock() { if(pthread_mutex_unlock(&blit_mutex) != 0) abort(); }
181 static inline void blit_wait() { if(pthread_cond_wait(&blit_cond,&blit_mutex) != 0) abort(); }
182 static inline void blit_signal() { if(pthread_cond_signal(&blit_cond) != 0) abort(); }
184 void Darwin$CarbonSurface::blitLock() { blit_lock(); }
185 void Darwin$CarbonSurface::blitUnlock() { blit_unlock(); }
186 void Darwin$CarbonSurface::blitWait() { blit_wait(); }
189 template <bool CHECK> static inline int CompileTimeCheck() { const int something_is_wrong=1; something_is_wrong++; return 0; }
190 template <> static inline int CompileTimeCheck<true>() { return 0; }
191 const static int unichar_check = CompileTimeCheck<sizeof(jchar)==sizeof(UniChar)>();
193 static void funcFailed(const char *func,int r);
194 static inline void funcFailed(const char *func) { funcFailed(func,-1); }
196 static inline void checkStatus(OSStatus r, char *func) { if(r != noErr) funcFailed(func,r); }
197 static inline void checkStatus(GLboolean b, char *func) { if(!b) funcFailed(func,-1); }
198 static inline void checkStatus(void *p, char *func) { if(!p) funcFailed(func,-1); }
200 jstring cfStringToJString(CFStringRef s) {
201 CFIndex length = WC(CFStringGetLength)(s);
202 CFRange range = CFRangeMake(0,length);
203 jstring js = JvAllocString(length);
204 UniChar *buf = (UniChar*)JvGetStringChars(js);
205 WC(CFStringGetCharacters)(s,range,buf);
209 #pragma mark ------ SmartCFString ------
210 class SmartCFString {
213 void release() { if(p) WC(CFRelease)(p); }
214 void checkNull() { if(!p) funcFailed("CFString function"); }
217 SmartCFString() : p(0) { }
218 SmartCFString(const char *s) : p(0) { *this = s; }
219 SmartCFString(jstring js) : p(0) { *this = js; }
220 SmartCFString(CFStringRef cf) : p(0) { *this = cf; }
222 ~SmartCFString() { release(); }
224 SmartCFString& operator= (const char *s) {
227 p = WC(CFStringCreateWithCString)(WC(kCFAllocatorDefault),s,kCFStringEncodingISOLatin1);
231 SmartCFString& operator= (jstring js) {
232 if(!js) return *this = "(null)";
234 UniChar *buf = (UniChar*) JvGetStringChars(js);
235 CFIndex length = js->length();
236 p = WC(CFStringCreateWithCharacters)(WC(kCFAllocatorDefault),buf,length);
240 SmartCFString& operator= (CFStringRef cf) {
241 if(cf == NULL) return *this = "(null)";
246 operator CFStringRef() { return p; }
247 operator jstring() { return getJString(); }
249 jstring getJString() { return cfStringToJString(p); }
251 bool equals(const char *s) {
252 SmartCFString cfs(s);
256 bool equals(CFStringRef cfs) {
257 return WC(CFStringCompare)(p,cfs,0) == kCFCompareEqualTo;
261 // CHECKME: Is just making up your own four char codes really correct?
262 const static UInt32 kEventClassCarbonMessage = 'ibxa';
263 const static UInt32 kEventCarbonMessage = 'ibxb';
264 const static UInt32 kEventParamCarbonMessage = 'ibxc';
266 static OSStatus carbonMessageEventHandler(EventHandlerCallRef handler, EventRef e, void *userData);
267 static EventHandlerUPP carbonMessageEventHandlerUPP;
269 static void fileDialogEventHandler(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *userData);
270 static NavEventUPP fileDialogEventHandlerUPP;
272 static OSStatus windowEventHandler(EventHandlerCallRef handler, EventRef e, void *userData);
273 static EventHandlerUPP windowEventHandlerUPP;
275 static OSStatus paintProc(GDHandle device,GrafPtr qdContext,WindowRef window,RgnHandle inClientPaintRgn,RgnHandle outSystemPaintRgn,void *userData);
276 static WindowPaintUPP paintProcUPP;
278 jboolean Darwin::isJaguar() {
280 OSStatus r = WC(Gestalt)(gestaltSystemVersion, &version);
281 checkStatus(r,"Gestalt");
282 return version >= 0x1020;
285 void Darwin$CarbonMessage::natInit() {
288 EventTypeSpec eventTypes = { kEventClassCarbonMessage, kEventCarbonMessage };
289 r = InstallEventHandler(WC(GetApplicationEventTarget)(),carbonMessageEventHandlerUPP,1,&eventTypes,NULL,NULL);
290 checkStatus(r,"InstallEventHandler");
293 void Darwin$CarbonMessage::add(Darwin$CarbonMessage *msg) {
297 GCJ$Retainer::retain(msg);
299 r = WC(CreateEvent)(WC(kCFAllocatorDefault),kEventClassCarbonMessage,kEventCarbonMessage,0,kEventAttributeNone,&event);
300 checkStatus(r,"CreateEvent");
301 r = WC(SetEventParameter)(event,kEventParamCarbonMessage,typeVoidPtr,sizeof(msg),(void*)&msg);
302 checkStatus(r,"SetEventParameter");
303 r = WC(PostEventToQueue)(WC(GetMainEventQueue)(),event,kEventPriorityHigh);
304 checkStatus(r,"PostEventToQueue");
305 WC(ReleaseEvent)(event);
309 static OSStatus carbonMessageEventHandler(EventHandlerCallRef handler, EventRef e, void *userData) {
310 UInt32 eKind = WC(GetEventKind)(e);
311 UInt32 eClass = WC(GetEventClass)(e);
313 Darwin$CarbonMessage *msg;
314 if(eClass != kEventClassCarbonMessage || eKind != kEventCarbonMessage)
315 return eventNotHandledErr;
316 r = WC(GetEventParameter)(e,kEventParamCarbonMessage,typeVoidPtr,NULL,sizeof(msg),NULL,&msg);
317 checkStatus(r,"GetEventParameter");
319 GCJ$Retainer::release(msg);
324 #pragma mark ------ Utility Functions ------
326 static void funcFailed(const char *func,int r){
327 fprintf(stderr,"%s() failed (%d)\n",func,r);
331 #pragma mark ------ CarbonPicture Methods ------
333 #pragma mark ----- Carbon Surface Methods ----
336 void Darwin$CarbonSurface::natSyncCursor(jint n) {
338 // see Carbon.java for what these numbers mean
340 case 1: c = kThemeWatchCursor;
341 case 2: c = kThemePlusCursor;
342 case 3: c = kThemeIBeamCursor;
343 case 4: c = kThemePointingHandCursor;
344 case 5: c = kThemeOpenHandCursor;
345 case 6: c = kThemeResizeLeftRightCursor;
346 default: c = kThemeArrowCursor;
348 WC(SetThemeCursor)(c);
351 void Darwin$CarbonSurface::natSetInvisible(jboolean b) {
352 WindowRef window = (WindowRef) rawWindowRef;
353 fprintf(stderr,"Making window %s\n",b?"invisible":"visible");
354 if(b) WC(HideWindow)(window);
355 else WC(ShowWindow)(window);
358 void Darwin$CarbonSurface::nat_setMaximized(jboolean b) {
359 WindowRef window = (WindowRef) rawWindowRef;
360 Point ideal = { 10000, 10000 };
361 OSStatus r = WC(ZoomWindowIdeal)(window,(b?inZoomOut:inZoomIn),&ideal);
362 checkStatus(r,"ZoomWindowIdeal");
365 void Darwin$CarbonSurface::nat_setMinimized(jboolean b) {
366 WindowRef window = (WindowRef) rawWindowRef;
367 if((WC(IsWindowCollapsed)(window) ? 1 : 0) == (b ? 1 : 0)) return;
368 OSStatus r = WC(CollapseWindow)(window,b);
369 checkStatus(r,"CollapseWindow");
372 void Darwin$CarbonSurface::natSetTitleBarText(jstring js) {
373 SmartCFString s = js;
374 WindowRef window = (WindowRef) rawWindowRef;
375 WC(SetWindowTitleWithCFString)(window,s);
378 void Darwin$CarbonSurface::natToBack() {
379 WindowRef window = (WindowRef) rawWindowRef;
380 WC(SendBehind)(window,NULL);
383 void Darwin$CarbonSurface::natToFront() {
384 WindowRef window = (WindowRef) rawWindowRef;
385 fprintf(stderr,"SelectWindow)()\n");
386 WC(SelectWindow)(window);
389 #pragma mark ---- Window Event Handler ----
390 static const EventTypeSpec eventTypeSpecs[] = {
391 // kEventClassCommand
392 // { kEventClassCommand, ??? },
395 { kEventClassWindow, kEventWindowUpdate },
396 { kEventClassWindow, kEventWindowBoundsChanged },
397 { kEventClassWindow, kEventWindowBoundsChanging },
398 { kEventClassWindow, kEventWindowActivated },
399 { kEventClassWindow, kEventWindowDeactivated },
400 { kEventClassWindow, kEventWindowZoomed },
401 { kEventClassWindow, kEventWindowCollapsed },
402 { kEventClassWindow, kEventWindowExpanded },
403 { kEventClassWindow, kEventWindowClose },
404 { kEventClassWindow, kEventWindowClosed },
405 { kEventClassWindow, kEventWindowDrawFrame },
406 { kEventClassWindow, kEventWindowDrawPart },
408 // kEventClassControl
409 { kEventClassControl, kEventControlApplyBackground },
411 // kEventClassKeyboard
412 { kEventClassKeyboard, kEventRawKeyDown },
413 { kEventClassKeyboard, kEventRawKeyRepeat },
414 { kEventClassKeyboard, kEventRawKeyUp },
415 { kEventClassKeyboard, kEventRawKeyModifiersChanged },
418 { kEventClassMouse, kEventMouseDown },
419 { kEventClassMouse, kEventMouseUp },
420 { kEventClassMouse, kEventMouseMoved },
421 { kEventClassMouse, kEventMouseDragged },
422 { kEventClassMouse, kEventMouseWheelMoved },
425 static OSStatus windowEventHandler(EventHandlerCallRef handler, EventRef e, void *userData) {
426 Darwin$CarbonSurface *surface = (Darwin$CarbonSurface*)userData;
427 UInt32 eKind = WC(GetEventKind)(e);
428 UInt32 eClass = WC(GetEventClass)(e);
430 char* ec = (char*)&eClass;
431 if (surface == NULL) return eventNotHandledErr;
435 case kEventClassCommand:
437 // TODO: handle menu items
440 case kEventClassKeyboard:
442 case kEventRawKeyDown:
443 case kEventRawKeyRepeat:
444 case kEventRawKeyUp: {
448 r = WC(GetEventParameter)(e,kEventParamKeyCode,typeUInt32,NULL,sizeof(keyCode),NULL,&keyCode);
449 checkStatus(r,"GetEventParameter");
452 // These values were obtained by experimentation. I can't find any constants for them
453 // in the header files
454 case 126: js = JvNewStringLatin1("up"); break;
455 case 125: js = JvNewStringLatin1("down"); break;
456 case 124: js = JvNewStringLatin1("right"); break;
457 case 123: js = JvNewStringLatin1("left"); break;
458 case 122: js = JvNewStringLatin1("f1"); break;
459 case 120: js = JvNewStringLatin1("f2"); break;
460 case 99: js = JvNewStringLatin1("f3"); break;
461 case 118: js = JvNewStringLatin1("f4"); break;
462 case 96: js = JvNewStringLatin1("f5"); break;
463 case 97: js = JvNewStringLatin1("f6"); break;
464 case 98: js = JvNewStringLatin1("f7"); break;
465 case 100: js = JvNewStringLatin1("f8"); break;
466 case 101: js = JvNewStringLatin1("f9"); break;
467 case 109: js = JvNewStringLatin1("f10"); break;
468 case 103: js = JvNewStringLatin1("f11"); break;
469 case 111: js = JvNewStringLatin1("f12"); break;
470 case 105: js = JvNewStringLatin1("f13"); break;
471 case 114: js = JvNewStringLatin1("insert"); break;
472 case 117: js = JvNewStringLatin1("delete"); break;
473 case 116: js = JvNewStringLatin1("page_up"); break;
474 case 121: js = JvNewStringLatin1("page_down"); break;
475 case 115: js = JvNewStringLatin1("home"); break;
476 case 119: js = JvNewStringLatin1("end"); break;
477 case 71: js = JvNewStringLatin1("num_lock"); break;
478 case 53: js = JvNewStringLatin1("escape"); break;
479 case 51: js = JvNewStringLatin1("back_space"); break;
480 case 36: js = JvNewStringLatin1("enter"); break;
481 case 48: js = JvNewStringLatin1("tab"); break;
482 case 76: js = JvNewStringLatin1("enter"); break; // number pad enter
485 UInt32 modifiers = surface->modifiers;
486 r = WC(GetEventParameter)(e,kEventParamKeyUnicodes,typeUnicodeText,NULL,0,&size,NULL);
487 checkStatus(r,"GetEventParameter");
488 if(size == 0 || (modifiers & controlKey && size>sizeof(UniChar))) return eventNotHandledErr;
490 js = JvAllocString(size/sizeof(UniChar));
491 UniChar *buf = (UniChar*)JvGetStringChars(js);
492 r = WC(GetEventParameter)(e,kEventParamKeyUnicodes,typeUnicodeText,NULL,size,NULL,buf);
493 checkStatus(r,"GetEventParameter");
495 if(!buf[0]) return eventNotHandledErr; // shouldn't happen
496 // odd, when the ctrl key is pressed a-"`" become 1-31, this brings them back to the corect values
497 if(modifiers & controlKey && buf[0] < 32) buf[0] += 0x60;
502 if(eKind == kEventRawKeyUp)
503 surface->KeyReleased(js);
505 surface->KeyPressed(js);
508 case kEventRawKeyModifiersChanged: {
509 const static struct {
512 } modifiersTable[] = {
513 { shiftKey, JvNewStringLatin1("shift") },
514 { alphaLock, JvNewStringLatin1("caps_lock") },
515 { controlKey, JvNewStringLatin1("control") },
516 { optionKey, JvNewStringLatin1("alt") },
517 { kEventKeyModifierNumLockMask, JvNewStringLatin1("num_lock") },
521 UInt32 oldModifiers = (UInt32) surface->modifiers;
523 r = WC(GetEventParameter)(e,kEventParamKeyModifiers,typeUInt32,NULL,sizeof(newModifiers),NULL,&newModifiers);
524 checkStatus(r,"GetEventParameter");
525 surface->modifiers = (jint) newModifiers;
526 UInt32 changedModifiers = oldModifiers ^ newModifiers;
528 for(int i=0;modifiersTable[i].mask;i++) {
529 UInt32 mask = modifiersTable[i].mask;
530 if(!(changedModifiers & mask)) continue;
531 if(newModifiers & mask)
532 surface->KeyPressed(modifiersTable[i].ibexKey);
534 surface->KeyReleased(modifiersTable[i].ibexKey);
540 case kEventClassMouse:
541 // The default handler gets first dibs on mouse events
542 // (this catches the titlebar, resize box, etc)
543 r = WC(CallNextEventHandler)(handler, e);
544 if(r != eventNotHandledErr && eKind != kEventMouseMoved && eKind != kEventMouseDragged) return r;
547 case kEventMouseMoved:
548 case kEventMouseDragged: {
549 WindowRef window = (WindowRef) surface->rawWindowRef;
553 r = WC(GetEventParameter)(e,kEventParamMouseLocation,typeQDPoint,NULL,sizeof(p),NULL,&p);
554 checkStatus(r,"GetEventParameter");
555 r = WC(GetWindowBounds)(window,kWindowContentRgn,&rect);
556 checkStatus(r,"GetWindowBounds");
557 surface->Move(p.h-rect.left,p.v-rect.top);
560 case kEventMouseDown:
561 case kEventMouseUp: {
562 EventMouseButton button;
565 r = WC(GetEventParameter)(e,kEventParamMouseButton,typeMouseButton,NULL,sizeof(button),NULL,&button);
566 checkStatus(r,"GetEventParameter");
567 r = WC(GetEventParameter)(e,kEventParamClickCount,typeUInt32,NULL,sizeof(clickCount),NULL,&clickCount);
568 checkStatus(r,"GetEventParameter");
571 case kEventMouseButtonPrimary: ibexButton = 1; break;
572 case kEventMouseButtonSecondary: ibexButton = 2; break;
573 case kEventMouseButtonTertiary: ibexButton = 3; break;
574 default: return noErr;
576 if(eKind == kEventMouseDown) {
577 surface->Press(ibexButton);
579 surface->Release(ibexButton);
580 while(clickCount > 1) {
581 surface->DoubleClick(ibexButton);
584 if(clickCount) surface->Click(ibexButton);
588 case kEventMouseWheelMoved: {
589 EventMouseWheelAxis axis;
591 r = WC(GetEventParameter)(e,kEventParamMouseWheelAxis,typeMouseWheelAxis,NULL,sizeof(axis),NULL,&axis);
592 checkStatus(r,"GetEventParameter");
593 r = WC(GetEventParameter)(e,kEventParamMouseWheelDelta,typeSInt32,NULL,sizeof(delta),NULL,&delta);
594 checkStatus(r,"GetEventParameter");
596 case kEventMouseWheelAxisX: surface->HScroll((jint)(40 * delta)); break;
597 case kEventMouseWheelAxisY: surface->VScroll((jint)(40 * delta)); break;
604 case kEventClassWindow: {
606 r = WC(GetEventParameter)(e,kEventParamDirectObject,typeWindowRef,NULL,sizeof(window),NULL,&window);
607 checkStatus(r,"kEventClassWindow/WC(GetEventParameter");
609 if((RawData*)window != surface->rawWindowRef) Darwin::abort(JvNewStringLatin1("window != surface->window"));
612 case kEventWindowBoundsChanging: {
616 r = WC(GetEventParameter)(e,kEventParamAttributes,typeUInt32,NULL,sizeof(attr),NULL,&attr);
617 checkStatus(r,"kEventWindowBoundsChanged/GetEventParameter");
619 r = WC(GetEventParameter)(e,kEventParamCurrentBounds,typeQDRectangle,NULL,sizeof(rect),NULL,&rect);
620 checkStatus(r,"kEventWindowBoundsChanging/GetEventParameter");
622 if(attr & kWindowBoundsChangeSizeChanged) {
623 jint w = rect.right-rect.left;
624 jint h = rect.bottom-rect.top;
628 surface->winWidth = w;
629 surface->winHeight = h;
630 surface->pendingResize = true;
631 surface->needsReshape();
635 surface->SizeChange(w,h);
636 if(attr & kWindowBoundsChangeUserResize && surface->maximized)
637 surface->Maximized(false);
640 if(attr & kWindowBoundsChangeOriginChanged) {
641 surface->PosChange(rect.left,rect.top);
646 case kEventWindowBoundsChanged: {
648 r = WC(GetEventParameter)(e,kEventParamAttributes,typeUInt32,NULL,sizeof(attr),NULL,&attr);
649 checkStatus(r,"kEventWindowBoundsChanged/GetEventParameter");
651 if(attr & kWindowBoundsChangeSizeChanged) {
654 surface->pendingResize = false;
661 case kEventWindowActivated:
662 case kEventWindowDeactivated: {
663 surface->Focused(eKind == kEventWindowActivated);
666 case kEventWindowZoomed: {
667 surface->Maximized(true);
670 case kEventWindowCollapsed: {
671 surface->Minimized(true);
674 case kEventWindowExpanded: {
675 surface->Minimized(false);
678 case kEventWindowClose: {
682 case kEventWindowClosed: {
683 GCJ$Retainer::release(surface);
686 case kEventWindowUpdate: {
687 fprintf(stderr,"kEventWindowUpdate: Should not be here\n");
694 return eventNotHandledErr;
697 static OSStatus paintProc (
701 RgnHandle inClientPaintRgn,
702 RgnHandle outSystemPaintRgn,
705 Darwin$CarbonSurface *surface = (Darwin$CarbonSurface*) userData;
707 WC(GetRegionBounds)(inClientPaintRgn, &rect);
708 surface->Dirty(rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top);
712 void Darwin$CarbonSurface::natInit(jboolean framed) {
715 WindowClass wc = framed ? kDocumentWindowClass : kPlainWindowClass;
716 // FIXME: unframed windows should appear in the window menu
717 // This probably needs a hack similar to whats in Cocoa.mm
718 WindowAttributes attr = kWindowStandardHandlerAttribute|
719 (framed ? kWindowInWindowMenuAttribute|kWindowStandardDocumentAttributes|kWindowLiveResizeAttribute : 0);
721 rect.top = rect.left = 0;
722 rect.bottom = rect.right = 10;
723 winWidth = winHeight = 10;
725 r = WC(CreateNewWindow)(wc, attr, &rect, &window);
726 checkStatus(r,"CreateNewWindow");
728 rawWindowRef = (RawData*) window;
730 GCJ$Retainer::retain(this); // Need to account for the EventHandlers pointer to us
732 r = InstallWindowEventHandler(window,windowEventHandlerUPP,sizeof(eventTypeSpecs)/sizeof(EventTypeSpec),eventTypeSpecs,this,NULL);
733 checkStatus(r,"InstallWindowEventHandler");
735 r = WC(InstallWindowContentPaintProc)(window,paintProcUPP,kWindowPaintProcOptionsNone,this);
736 checkStatus(r,"InstallWindowContentPaintProc");
738 WC(ShowWindow)(window);
741 void Darwin$CarbonSurface::natDispose() {
742 WindowRef window = (WindowRef) rawWindowRef;
743 WC(DisposeWindow)(window);
746 void Darwin$CarbonSurface::natSetIcon(org::ibex::graphics::Picture *_p) {
749 void Darwin$CarbonSurface::natSetLocation() {
750 WindowRef window = (WindowRef) rawWindowRef;
754 OSStatus r = WC(GetWindowBounds)(window,kWindowStructureRgn,&rect);
755 checkStatus(r,"GetWindowBounds");
756 rect.bottom = y + (rect.bottom - rect.top);
757 rect.right = x + (rect.right - rect.left);
760 r = WC(SetWindowBounds)(window,kWindowStructureRgn,&rect);
761 checkStatus(r,"SetWindowBounds");
762 r = WC(ConstrainWindowToScreen)(window,kWindowStructureRgn,kWindowConstrainMoveRegardlessOfFit,NULL,NULL);
763 checkStatus(r,"ConstrainWindowToScreen");
766 void Darwin$CarbonSurface::natSetSize(jint w, jint h) {
767 WindowRef window = (WindowRef) rawWindowRef;
769 OSStatus r = WC(GetWindowBounds)(window,kWindowContentRgn,&rect);
770 checkStatus(r,"GetWindowBounds");
771 rect.bottom = rect.top + h;
772 rect.right = rect.left + w;
773 r = WC(SetWindowBounds)(window,kWindowContentRgn,&rect);
774 checkStatus(r,"SetWindowBounds");
775 r = WC(ConstrainWindowToScreen)(window,kWindowStructureRgn,kWindowConstrainMoveRegardlessOfFit,NULL,NULL);
776 checkStatus(r,"ConstrainWindowToScreen");
779 void Darwin$CarbonSurface::natSetLimits(jint minw, jint minh, jint maxw, jint maxh) {
780 WindowRef window = (WindowRef) rawWindowRef;
781 const int maxMax = 32767;
782 const int minMinW = 80;
783 const int minMinH = 20;
785 min.width = minw > maxMax ? maxMax : (minw < minMinW ? minMinW : minw);
786 min.height = minh > maxMax ? maxMax : (minh < minMinH ? minMinH : minh);
787 max.width = maxw > maxMax ? maxMax : (maxw < minMinW ? minMinW : maxw);
788 max.height = maxh > maxMax ? maxMax : (maxh < minMinH ? minMinH : maxh);
789 OSStatus r = WC(SetWindowResizeLimits)(window,&min,&max);
790 checkStatus(r,"SetWindowResizeLimits");
794 #pragma mark ------ Carbon Methods ------
795 void fileDialogEventHandler(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *userData) {
796 Darwin$FileDialogHelper *helper = (Darwin$FileDialogHelper*) userData;
797 NavDialogRef dialog = callBackParms->context;
799 switch(callBackSelector) {
800 case kNavCBUserAction: {
801 NavUserAction action = WC(NavDialogGetUserAction)(dialog);
802 if(action == kNavUserActionNone || action == kNavUserActionCancel) {
803 helper->fileName = 0;
805 NavReplyRecord reply;
806 r = WC(NavDialogGetReply)(dialog,&reply);
807 checkStatus(r,"NavDialogGetReply");
812 r = WC(AEGetNthPtr)(&reply.selection,1,typeFSRef,&keyword,NULL,&ref,sizeof(ref),NULL);
813 checkStatus(r,"AEGetNthPtr");
814 r = WC(FSRefMakePath)(&ref,(UInt8*)buf,sizeof(buf)-1);
815 checkStatus(r,"FSRefMakePath");
816 helper->fileName = JvNewStringLatin1(buf);
817 if(helper->save) helper->saveName = cfStringToJString(reply.saveFileName);
818 r = WC(NavDisposeReply)(&reply);
819 checkStatus(r,"NavDialogGetReply");
821 helper->sem->release();
824 case kNavCBTerminate:
825 WC(NavDialogDispose)(dialog);
830 void Darwin::natFileDialog(Darwin$FileDialogHelper *helper,jstring suggestion_, jboolean write) {
832 SmartCFString suggestion = suggestion_;
833 CFStringRef message = CFSTR("By selecting a file in this dialog you are giving this Ibex application permission to access that file.");
835 WindowRef window = WC(FrontWindow)();
836 NavDialogCreationOptions options;
838 WC(NavGetDefaultDialogCreationOptions)(&options);
839 options.optionFlags =
840 (options.optionFlags|kNavAllFilesInPopup|kNavSelectAllReadableItem|kNavDontUseCustomFrame|kNavDontConfirmReplacement)
841 &~(kNavAllowStationery|kNavAllowMultipleFiles);
842 options.clientName = CFSTR("Ibex");
844 options.saveFileName = suggestion;
845 options.message = message;
846 options.modality = window ? kWindowModalityWindowModal : kWindowModalityAppModal;
847 options.parentWindow = window;
850 r = WC(NavCreatePutFileDialog)(&options,0,0,fileDialogEventHandlerUPP,helper,&dlg);
852 r = WC(NavCreateGetFileDialog)(&options,NULL,fileDialogEventHandlerUPP,NULL,NULL,helper,&dlg);
853 checkStatus(r,"NavCreate(Get/Put)FileDialog");
855 WC(NavDialogRun)(dlg);
858 jstring Darwin::natGetClipBoard() {
863 r = WC(GetCurrentScrap)(&scrap);
864 checkStatus(r,"GetCurrentScrap");
866 r = WC(GetScrapFlavorSize)( scrap, kScrapFlavorTypeUnicode, &size);
867 if(r == scrapFlavorNotFoundErr) return JvNewStringLatin1("");
868 checkStatus(r,"GetScrapFlavorSize");
870 unsigned int length = size/sizeof(UniChar);
872 jstring js = JvAllocString(length);
873 UniChar *buf = (UniChar*) JvGetStringChars(js);
875 r = WC(GetScrapFlavorData)(scrap,kScrapFlavorTypeUnicode,&size2,buf);
876 if(r == scrapFlavorNotFoundErr);
877 checkStatus(r,"GetScrapFlavorData");
878 if(size2 != size) return JvNewStringLatin1("");
883 void Darwin::natSetClipBoard(jstring js) {
884 unsigned int length = js->length();
888 r = WC(GetCurrentScrap)(&scrap);
889 checkStatus(r,"GetCurrentScrap");
891 r = WC(PutScrapFlavor)(scrap,kScrapFlavorTypeUnicode,0,sizeof(UniChar)*length,JvGetStringChars(js));
892 checkStatus(r,"PutScrapFlavor");
895 org::ibex::net::HTTP$Proxy *Darwin::natDetectProxy() {
896 org::ibex::net::HTTP$Proxy *p=0;
899 SmartCFString smartString;
900 CFArrayRef exceptionList;
903 CFDictionaryRef proxyInfo = WC(SCDynamicStoreCopyProxies)(NULL);
904 if(proxyInfo == NULL) return 0;
906 #define doproto(proto,var) \
907 number = (CFNumberRef) WC(CFDictionaryGetValue)(proxyInfo,kSCPropNetProxies ## proto ## Enable); \
908 if(number != NULL && WC(CFGetTypeID)(number) != WC(CFNumberGetTypeID)()) number = NULL; \
909 if(number && WC(CFNumberGetValue)(number,kCFNumberIntType,&i) && i) { \
910 string = (CFStringRef) WC(CFDictionaryGetValue)(proxyInfo, kSCPropNetProxies ## proto ## Proxy);\
911 if(string != NULL && WC(CFGetTypeID)(string) != WC(CFStringGetTypeID)()) string = NULL; \
912 number = (CFNumberRef) WC(CFDictionaryGetValue)(proxyInfo, kSCPropNetProxies ## proto ## Port); \
913 if(number != NULL && WC(CFGetTypeID)(number) != WC(CFNumberGetTypeID)()) number = NULL; \
914 if(string && number && WC(CFNumberGetValue)(number,kCFNumberIntType,&i) && i) { \
915 if(!p) p = new org::ibex::net::HTTP$Proxy(); \
916 p->var ## ProxyHost = cfStringToJString(string); \
917 p->var ## ProxyPort = i; \
925 exceptionList = (CFArrayRef) WC(CFDictionaryGetValue)(proxyInfo,kSCPropNetProxiesExceptionsList);
926 if(exceptionList != NULL && WC(CFGetTypeID)(exceptionList) != WC(CFArrayGetTypeID)()) exceptionList = NULL;
927 if(p && exceptionList && WC(CFArrayGetCount)(exceptionList)) {
928 CFIndex count = WC(CFArrayGetCount)(exceptionList);
929 p->excluded = (JArray<java::lang::String*>*)
930 JvNewObjectArray(count,&java::lang::String::class$,0);
931 for(i=0;i<count;i++) {
932 string = (CFStringRef) WC(CFArrayGetValueAtIndex)(exceptionList,i);
933 if(string != NULL && WC(CFGetTypeID)(string) != WC(CFStringGetTypeID)()) string = NULL;
934 elements(p->excluded)[i] = string ? cfStringToJString(string) : JvNewStringLatin1("(null)");
937 WC(CFRelease)(proxyInfo);
941 exceptionList = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesExceptionsList];
942 if(p && exceptionList && [exceptionList count]) {
943 NSLog(@"excl: %@",exceptionList);
944 p->excluded = (JArray<java::lang::String*>*)
945 JvNewObjectArray([exceptionList count],&java::lang::String::class$,0);
946 for(i=0;i<[exceptionList count];i++)
947 elements(p->excluded)[i] = [[exceptionList objectAtIndex: i] jstring];
953 using org::ibex::Proxy;
958 NSArray *exceptionList;
960 NSDictionary *proxyInfo = (NSDictionary*)WC(SCDynamicStoreCopyProxies)(NULL);
962 if(proxyInfo == NULL) return 0;
963 if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPEnable] boolValue]) {
964 host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPProxy];
965 port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPPort];
966 if(host && [port intValue]) {
967 if(!p) p = new Proxy();
968 p->httpProxyHost = [host jstring];
969 p->httpProxyPort = [port intValue];
972 if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSEnable] boolValue]) {
973 host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSProxy];
974 port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSPort];
975 if(host && [port intValue]) {
976 if(!p) p = new Proxy();
977 p->httpsProxyHost = [host jstring];
978 p->httpsProxyPort = [port intValue];
981 if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSEnable] boolValue]) {
982 host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSProxy];
983 port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSPort];
984 if(host && [port intValue]) {
985 if(!p) p = new Proxy();
986 p->socksProxyHost = [host jstring];
987 p->socksProxyPort = [port intValue];
991 exceptionList = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesExceptionsList];
992 if(p && exceptionList && [exceptionList count]) {
993 NSLog(@"excl: %@",exceptionList);
994 p->excluded = (JArray<java::lang::String*>*)
995 JvNewObjectArray([exceptionList count],&java::lang::String::class$,0);
996 for(i=0;i<[exceptionList count];i++)
997 elements(p->excluded)[i] = [[exceptionList objectAtIndex: i] jstring];
1003 jint Darwin::cgScreenWidth() {
1004 return WC(CGDisplayPixelsWide)(((CGDirectDisplayID)0));
1007 jint Darwin::cgScreenHeight() {
1008 return WC(CGDisplayPixelsHigh)(((CGDirectDisplayID)0));
1011 void Darwin::_newBrowserWindow(jstring js) {
1012 SmartCFString cfs = js;
1013 CFURLRef url = WC(CFURLCreateWithString)(WC(kCFAllocatorDefault),cfs,NULL);
1014 SmartCFString scheme = WC(CFURLCopyScheme)(url);
1015 if(scheme.equals(CFStringRef("http")))
1016 WC(LSOpenCFURLRef)(url,NULL);
1020 void Darwin::natInit() {
1023 if(pthread_mutex_init(&blit_mutex,NULL) != 0) funcFailed("pthread_mutex_init");
1024 if(pthread_cond_init(&blit_cond,NULL) != 0) funcFailed("pthread_cond_init");
1026 carbonMessageEventHandlerUPP = WC(NewEventHandlerUPP)(carbonMessageEventHandler);
1027 windowEventHandlerUPP = WC(NewEventHandlerUPP)(windowEventHandler);
1028 fileDialogEventHandlerUPP = WC(NewNavEventUPP)(fileDialogEventHandler);
1029 paintProcUPP = WC(NewWindowPaintUPP)(paintProc);
1031 #ifdef Ibex_CARBON_NO_BUNDLE_HACK
1033 ProcessSerialNumber currentProcess = { 0, kCurrentProcess };
1035 ::fprintf(stderr,"Doing Ibex_CARBON_NO_BUNDLE_HACK\n");
1036 r = WC(GetCurrentProcess)(¤tProcess);
1037 checkStatus(r,"GetCurrentProcess");
1038 r = WC(CPSEnableForegroundOperation)( ¤tProcess );
1039 checkStatus(r,"CPSEnableForegroundOperation");
1040 r = WC(CPSSetFrontProcess)(¤tProcess);
1041 checkStatus(r,"CPSSetFrontProcess");
1046 r = CreateNibReference(CFSTR("MainMenu"), &nib);
1047 checkStatus(r,"CreateNibReference");
1048 r = SetMenuBarFromNib(nib, CFSTR("MenuBar"));
1049 checkStatus(r,"SetMenuBarFromNib");
1050 DisposeNibReference(nib);
1052 // FEATURE: Install menu event handler
1057 void Darwin::runApplicationEventLoop() {
1058 WC(RunApplicationEventLoop)();
1062 #pragma mark ------ OpenGL Functions -----
1064 void Darwin$CarbonOpenGL::activateSharedContext() {
1065 AGLContext ctx = (AGLContext) rawSharedContext;
1066 WC(aglSetCurrentContext)(ctx);
1069 jboolean Darwin$CarbonOpenGL::initPixelFormat() {
1081 rawPixelFormat = (RawData*) WC(aglChoosePixelFormat)(NULL,0,attr);
1082 return rawPixelFormat != 0;
1085 void Darwin$CarbonOpenGL::initSharedContext() {
1086 AGLPixelFormat fmt = (AGLPixelFormat) rawPixelFormat;
1087 rawSharedContext = (RawData*) WC(aglCreateContext)(fmt,NULL);
1088 checkStatus(rawSharedContext,"aglCreateContext");
1091 void Darwin$GLCarbonPixelBuffer::natInit() {
1092 WindowClass wc = kPlainWindowClass;
1093 WindowAttributes attr = 0;
1097 AGLContext ctx,shared;
1103 rect.top = rect.left = 0;
1104 rect.right = width + rect.left;
1105 rect.bottom = height + rect.top;
1107 r = WC(CreateNewWindow)(wc,attr,&rect,&window);
1108 checkStatus(r,"CreateNewWindow");
1110 shared = (AGLContext) gl->rawSharedContext;
1111 fmt = (AGLPixelFormat) gl->rawPixelFormat;
1112 ctx = WC(aglCreateContext)(fmt,shared);
1113 checkStatus(ctx, "aglCreateContext");
1115 b = WC(aglSetDrawable)(ctx,WC(GetWindowPort)(window));
1116 checkStatus(b,"aglSetDrawable");
1118 WC(aglSetCurrentContext)(ctx);
1119 WC(aglUpdateContext)(ctx);
1120 drawableInit(width,height);
1121 glClear(GL_COLOR_BUFFER_BIT);
1123 WC(aglSetCurrentContext)(shared);
1124 target = rectTexture ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D;
1126 glGenTextures(1,&tex);
1127 glBindTexture(target,tex);
1128 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1129 glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1130 WC(aglSurfaceTexture) (shared, target, GL_RGBA, ctx);
1134 //WC(ShowWindow)(window);
1135 textureName = (jint) tex;
1136 rawWindowRef = (RawData*) window;
1137 rawCTX = (RawData*) ctx;
1140 void Darwin$GLCarbonPixelBuffer::activateContext() {
1141 AGLContext ctx = (AGLContext) rawCTX;
1142 WC(aglSetCurrentContext)(ctx);
1145 void Darwin$GLCarbonPixelBuffer::natCleanup(RawData* rawWindowRef, RawData* rawCTX) {
1146 WindowRef window = (WindowRef) rawWindowRef;
1147 AGLContext ctx = (AGLContext) rawCTX;
1148 WC(aglDestroyContext)(ctx);
1149 WC(DisposeWindow)(window);
1152 void Darwin$GLCarbonSurface::clear() {
1153 AGLContext ctx = (AGLContext) rawCTX;
1154 WC(aglSetCurrentContext)(ctx);
1155 glColor4f(1.0f,1.0f,1.0f,1.0f);
1157 glMatrixMode (GL_MODELVIEW);
1160 glMatrixMode (GL_PROJECTION);
1164 glVertex3i (-1, -1, -1);
1165 glVertex3i (1, -1, -1);
1166 glVertex3i (1, 1, -1);
1167 glVertex3i (-1, 1, -1);
1170 glMatrixMode (GL_MODELVIEW);
1174 void Darwin$GLCarbonSurface::flush() {
1175 AGLContext ctx = (AGLContext) rawCTX;
1176 WC(aglSetCurrentContext)(ctx);
1180 // blit_lock is assumed to be held
1181 void Darwin$GLCarbonSurface::reshape(jint w, jint h) {
1182 AGLContext ctx = (AGLContext) rawCTX;
1183 WC(aglSetCurrentContext)(ctx);
1184 WC(aglUpdateContext)(ctx);
1186 glViewport(0,0,w,h);
1187 glMatrixMode(GL_PROJECTION);
1189 glOrtho(0,w,h,0,-1,1);
1190 glMatrixMode(GL_MODELVIEW);
1192 glTranslatef (0.375f, 0.375f, 0.0f);
1196 // blit_lock is assumed to be held
1197 void Darwin$GLCarbonSurface::natBlit(Darwin$GLCarbonPixelBuffer *db, jint sx1, jint sy1, jint dx1, jint dy1, jint dx2, jint dy2) {
1198 AGLContext ctx = (AGLContext) rawCTX;
1199 int sx2 = sx1 + (dx2-dx1);
1200 int sy2 = sy1 + (dy2-dy1);
1202 db->activateContext();
1206 WC(aglSetCurrentContext)(ctx);
1209 if(db->rectTexture) {
1210 glEnable(GL_TEXTURE_RECTANGLE_EXT);
1212 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, db->textureName);
1215 glTexCoord2i (sx1, sy1 );
1216 glVertex3i (dx1, dy1, 0);
1217 glTexCoord2i (sx2, sy1 );
1218 glVertex3i (dx2, dy1, 0);
1219 glTexCoord2i (sx2, sy2 );
1220 glVertex3i (dx2, dy2, 0);
1221 glTexCoord2i (sx1, sy2 );
1222 glVertex3i (dx1, dy2, 0);
1225 glDisable(GL_TEXTURE_RECTANGLE_EXT);
1228 float tx1,ty1,tx2,ty2; // normalized texture coords
1229 tx1 = (float) sx1 / (float) db->width;
1230 ty1 = (float) sy1 / (float) db->height;
1231 tx2 = (float) sx2 / (float) db->width;
1232 ty2 = (float) sy2 / (float) db->height;
1234 glColor4f(1.0f,1.0f,1.0f,1.0f);
1235 glEnable(GL_TEXTURE_2D);
1236 glBindTexture(GL_TEXTURE_2D, db->textureName);
1239 glTexCoord2f (tx1, ty1 );
1240 glVertex3i (dx1, dy1, 0);
1241 glTexCoord2f (tx2, ty1 );
1242 glVertex3i (dx2, dy1, 0);
1243 glTexCoord2f (tx2, ty2 );
1244 glVertex3i (dx2, dy2, 0);
1245 glTexCoord2f (tx1, ty2 );
1246 glVertex3i (dx1, dy2, 0);
1248 glDisable(GL_TEXTURE_2D);
1253 void Darwin$GLCarbonSurface::natInit() {
1254 WindowRef window = (WindowRef) rawWindowRef;
1255 AGLContext ctx,shared;
1259 shared = (AGLContext) gl->rawSharedContext;
1260 fmt = (AGLPixelFormat) gl->rawPixelFormat;
1261 ctx = WC(aglCreateContext)(fmt,shared);
1262 checkStatus(ctx, "aglCreateContext");
1264 b = WC(aglSetDrawable)(ctx,WC(GetWindowPort)(window));
1265 checkStatus(b,"aglSetDrawable");
1267 WC(aglSetCurrentContext)(ctx);
1268 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1270 glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
1271 glClearDepth( 0.0f );
1275 rawCTX = (RawData*)ctx;
1278 void Darwin$GLCarbonSurface::natDispose() {
1279 AGLContext ctx = (AGLContext) rawCTX;
1280 WC(aglDestroyContext)(ctx);
1281 Darwin$CarbonSurface::natDispose();
1284 } } } // end namepsace org::ibex::plat