From 032661c3770e2df9b19495ceeff402c42e17738e Mon Sep 17 00:00:00 2001 From: megacz Date: Fri, 30 Jan 2004 07:04:53 +0000 Subject: [PATCH] 2003/09/07 03:10:15 darcs-hash:20040130070453-2ba56-ee0f99d4880ae84af8fa574f94dc62722c9c66e3.gz --- Makefile | 4 +- Makefile.upstream | 5 +- src/org/xwt/plat/Carbon.cc | 1061 ----------------------------------------- src/org/xwt/plat/Carbon.java | 321 ------------- src/org/xwt/plat/Darwin.cc | 1063 +++++++++++++++++++++++++++++++++++++++++- src/org/xwt/plat/Darwin.java | 319 ++++++++++++- 6 files changed, 1381 insertions(+), 1392 deletions(-) delete mode 100644 src/org/xwt/plat/Carbon.cc delete mode 100644 src/org/xwt/plat/Carbon.java diff --git a/Makefile b/Makefile index 5cc88bd..9c249c1 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # The XWT Makefile # -all: JVM Linux Win32 Carbon Java2 #Solaris +all: JVM Linux Win32 Darwin Java2 Solaris JVM: build/JVM/xwt.jar Linux: ; make gcj platform=Linux target=i686-pc-linux-gnu link_flags="-lX11 -lXext --static" @@ -128,7 +128,7 @@ build/java/org/xwt/Builtin.java: $(shell ls src/org/xwt/builtin/*.png src/org/xw # compile is here to force compilation of the .class files (they get used via -Ibuild) without # having the individual .o's depend on the .java's (otherwise every .o gets recompiled when one .java changes) -gcj: .vendor install_gcc-3.3 .compile $(target_bin) +gcj: .vendor .install_gcc-3.3_$(target) .compile $(target_bin) build/JVM/xwt.jar: .compile @echo -e "\n\033[1marchiving .class -> .jar: build/JVM/xwt.jar\033[0m" mkdir -p build/JVM diff --git a/Makefile.upstream b/Makefile.upstream index 7819c74..541a547 100644 --- a/Makefile.upstream +++ b/Makefile.upstream @@ -49,7 +49,7 @@ vendor: .vendor; @true (test -e upstream/$*/patches && cd upstream/$*/src && for A in ../patches/*.patch; do patch -p0 < $$A; done); true touch $@ -.configure_%_$(target): download_% +.configure_%_$(target): .download_% @echo -e "\n\033[1mconfiguring $*...\033[0m" mkdir -p upstream/$*/build-$(target) cd upstream/$*/build-$(target); \ @@ -60,8 +60,7 @@ vendor: .vendor; @true $(configure_$*-$(target)) touch $@ -install_%: .install_%_$(target); @true -.install_%_$(target): .configure_% +.install_%_$(target): .configure_%_$(target) @echo -e "\n\033[1mbuilding $*...\033[0m" cd upstream/$*/build-$(target); $(setcc) PATH=$$PATH:`pwd`/../../install/bin make @echo -e "\n\033[1minstalling $*...\033[0m" diff --git a/src/org/xwt/plat/Carbon.cc b/src/org/xwt/plat/Carbon.cc deleted file mode 100644 index 914ba77..0000000 --- a/src/org/xwt/plat/Carbon.cc +++ /dev/null @@ -1,1061 +0,0 @@ -// Copyright 2003 Adam Megacz, see the COPYING file for licensing [LGPL] -// Authors: Brian Alliet and Evan Jones -#ifndef __APPLE_CC__ -#define FSF_GCC -#define __APPLE_CC__ -#else -#define APPLE_GCC -#endif - -#include "POSIX.cc" -#include "OpenGL.cc" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -// For proxy stuff -#include -// For LSOpenURLRef -#include - -#include - -#include - -using namespace org::xwt::plat; -using gnu::gcj::RawData; -using org::xwt::util::Semaphore; -using java::lang::Object; - -namespace org { namespace xwt { namespace plat { - -namespace carbon { } -using namespace carbon; - -#pragma mark ------ Carbon Namespace ------ -namespace carbon { - // We put everything that isn't in org.xwt.plat.Carbon in - // org.xwt.plat.carbon to prevent namespace conflicts - - template static inline int CompileTimeCheck() { const int something_is_wrong=1; something_is_wrong++; return 0; } - template <> static inline int CompileTimeCheck() { return 0; } - const static int unichar_check = CompileTimeCheck(); - - void funcFailed(char *func,int r); - static inline void checkStatus(OSStatus r, char *func) { if(r != noErr) funcFailed(func,r); } - static inline void checkStatus(GLboolean b, char *func) { if(!b) funcFailed(func,-1); } - static inline void checkStatus(void *p, char *func) { if(!p) funcFailed(func,-1); } - - jstring cfStringToJString(CFStringRef s) { - CFIndex length = CFStringGetLength(s); - CFRange range = CFRangeMake(0,length); - jstring js = JvAllocString(length); - UniChar *buf = (UniChar*)JvGetStringChars(js); - CFStringGetCharacters(s,range,buf); - return js; - } - - #pragma mark ------ SmartCFString ------ - class SmartCFString { - private: - CFStringRef p; - void release() { if(p) CFRelease(p); } - void checkNull() { if(!p) throw new java::lang::Error(JvNewStringLatin1("CFString function failed")); } - public: - // Constructors - SmartCFString() : p(0) { } - SmartCFString(const char *s) : p(0) { *this = s; } - SmartCFString(jstring js) : p(0) { *this = js; } - SmartCFString(CFStringRef cf) : p(0) { *this = cf; } - // Destructor - ~SmartCFString() { release(); } - // Assignment - SmartCFString& operator= (const char *s) { - release(); - if(!s) s = "(null)"; - p = CFStringCreateWithCString(kCFAllocatorDefault,s,kCFStringEncodingISOLatin1); - checkNull(); - return *this; - } - SmartCFString& operator= (jstring js) { - if(!js) return *this = "(null)"; - release(); - UniChar *buf = (UniChar*) JvGetStringChars(js); - CFIndex length = js->length(); - p = CFStringCreateWithCharacters(kCFAllocatorDefault,buf,length); - checkNull(); - return *this; - } - SmartCFString& operator= (CFStringRef cf) { - if(cf == NULL) return *this = "(null)"; - release(); - p = cf; - return *this; - } - operator CFStringRef() { return p; } - operator jstring() { return getJString(); } - - jstring getJString() { return cfStringToJString(p); } - - bool equals(const char *s) { - SmartCFString cfs(s); - return equals(cfs); - } - - bool equals(CFStringRef cfs) { - return CFStringCompare(p,cfs,0) == kCFCompareEqualTo; - } - }; - - // CHECKME: Is just making up your own four char codes really correct? - const static UInt32 kEventClassCarbonMessage = 'xwta'; - const static UInt32 kEventCarbonMessage = 'xwtb'; - const static UInt32 kEventParamCarbonMessage = 'xwtc'; - - pascal OSStatus carbon::carbonMessageEventHandler(EventHandlerCallRef handler, EventRef e, void *userData); - void fileDialogEventHandler(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *userData); - -} // end namespace - -jboolean Carbon::isJaguar() { - SInt32 version; - OSStatus r = Gestalt(gestaltSystemVersion, &version); - checkStatus(r,"Gestalt"); - return version >= 0x1020; -} - -void Carbon$CarbonMessage::natInit() { - OSStatus r; - - EventHandlerUPP upp = NewEventHandlerUPP(carbonMessageEventHandler); - EventTypeSpec eventTypes = { kEventClassCarbonMessage, kEventCarbonMessage }; - r = InstallEventHandler(GetApplicationEventTarget(),upp,1,&eventTypes,NULL,NULL); - checkStatus(r,"InstallEventHandler"); -} - -void Carbon$CarbonMessage::add(Carbon$CarbonMessage *msg) { - EventRef event; - OSStatus r; - - GCJ$Retainer::retain(msg); - - r = CreateEvent(kCFAllocatorDefault,kEventClassCarbonMessage,kEventCarbonMessage,0,kEventAttributeNone,&event); - checkStatus(r,"CreateEvent"); - r = SetEventParameter(event,kEventParamCarbonMessage,typeVoidPtr,sizeof(msg),(void*)&msg); - checkStatus(r,"SetEventParameter"); - r = PostEventToQueue(GetMainEventQueue(),event,kEventPriorityHigh); - checkStatus(r,"PostEventToQueue"); - ReleaseEvent(event); -} - - -pascal OSStatus carbon::carbonMessageEventHandler(EventHandlerCallRef handler, EventRef e, void *userData) { - UInt32 eKind = GetEventKind(e); - UInt32 eClass = GetEventClass(e); - OSStatus r; - Carbon$CarbonMessage *msg; - if(eClass != kEventClassCarbonMessage || eKind != kEventCarbonMessage) - return eventNotHandledErr; - r = GetEventParameter(e,kEventParamCarbonMessage,typeVoidPtr,NULL,sizeof(msg),NULL,&msg); - checkStatus(r,"GetEventParameter"); - msg->perform(); - GCJ$Retainer::release(msg); - return noErr; -} - - -#pragma mark ------ Utility Functions ------ - -void carbon::funcFailed(char *func,int r){ - fprintf(stderr,"%s() failed (%d)\n",func,r); - exit(EXIT_FAILURE); -} - -#pragma mark ------ CarbonPicture Methods ------ - -#pragma mark ----- Carbon Surface Methods ---- - - -void Carbon$CarbonSurface::natSyncCursor(jint n) { - ThemeCursor c; - // see Carbon.java for what these numbers mean - switch(n) { - case 1: c = kThemeWatchCursor; - case 2: c = kThemePlusCursor; - case 3: c = kThemeIBeamCursor; - case 4: c = kThemePointingHandCursor; - case 5: c = kThemeOpenHandCursor; - case 6: c = kThemeResizeLeftRightCursor; - default: c = kThemeArrowCursor; - } - SetThemeCursor(c); -} - -void Carbon$CarbonSurface::natSetInvisible(jboolean b) { - WindowRef window = (WindowRef) rawWindowRef; - fprintf(stderr,"Making window %s\n",b?"invisible":"visible"); - if(b) HideWindow(window); - else ShowWindow(window); -} - -void Carbon$CarbonSurface::nat_setMaximized(jboolean b) { - WindowRef window = (WindowRef) rawWindowRef; - Point ideal = { 10000, 10000 }; - OSStatus r = ZoomWindowIdeal(window,(b?inZoomOut:inZoomIn),&ideal); - checkStatus(r,"ZoomWindowIdeal"); -} - -void Carbon$CarbonSurface::nat_setMinimized(jboolean b) { - WindowRef window = (WindowRef) rawWindowRef; - if((IsWindowCollapsed(window) ? 1 : 0) == (b ? 1 : 0)) return; - OSStatus r = CollapseWindow(window,b); - checkStatus(r,"CollapseWindow"); -} - -void Carbon$CarbonSurface::natSetTitleBarText(jstring js) { - SmartCFString s = js; - WindowRef window = (WindowRef) rawWindowRef; - SetWindowTitleWithCFString(window,s); -} - -void Carbon$CarbonSurface::natToBack() { - WindowRef window = (WindowRef) rawWindowRef; - SendBehind(window,NULL); -} - -void Carbon$CarbonSurface::natToFront() { - WindowRef window = (WindowRef) rawWindowRef; - fprintf(stderr,"SelectWindow()\n"); - SelectWindow(window); -} - -#pragma mark ---- Window Event Handler ---- -namespace carbon { -static const EventTypeSpec eventTypeSpecs[] = { - // kEventClassCommand - // { kEventClassCommand, ??? }, - - // kEventClassWindow - { kEventClassWindow, kEventWindowUpdate }, - { kEventClassWindow, kEventWindowBoundsChanged }, - { kEventClassWindow, kEventWindowActivated }, - { kEventClassWindow, kEventWindowDeactivated }, - { kEventClassWindow, kEventWindowZoomed }, - { kEventClassWindow, kEventWindowCollapsed }, - { kEventClassWindow, kEventWindowExpanded }, - { kEventClassWindow, kEventWindowClose }, - { kEventClassWindow, kEventWindowClosed }, - - // kEventClassKeyboard - { kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassKeyboard, kEventRawKeyRepeat }, - { kEventClassKeyboard, kEventRawKeyUp }, - { kEventClassKeyboard, kEventRawKeyModifiersChanged }, - - // kEventClassMouse - { kEventClassMouse, kEventMouseDown }, - { kEventClassMouse, kEventMouseUp }, - { kEventClassMouse, kEventMouseMoved }, - { kEventClassMouse, kEventMouseDragged }, - { kEventClassMouse, kEventMouseWheelMoved }, -}; - -pascal OSStatus windowEventHandler(EventHandlerCallRef handler, EventRef e, void *userData) { - Carbon$CarbonSurface *surface = (Carbon$CarbonSurface*) userData; - UInt32 eKind = GetEventKind(e); - UInt32 eClass = GetEventClass(e); - OSStatus r; - - switch(eClass) { - case kEventClassCommand: - switch(eKind) { - // TODO: handle menu items - } - break; - case kEventClassKeyboard: - switch(eKind) { - case kEventRawKeyDown: - case kEventRawKeyRepeat: - case kEventRawKeyUp: { - UInt32 keyCode; - jstring js; - - r = GetEventParameter(e,kEventParamKeyCode,typeUInt32,NULL,sizeof(keyCode),NULL,&keyCode); - checkStatus(r,"GetEventParameter"); - - switch(keyCode) { - // These values were obtained by experimentation. I can't find any constants for them - // in the header files - case 126: js = JvNewStringLatin1("up"); break; - case 125: js = JvNewStringLatin1("down"); break; - case 124: js = JvNewStringLatin1("right"); break; - case 123: js = JvNewStringLatin1("left"); break; - case 122: js = JvNewStringLatin1("f1"); break; - case 120: js = JvNewStringLatin1("f2"); break; - case 99: js = JvNewStringLatin1("f3"); break; - case 118: js = JvNewStringLatin1("f4"); break; - case 96: js = JvNewStringLatin1("f5"); break; - case 97: js = JvNewStringLatin1("f6"); break; - case 98: js = JvNewStringLatin1("f7"); break; - case 100: js = JvNewStringLatin1("f8"); break; - case 101: js = JvNewStringLatin1("f9"); break; - case 109: js = JvNewStringLatin1("f10"); break; - case 103: js = JvNewStringLatin1("f11"); break; - case 111: js = JvNewStringLatin1("f12"); break; - case 105: js = JvNewStringLatin1("f13"); break; - case 114: js = JvNewStringLatin1("insert"); break; - case 117: js = JvNewStringLatin1("delete"); break; - case 116: js = JvNewStringLatin1("page_up"); break; - case 121: js = JvNewStringLatin1("page_down"); break; - case 115: js = JvNewStringLatin1("home"); break; - case 119: js = JvNewStringLatin1("end"); break; - case 71: js = JvNewStringLatin1("num_lock"); break; - case 53: js = JvNewStringLatin1("escape"); break; - case 51: js = JvNewStringLatin1("back_space"); break; - case 36: js = JvNewStringLatin1("enter"); break; - case 48: js = JvNewStringLatin1("tab"); break; - case 76: js = JvNewStringLatin1("enter"); break; // number pad enter - default: { - UInt32 size; - UInt32 modifiers = surface->modifiers; - r = GetEventParameter(e,kEventParamKeyUnicodes,typeUnicodeText,NULL,0,&size,NULL); - checkStatus(r,"GetEventParameter"); - if(size == 0 || (modifiers & controlKey && size>sizeof(UniChar))) return eventNotHandledErr; - - js = JvAllocString(size/sizeof(UniChar)); - UniChar *buf = (UniChar*)JvGetStringChars(js); - r = GetEventParameter(e,kEventParamKeyUnicodes,typeUnicodeText,NULL,size,NULL,buf); - checkStatus(r,"GetEventParameter"); - - if(!buf[0]) return eventNotHandledErr; // shouldn't happen - // odd, when the ctrl key is pressed a-"`" become 1-31, this brings them back to the corect values - if(modifiers & controlKey && buf[0] < 32) buf[0] += 0x60; - break; - } - } - - if(eKind == kEventRawKeyUp) - surface->KeyReleased(js); - else - surface->KeyPressed(js); - return noErr; - } - case kEventRawKeyModifiersChanged: { - const static struct { - UInt32 mask; - jstring xwtKey; - } modifiersTable[] = { - { shiftKey, JvNewStringLatin1("shift") }, - { alphaLock, JvNewStringLatin1("caps_lock") }, - { controlKey, JvNewStringLatin1("control") }, - { optionKey, JvNewStringLatin1("alt") }, - { kEventKeyModifierNumLockMask, JvNewStringLatin1("num_lock") }, - { 0, 0 } - }; - - UInt32 oldModifiers = (UInt32) surface->modifiers; - UInt32 newModifiers; - r = GetEventParameter(e,kEventParamKeyModifiers,typeUInt32,NULL,sizeof(newModifiers),NULL,&newModifiers); - checkStatus(r,"GetEventParameter"); - surface->modifiers = (jint) newModifiers; - UInt32 changedModifiers = oldModifiers ^ newModifiers; - - for(int i=0;modifiersTable[i].mask;i++) { - UInt32 mask = modifiersTable[i].mask; - if(!(changedModifiers & mask)) continue; - if(newModifiers & mask) - surface->KeyPressed(modifiersTable[i].xwtKey); - else - surface->KeyReleased(modifiersTable[i].xwtKey); - } - return noErr; - } - } - break; - case kEventClassMouse: - // The default handler gets first dibs on mouse events - // (this catches the titlebar, resize box, etc) - r = CallNextEventHandler(handler, e); - if(r != eventNotHandledErr && eKind != kEventMouseMoved && eKind != kEventMouseDragged) return r; - - switch(eKind) { - case kEventMouseMoved: - case kEventMouseDragged: { - WindowRef window = (WindowRef) surface->rawWindowRef; - Point p; - Rect rect; - - r = GetEventParameter(e,kEventParamMouseLocation,typeQDPoint,NULL,sizeof(p),NULL,&p); - checkStatus(r,"GetEventParameter"); - r = GetWindowBounds(window,kWindowContentRgn,&rect); - checkStatus(r,"GetWindowBounds"); - surface->Move(p.h-rect.left,p.v-rect.top); - return noErr; - } - case kEventMouseDown: - case kEventMouseUp: { - EventMouseButton button; - UInt32 clickCount; - jint xwtButton; - r = GetEventParameter(e,kEventParamMouseButton,typeMouseButton,NULL,sizeof(button),NULL,&button); - checkStatus(r,"GetEventParameter"); - r = GetEventParameter(e,kEventParamClickCount,typeUInt32,NULL,sizeof(clickCount),NULL,&clickCount); - checkStatus(r,"GetEventParameter"); - - switch(button) { - case kEventMouseButtonPrimary: xwtButton = 1; break; - case kEventMouseButtonSecondary: xwtButton = 2; break; - case kEventMouseButtonTertiary: xwtButton = 3; break; - default: return noErr; - } - if(eKind == kEventMouseDown) { - surface->Press(xwtButton); - } else { - surface->Release(xwtButton); - while(clickCount > 1) { - surface->DoubleClick(xwtButton); - clickCount-=2; - } - if(clickCount) surface->Click(xwtButton); - } - return noErr; - } - case kEventMouseWheelMoved: { - EventMouseWheelAxis axis; - SInt32 delta; - r = GetEventParameter(e,kEventParamMouseWheelAxis,typeMouseWheelAxis,NULL,sizeof(axis),NULL,&axis); - checkStatus(r,"GetEventParameter"); - if(axis != kEventMouseWheelAxisY) break; - r = GetEventParameter(e,kEventParamMouseWheelDelta,typeSInt32,NULL,sizeof(delta),NULL,&delta); - checkStatus(r,"GetEventParameter"); - fprintf(stderr,"kEventMouseWheelMoved: delta: %d",delta); - // surface->MouseWheelMoved(...) IMPROVMENT: mouse wheel support in xwt - return noErr; - } - } - break; - - case kEventClassWindow: { - WindowRef window; - r = GetEventParameter(e,kEventParamDirectObject,typeWindowRef,NULL,sizeof(window),NULL,&window); - checkStatus(r,"kEventClassWindow/GetEventParameter"); - - if((RawData*)window != surface->rawWindowRef) Carbon::abort(JvNewStringLatin1("window != surface->window")); - - switch(eKind) { - case kEventWindowUpdate: { - surface->Dirty(0,0,surface->width,surface->height); - return noErr; - } - case kEventWindowBoundsChanged: { - UInt32 attr; - Rect rect; - r = GetEventParameter(e,kEventParamAttributes,typeUInt32,NULL,sizeof(attr),NULL,&attr); - checkStatus(r,"kEventWindowBoundsChanged/GetEventParameter"); - r = GetWindowBounds(window,kWindowContentRgn,&rect); - checkStatus(r,"GetWindowBounds"); - if(attr & kWindowBoundsChangeSizeChanged) { - jint w = rect.right-rect.left; - jint h = rect.bottom-rect.top; - if(attr & kWindowBoundsChangeUserResize && surface->maximized) - surface->Maximized(false); - surface->reshape(w,h); - surface->SizeChange(w,h); - surface->Dirty(0,0,w,h); - surface->blitDirtyScreenRegions(); - } - if(attr & kWindowBoundsChangeOriginChanged) { - surface->PosChange(rect.left,rect.top); - } - return noErr; - } - case kEventWindowActivated: - case kEventWindowDeactivated: { - surface->Focused(eKind == kEventWindowActivated); - return noErr; - } - case kEventWindowZoomed: { - fprintf(stderr,"Zoomed....\n"); - surface->Maximized(true); - return noErr; - } - case kEventWindowCollapsed: { - surface->Minimized(true); - return noErr; - } - case kEventWindowExpanded: { - surface->Minimized(false); - return noErr; - } - case kEventWindowClose: { - surface->Close(); - return noErr; - } - case kEventWindowClosed: { - DisposeEventHandlerUPP((EventHandlerUPP)surface->rawEventHandlerUPP); - GCJ$Retainer::release(surface); - return noErr; - } - } - } - break; - } - return eventNotHandledErr; -} -} // end namespace - -void Carbon$CarbonSurface::natInit(jboolean framed) { - WindowRef window; - Rect rect; - WindowClass wc = framed ? kDocumentWindowClass : kPlainWindowClass; - // FIXME: unframed windows should appear in the window menu - // This probably needs a hack similar to whats in Cocoa.mm - WindowAttributes attr = kWindowStandardHandlerAttribute| - (framed ? kWindowInWindowMenuAttribute|kWindowStandardDocumentAttributes|kWindowLiveResizeAttribute : 0); - OSStatus r; - - rect.top = 0; rect.left = 0; rect.bottom = 10; rect.right=10; - r = CreateNewWindow(wc,attr,&rect,&window); - checkStatus(r,"CreateNewWindow"); - - GCJ$Retainer::retain(this); // Need to account for the EventHandlers pointer to us - EventHandlerUPP upp = NewEventHandlerUPP(windowEventHandler); - - r = InstallWindowEventHandler(window,upp,sizeof(eventTypeSpecs)/sizeof(EventTypeSpec),eventTypeSpecs,this,NULL); - checkStatus(r,"InstallWindowEventHandler"); - - rawWindowRef = (RawData*) window; - rawEventHandlerUPP = (RawData*) upp; -} - -void Carbon$CarbonSurface::natDispose() { - WindowRef window = (WindowRef) rawWindowRef; - DisposeWindow(window); -} - -void Carbon$CarbonSurface::natSetIcon(org::xwt::Picture *_p) { -} - -void Carbon$CarbonSurface::natSetLocation(jint x, jint y) { - WindowRef window = (WindowRef) rawWindowRef; - Rect rect; - OSStatus r = GetWindowBounds(window,kWindowStructureRgn,&rect); - checkStatus(r,"GetWindowBounds"); - rect.bottom = y + (rect.bottom - rect.top); - rect.right = x + (rect.right - rect.left); - rect.top = y; - rect.left = x; - r = SetWindowBounds(window,kWindowStructureRgn,&rect); - checkStatus(r,"SetWindowBounds"); - r = ConstrainWindowToScreen(window,kWindowStructureRgn,kWindowConstrainMoveRegardlessOfFit,NULL,NULL); - checkStatus(r,"ConstrainWindowToScreen"); -} - -void Carbon$CarbonSurface::natSetSize(jint w, jint h) { - WindowRef window = (WindowRef) rawWindowRef; - Rect rect; - OSStatus r = GetWindowBounds(window,kWindowStructureRgn,&rect); - checkStatus(r,"GetWindowBounds"); - rect.bottom = rect.top + h; - rect.right = rect.left + w; - r = SetWindowBounds(window,kWindowStructureRgn,&rect); - checkStatus(r,"SetWindowBounds"); - r = ConstrainWindowToScreen(window,kWindowStructureRgn,kWindowConstrainMoveRegardlessOfFit,NULL,NULL); - checkStatus(r,"ConstrainWindowToScreen"); -} - -void Carbon$CarbonSurface::natSetLimits(jint minw, jint minh, jint maxw, jint maxh) { - WindowRef window = (WindowRef) rawWindowRef; - const int maxMax = 32767; - const int minMinW = 80; - const int minMinH = 20; - HISize min,max; - min.width = minw > maxMax ? maxMax : (minw < minMinW ? minMinW : minw); - min.height = minh > maxMax ? maxMax : (minh < minMinH ? minMinH : minh); - max.width = maxw > maxMax ? maxMax : (maxw < minMinW ? minMinW : maxw); - max.height = maxh > maxMax ? maxMax : (maxh < minMinH ? minMinH : maxh); - OSStatus r = SetWindowResizeLimits(window,&min,&max); - checkStatus(r,"SetWindowResizeLimits"); -} - - -#pragma mark ------ Carbon Methods ------ -void carbon::fileDialogEventHandler(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *userData) { - Carbon$FileDialogHelper *helper = (Carbon$FileDialogHelper*) userData; - NavDialogRef dialog = callBackParms->context; - OSStatus r; - switch(callBackSelector) { - case kNavCBUserAction: { - NavUserAction action = NavDialogGetUserAction(dialog); - if(action == kNavUserActionNone || action == kNavUserActionCancel) { - helper->fileName = 0; - } else { - NavReplyRecord reply; - r = NavDialogGetReply(dialog,&reply); - checkStatus(r,"NavDialogGetReply"); - - AEKeyword keyword; - FSRef ref; - char buf[4096]; - r = AEGetNthPtr(&reply.selection,1,typeFSRef,&keyword,NULL,&ref,sizeof(ref),NULL); - checkStatus(r,"AEGetNthPtr"); - r = FSRefMakePath(&ref,(UInt8*)buf,sizeof(buf)-1); - checkStatus(r,"FSRefMakePath"); - helper->fileName = JvNewStringLatin1(buf); - if(helper->save) helper->saveName = cfStringToJString(reply.saveFileName); - r = NavDisposeReply(&reply); - checkStatus(r,"NavDialogGetReply"); - } - helper->sem->release(); - break; - } - case kNavCBTerminate: - DisposeNavEventUPP((NavEventUPP)helper->rawUPP); - NavDialogDispose(dialog); - break; - } -} - -void Carbon::natFileDialog(Carbon$FileDialogHelper *helper,jstring suggestion_, jboolean write) { - NavDialogRef dlg; - SmartCFString suggestion = suggestion_; - CFStringRef message = CFSTR("By selecting a file in this dialog you are giving this XWT application permission to access that file."); - OSStatus r; - WindowRef window = FrontWindow(); - NavDialogCreationOptions options; - - NavEventUPP handler = NewNavEventUPP(carbon::fileDialogEventHandler); - - NavGetDefaultDialogCreationOptions(&options); - options.optionFlags = - (options.optionFlags|kNavAllFilesInPopup|kNavSelectAllReadableItem|kNavDontUseCustomFrame|kNavDontConfirmReplacement) - &~(kNavAllowStationery|kNavAllowMultipleFiles); - options.clientName = CFSTR("XWT"); - if(write) - options.saveFileName = suggestion; - options.message = message; - options.modality = window ? kWindowModalityWindowModal : kWindowModalityAppModal; - options.parentWindow = window; - - if(write) - r = NavCreatePutFileDialog(&options,0,0,handler,helper,&dlg); - else - r = NavCreateGetFileDialog(&options,NULL,handler,NULL,NULL,helper,&dlg); - checkStatus(r,"NavCreate(Get/Put)FileDialog"); - - helper->rawUPP = (RawData*)handler; - NavDialogRun(dlg); -} - -jstring Carbon::natGetClipBoard() { - ScrapRef scrap; - OSStatus r; - Size size,size2; - - r = GetCurrentScrap(&scrap); - checkStatus(r,"GetCurrentScrap"); - - r = GetScrapFlavorSize( scrap, kScrapFlavorTypeUnicode, &size); - if(r == scrapFlavorNotFoundErr) return JvNewStringLatin1(""); - checkStatus(r,"GetScrapFlavorSize"); - - unsigned int length = size/sizeof(UniChar); - - jstring js = JvAllocString(length); - UniChar *buf = (UniChar*) JvGetStringChars(js); - size2 = size; - r = GetScrapFlavorData(scrap,kScrapFlavorTypeUnicode,&size2,buf); - if(r == scrapFlavorNotFoundErr); - checkStatus(r,"GetScrapFlavorData"); - if(size2 != size) return JvNewStringLatin1(""); - - return js; -} - -void Carbon::natSetClipBoard(jstring js) { - unsigned int length = js->length(); - ScrapRef scrap; - OSStatus r; - - r = GetCurrentScrap(&scrap); - checkStatus(r,"GetCurrentScrap"); - - r = PutScrapFlavor(scrap,kScrapFlavorTypeUnicode,0,sizeof(UniChar)*length,JvGetStringChars(js)); - checkStatus(r,"PutScrapFlavor"); -} - -Proxy *Carbon::natDetectProxy() { - using org::xwt::Proxy; - Proxy *p=0; - CFStringRef string; - CFNumberRef number; - SmartCFString smartString; - CFArrayRef exceptionList; - int i; - - CFDictionaryRef proxyInfo = SCDynamicStoreCopyProxies(NULL); - if(proxyInfo == NULL) return 0; - -#define doproto(proto,var) \ - number = (CFNumberRef) CFDictionaryGetValue(proxyInfo,kSCPropNetProxies ## proto ## Enable); \ - if(number != NULL && CFGetTypeID(number) != CFNumberGetTypeID()) number = NULL; \ - if(number && CFNumberGetValue(number,kCFNumberIntType,&i) && i) { \ - string = (CFStringRef) CFDictionaryGetValue(proxyInfo, kSCPropNetProxies ## proto ## Proxy);\ - if(string != NULL && CFGetTypeID(string) != CFStringGetTypeID()) string = NULL; \ - number = (CFNumberRef) CFDictionaryGetValue(proxyInfo, kSCPropNetProxies ## proto ## Port); \ - if(number != NULL && CFGetTypeID(number) != CFNumberGetTypeID()) number = NULL; \ - if(string && number && CFNumberGetValue(number,kCFNumberIntType,&i) && i) { \ - if(!p) p = new Proxy(); \ - p->var ## ProxyHost = cfStringToJString(string); \ - p->var ## ProxyPort = i; \ - } \ - } -doproto(HTTP,http) -doproto(HTTPS,https) -doproto(SOCKS,socks) -#undef doproto - - exceptionList = (CFArrayRef) CFDictionaryGetValue(proxyInfo,kSCPropNetProxiesExceptionsList); - if(exceptionList != NULL && CFGetTypeID(exceptionList) != CFArrayGetTypeID()) exceptionList = NULL; - if(p && exceptionList && CFArrayGetCount(exceptionList)) { - CFIndex count = CFArrayGetCount(exceptionList); - p->excluded = (JArray*) - JvNewObjectArray(count,&java::lang::String::class$,0); - for(i=0;iexcluded)[i] = string ? cfStringToJString(string) : JvNewStringLatin1("(null)"); - } - } - CFRelease(proxyInfo); - - return p; -/* - exceptionList = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesExceptionsList]; - if(p && exceptionList && [exceptionList count]) { - NSLog(@"excl: %@",exceptionList); - p->excluded = (JArray*) - JvNewObjectArray([exceptionList count],&java::lang::String::class$,0); - for(i=0;i<[exceptionList count];i++) - elements(p->excluded)[i] = [[exceptionList objectAtIndex: i] jstring]; - } - return p; - */ - -/* - using org::xwt::Proxy; - AutoARP pool; - Proxy *p=0; - NSString *host; - NSNumber *port; - NSArray *exceptionList; - unsigned int i; - NSDictionary *proxyInfo = (NSDictionary*)SCDynamicStoreCopyProxies(NULL); - - if(proxyInfo == NULL) return 0; - if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPEnable] boolValue]) { - host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPProxy]; - port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPPort]; - if(host && [port intValue]) { - if(!p) p = new Proxy(); - p->httpProxyHost = [host jstring]; - p->httpProxyPort = [port intValue]; - } - } - if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSEnable] boolValue]) { - host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSProxy]; - port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSPort]; - if(host && [port intValue]) { - if(!p) p = new Proxy(); - p->httpsProxyHost = [host jstring]; - p->httpsProxyPort = [port intValue]; - } - } - if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSEnable] boolValue]) { - host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSProxy]; - port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSPort]; - if(host && [port intValue]) { - if(!p) p = new Proxy(); - p->socksProxyHost = [host jstring]; - p->socksProxyPort = [port intValue]; - } - } - - exceptionList = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesExceptionsList]; - if(p && exceptionList && [exceptionList count]) { - NSLog(@"excl: %@",exceptionList); - p->excluded = (JArray*) - JvNewObjectArray([exceptionList count],&java::lang::String::class$,0); - for(i=0;i<[exceptionList count];i++) - elements(p->excluded)[i] = [[exceptionList objectAtIndex: i] jstring]; - } - return p; -*/ -} - -jint Carbon::cgScreenWidth() { - return CGDisplayPixelsWide(kCGDirectMainDisplay); -} - -jint Carbon::cgScreenHeight() { - return CGDisplayPixelsHigh(kCGDirectMainDisplay); -} - -void Carbon::_newBrowserWindow(jstring js) { - SmartCFString cfs = js; - CFURLRef url = CFURLCreateWithString(kCFAllocatorDefault,cfs,NULL); - SmartCFString scheme = CFURLCopyScheme(url); - if(scheme.equals(CFStringRef("http"))) - LSOpenCFURLRef(url,NULL); - CFRelease(url); -} - -void Carbon::_exit() { - QuitApplicationEventLoop(); -} - -#define XWT_CARBON_NO_BUNDLE_HACK -#ifdef XWT_CARBON_NO_BUNDLE_HACK -extern "C" { - OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn); - OSErr CPSSetFrontProcess(ProcessSerialNumber *psn); -} -#endif -void Carbon::natInit() { - OSStatus r; - #ifdef XWT_CARBON_NO_BUNDLE_HACK - { - ProcessSerialNumber currentProcess = { 0, kCurrentProcess }; - - ::fprintf(stderr,"Doing XWT_CARBON_NO_BUNDLE_HACK\n"); - r = GetCurrentProcess(¤tProcess); - checkStatus(r,"GetCurrentProcess"); - r = CPSEnableForegroundOperation( ¤tProcess ); - checkStatus(r,"CPSEnableForegroundOperation"); - r = CPSSetFrontProcess(¤tProcess); - checkStatus(r,"CPSSetFrontProcess"); - } - #else - { - IBNibRef nib; - r = CreateNibReference(CFSTR("MainMenu"), &nib); - checkStatus(r,"CreateNibReference"); - r = SetMenuBarFromNib(nib, CFSTR("MenuBar")); - checkStatus(r,"SetMenuBarFromNib"); - DisposeNibReference(nib); - - // FIXME: Install menu event handler - } - #endif -} - -void Carbon::_running() { - RunApplicationEventLoop(); - ExitToShell(); -} - -#pragma mark ------ OpenGL Functions ----- - -void Carbon$CarbonOpenGL::activateSharedContext() { - AGLContext ctx = (AGLContext) rawSharedContext; - aglSetCurrentContext(ctx); -} - -jboolean Carbon$CarbonOpenGL::initPixelFormat() { - GLint attr[] = { - AGL_NO_RECOVERY, - AGL_RGBA, - AGL_DEPTH_SIZE, 32, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_RED_SIZE, 8, - AGL_ALPHA_SIZE, 8, - AGL_NONE - }; - - rawPixelFormat = (RawData*) aglChoosePixelFormat(NULL,0,attr); - return rawPixelFormat != 0; -} - -void Carbon$CarbonOpenGL::initSharedContext() { - AGLPixelFormat fmt = (AGLPixelFormat) rawPixelFormat; - rawSharedContext = (RawData*) aglCreateContext(fmt,NULL); - checkStatus(rawSharedContext,"aglCreateContext"); -} - -void Carbon$GLCarbonDoubleBuffer::natInit() { - WindowClass wc = kPlainWindowClass; - WindowAttributes attr = 0; - WindowRef window; - Rect rect; - OSStatus r; - AGLContext ctx,shared; - AGLPixelFormat fmt; - GLboolean b; - GLuint tex; - GLuint target; - - rect.top = rect.left = 0; - rect.right = width + rect.left; - rect.bottom = height + rect.top; - - r = CreateNewWindow(wc,attr,&rect,&window); - checkStatus(r,"CreateNewWindow"); - - shared = (AGLContext) gl->rawSharedContext; - fmt = (AGLPixelFormat) gl->rawPixelFormat; - ctx = aglCreateContext(fmt,shared); - checkStatus(ctx, "aglCreateContext"); - - b = aglSetDrawable(ctx,GetWindowPort(window)); - checkStatus(b,"aglSetDrawable"); - - aglSetCurrentContext(ctx); - aglUpdateContext(ctx); - drawableInit(width,height); - glClear(GL_COLOR_BUFFER_BIT); - - aglSetCurrentContext(shared); - target = rectTexture ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D; - glEnable(target); - glGenTextures(1,&tex); - glBindTexture(target,tex); - glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - aglSurfaceTexture (shared, target, GL_RGBA, ctx); - checkGLError(); - glDisable(target); - - //ShowWindow(window); - textureName = (jint) tex; - rawWindowRef = (RawData*) window; - rawCTX = (RawData*) ctx; -} - -void Carbon$GLCarbonDoubleBuffer::activateContext() { - AGLContext ctx = (AGLContext) rawCTX; - aglSetCurrentContext(ctx); -} - -void Carbon$GLCarbonDoubleBuffer::natCleanup(RawData* rawWindowRef, RawData* rawCTX) { - WindowRef window = (WindowRef) rawWindowRef; - AGLContext ctx = (AGLContext) rawCTX; - aglDestroyContext(ctx); - DisposeWindow(window); -} - -void Carbon$GLCarbonSurface::natBlit(Carbon$GLCarbonDoubleBuffer *db, jint sx1, jint sy1, jint dx1, jint dy1, jint dx2, jint dy2) { - AGLContext ctx = (AGLContext) rawCTX; - int sx2 = sx1 + (dx2-dx1); - int sy2 = sy1 + (dy2-dy1); - db->activateContext(); - glFlush(); - checkGLError(); - aglSetCurrentContext(ctx); - checkGLError(); - if(db->rectTexture) { - glEnable(GL_TEXTURE_RECTANGLE_EXT); - checkGLError(); - glBindTexture(GL_TEXTURE_RECTANGLE_EXT, db->textureName); - checkGLError(); - glBegin(GL_QUADS); - glTexCoord2i (sx1, sy1 ); - glVertex3i (dx1, dy1, 0); - glTexCoord2i (sx2, sy1 ); - glVertex3i (dx2, dy1, 0); - glTexCoord2i (sx2, sy2 ); - glVertex3i (dx2, dy2, 0); - glTexCoord2i (sx1, sy2 ); - glVertex3i (dx1, dy2, 0); - glEnd(); - checkGLError(); - glDisable(GL_TEXTURE_RECTANGLE_EXT); - checkGLError(); - } else { - float tx1,ty1,tx2,ty2; // normalized texture coords - tx1 = (float) sx1 / (float) db->width; - ty1 = (float) sy1 / (float) db->height; - tx2 = (float) sx2 / (float) db->width; - ty2 = (float) sy2 / (float) db->height; - - glColor4f(1.0f,1.0f,1.0f,1.0f); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, db->textureName); - checkGLError(); - glBegin(GL_QUADS); - glTexCoord2f (tx1, ty1 ); - glVertex3i (dx1, dy1, 0); - glTexCoord2f (tx2, ty1 ); - glVertex3i (dx2, dy1, 0); - glTexCoord2f (tx2, ty2 ); - glVertex3i (dx2, dy2, 0); - glTexCoord2f (tx1, ty2 ); - glVertex3i (dx1, dy2, 0); - glEnd(); - glDisable(GL_TEXTURE_2D); - checkGLError(); - } - glFlush(); -} - -void Carbon$GLCarbonSurface::natReshape(jint w, jint h) { - AGLContext ctx = (AGLContext) rawCTX; - - aglSetCurrentContext (ctx); - aglUpdateContext(ctx); - - glViewport(0, 0, w, h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, w, h, 0, -1, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef (0.375, 0.375, 0.0); - checkGLError(); -} - -void Carbon$GLCarbonSurface::natInit() { - WindowRef window = (WindowRef) rawWindowRef; - AGLContext ctx,shared; - AGLPixelFormat fmt; - GLboolean b; - - shared = (AGLContext) gl->rawSharedContext; - fmt = (AGLPixelFormat) gl->rawPixelFormat; - ctx = aglCreateContext(fmt,shared); - checkStatus(ctx, "aglCreateContext"); - - b = aglSetDrawable(ctx,GetWindowPort(window)); - checkStatus(b,"aglSetDrawable"); - - aglSetCurrentContext(ctx); - checkGLError(); - - rawCTX = (RawData*)ctx; - - reshape(10,10); - - aglSetCurrentContext(ctx); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); -} - -void Carbon$GLCarbonSurface::natDispose() { - AGLContext ctx = (AGLContext) rawCTX; - aglDestroyContext(ctx); - Carbon$CarbonSurface::natDispose(); -} - -} } } // end namepsace org::xwt::plat diff --git a/src/org/xwt/plat/Carbon.java b/src/org/xwt/plat/Carbon.java deleted file mode 100644 index c6ec350..0000000 --- a/src/org/xwt/plat/Carbon.java +++ /dev/null @@ -1,321 +0,0 @@ -// Copyright 2003 Adam Megacz, see the COPYING file for licensing [LGPL] -// Authors: Brian Alliet and Evan Jones - -package org.xwt.plat; - -import gnu.gcj.RawData; -import org.xwt.util.*; -import org.xwt.*; -import java.util.*; - -public class Carbon extends POSIX { - static Carbon singleton; - private CarbonOpenGL openGL; - boolean jaguar; // true if we are on OS X >= 10.2 - - // TEMPORARY HACKS (remove these when we ditch platform fonts) - protected int _stringWidth(String font, String text) { return (int)Math.round(6.5 * text.length()); } - protected int _getMaxAscent(String font) { return 10; } - protected int _getMaxDescent(String font) { return 2; } - - // General Methods - protected String _getAltKeyName() { return "Option"; } - protected boolean _needsAutoClick() { return false; } - protected boolean _needsAutoDoubleClick() { return false; } - protected String getDescriptiveName() { return "GCJ Carbon Binary"; } - protected boolean _isCaseSensitive() { return false; /* Well, not always, could be UFS */ } - - - // Native Methods - protected int _getScreenWidth() { return cgScreenWidth(); } - protected int _getScreenHeight() { return cgScreenHeight(); } - private native static int cgScreenWidth(); - private native static int cgScreenHeight(); - protected native void _newBrowserWindow(String url); - protected native Proxy natDetectProxy(); - private native void natInit(); - protected native void _exit(); - - private native String natGetClipBoard(); - private native void natSetClipBoard(String text); - protected void _setClipBoard(final String text) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetClipBoard(text); } }); } - protected String _getClipBoard() { - final Semaphore sem = new Semaphore(); - final String[] result = new String[1]; // Kind of like a pointer - CarbonMessage.add(new CarbonMessage() { public void perform() { result[0] = natGetClipBoard(); sem.release(); } }); - sem.block(); - return result[0]; - } - - private static class FileDialogHelper { - public FileDialogHelper(boolean save) { this.save = save; } - public boolean save; - public Semaphore sem = new Semaphore(); - public String fileName; - public String saveName; - public RawData rawUPP; - } - private native void natFileDialog(FileDialogHelper helper, String suggestedFileName, boolean write); - protected String _fileDialog(final String fn, final boolean w) { - final FileDialogHelper helper = new FileDialogHelper(w); - CarbonMessage.add(new CarbonMessage() { public void perform() { natFileDialog(helper,fn,w); } }); - helper.sem.block(); - if(w) - return helper.fileName + "/" + helper.saveName; - else - return helper.fileName; - } - - - // Called by main thread after initialization, this is the event handler - protected native void _running(); - - static void abort(String err) { - throw new Error(err); - } - - public Carbon() { - synchronized(Carbon.class) { - if(singleton != null) abort("Tried to instansiate Carbon more than once"); - singleton = this; - } - } - - protected synchronized Proxy _detectProxy() { - return natDetectProxy(); - } - - private static native final boolean isJaguar(); - - public void init() { - super.init(); - jaguar = isJaguar(); - try { - openGL = new CarbonOpenGL(); - openGL.init(); - } catch(OpenGL.NotSupportedException e) { - Log.log(this,"WARNING: OpenGL support not available: " + e); - // FIXME: We need to fallback to Quartz2D - throw new Error("No OpenGL support"); - } - natInit(); - } - - private final class CarbonOpenGL extends OpenGL { - public RawData rawPixelFormat; - public RawData rawSharedContext; - public int maxAglSurfaceTexSize; - public int maxSurfaceWidth; - public int maxSurfaceHeight; - - private native boolean initPixelFormat(); - private native void initSharedContext(); - - public CarbonOpenGL() throws NotSupportedException { - if(!jaguar) - throw new NotSupportedException("OpenGL requires Mac OS X 10.2 or greater"); - if(!initPixelFormat()) - throw new NotSupportedException("Couldn't get an acceptable pixel format"); - initSharedContext(); - } - - public void init() throws NotSupportedException { - super.init(); - maxAglSurfaceTexSize = rectangularTextures ? maxRectTexSize : maxTexSize; - if(renderer.startsWith("ATI Radeon 7500")) { - maxAglSurfaceTexSize = Math.min(rectangularTextures ? 1600 : 1024,maxAglSurfaceTexSize); - Log.log(this,"Working around Radeon 7500 bug: maxAglSurfaceTexSize: " + maxAglSurfaceTexSize); - } - maxSurfaceWidth = maxSurfaceHeight = maxAglSurfaceTexSize; - } - protected native void activateSharedContext(); - } - - static abstract class CarbonSurface extends Surface { - RawData rawWindowRef; - RawData rawEventHandlerUPP; - int modifiers; - - private native void natSetInvisible(boolean i); - public void setInvisible(final boolean i) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetInvisible(i); } }); } - private native void nat_setMaximized(boolean b); - public void _setMaximized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMaximized(b); } }); } - private native void nat_setMinimized(boolean b); - public void _setMinimized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMinimized(b); } }); } - private native void natSetIcon(Picture p); - public void setIcon(final Picture p) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetIcon(p); } }); } - private native void natSetTitleBarText(String s); - public void setTitleBarText(final String s) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetTitleBarText(s); } }); } - private native void natSetSize(int w, int h); - public void setSize(final int w, final int h) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetSize(w,h); } }); } - private native void natSetLocation(int x, int y); - public void setLocation(final int x, final int y) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLocation(x,y); } }); } - private native void natToFront(); - public void toFront() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToFront(); } }); } - private native void natToBack(); - public void toBack() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToBack(); } }); } - private native void natSetLimits(int minWidth, int minHeight, int maxWidth, int maxHeight); - public void setLimits(final int mnw, final int mnh, final int mxw, final int mxh) { - if(Carbon.singleton.jaguar) - CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLimits(mnw,mnh,mxw,mxh); } }); - } - private native void natSyncCursor(int n); - public void syncCursor() { - int n; - if(cursor.equals("default")) n = 0; - else if(cursor.equals("wait")) n = 1; - else if(cursor.equals("crosshair")) n = 2; - else if(cursor.equals("text")) n = 3; - else if(cursor.equals("hand")) n = 4; - else if(cursor.equals("move")) n = 5; - else if(cursor.equals("east") || cursor.equals("west")) n = 6; - else n = 0; - final int n_ = n; - CarbonMessage.add(new CarbonMessage() { public void perform() { natSyncCursor(n_); } }); - } - - public void _sizeChange(int w, int h) { SizeChange(w,h); } - - /* Drawing stuff */ - public abstract void blit(DoubleBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2); - - public final void _dispose() { CarbonMessage.add(new CarbonMessage() { public void perform() { natDispose(); } }); } - public native void natDispose(); - - public final native void natInit(boolean framed); - - public CarbonSurface(Box root, final boolean framed) { - super(root); - final Semaphore sem = new Semaphore(); - CarbonMessage.add(new CarbonMessage() { public void perform() { CarbonSurface.this.natInit(framed); sem.release(); } }); - sem.block(); - } - - public void reshape(int w, int h) { } - } - - static class GLCarbonDoubleBuffer extends OpenGL.GLDoubleBuffer { - RawData rawCTX; - RawData rawWindowRef; - int textureName; - boolean rectTexture; - CarbonOpenGL gl; - - private native void natInit(); - private static native void natCleanup(RawData rawWindowRef, RawData rawCTX); - - - private static final int fixupDimension(CarbonOpenGL gl, int n) { - if(!gl.rectangularTextures) n = OpenGL.roundToPowerOf2(n); - return Math.min(n,gl.maxAglSurfaceTexSize); - } - public GLCarbonDoubleBuffer(int w, int h, final CarbonOpenGL gl) { - super(fixupDimension(gl,w),fixupDimension(gl,h)); - this.gl = gl; - rectTexture = gl.hasRectangularTextures(); - final Semaphore sem = new Semaphore(); - CarbonMessage.add(new CarbonMessage() { public void perform() { GLCarbonDoubleBuffer.this.natInit(); sem.release(); } }); - sem.block(); - } - public native void activateContext(); - protected void finalize() { - CarbonMessage.add(new CarbonMessage() { public void perform() { natCleanup(rawWindowRef,rawCTX); } }); - gl.deleteTexture(textureName); - } - } - - static class GLCarbonSurface extends CarbonSurface { - RawData rawCTX; - CarbonOpenGL gl; - boolean sizeChange; - - private final native void natInit(); - - public GLCarbonSurface(Box root, boolean framed, CarbonOpenGL gl) { - super(root,framed); - this.gl = gl; - natInit(); - } - - public void setLimits(int mnw,int mnh, int mxw, int mxh) { - mxw = Math.min(mxw,gl.maxSurfaceWidth); - mxh = Math.min(mxh,gl.maxSurfaceHeight); - super.setLimits(mnw,mnh,mxw,mxh); - } - public void _sizeChange(int w, int h) { - sizeChange = true; - super._sizeChange(w,h); - } - - public void setSize(int w, int h) { - sizeChange = true; - w = Math.min(w,gl.maxSurfaceWidth); - h = Math.min(h,gl.maxSurfaceWidth); - super.setSize(w,h); - } - - private native void natBlit(GLCarbonDoubleBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2); - public synchronized void blit(DoubleBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2) { - natBlit((GLCarbonDoubleBuffer)db,sx,sy,dx,dy,dx2,dy2); - } - - private native void natReshape(int w, int h); - public synchronized void reshape(int w, int h) { natReshape(w,h); } - - public native void natDispose(); - } - - /*private class QZCarbonDoubleBuffer extends DoubleBuffer { - - public QZCarbonDoubleBuffer(int width, int height) { - } - } - - private class QZCarbonSurface extends CarbonSurface { - public QZCarbonSurface(Box root, boolean framed) { - super(b,root); - } - public native void blit(DoubleBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2); - } - - private class QZCarbonPicture extends Picture { - int width; - int height; - - public final int getWidth() { return width; } - public final int getHeight() { return height; } - - public QZCarbonPicture(int w, int h) { - this.width = w; - this.height = h; - } - }*/ - - protected DoubleBuffer _createDoubleBuffer(int w, int h, Surface owner) { - if(openGL != null) - return new GLCarbonDoubleBuffer(w,h,openGL); - else - return /*new QZCarbonDoubleBuffer(w,h)*/ null; - } - protected Surface _createSurface(Box b, boolean framed) { - if(openGL != null) - return new GLCarbonSurface(b,framed, openGL); - else - return /*new QZCarbonSufrace(b,framed)*/ null; - } - protected Picture _createPicture(int[] data, int w, int h) { - if(openGL != null) - return openGL.createPicture(data,w,h); - else - return /*new QZCarbonPicture(data,w,h);*/ null; - } - - /* A message that is sent through the carbon event queue */ - private static abstract class CarbonMessage { - public abstract void perform(); - - static { natInit(); } - public static native void natInit(); - public static native void add(CarbonMessage m); - } -} diff --git a/src/org/xwt/plat/Darwin.cc b/src/org/xwt/plat/Darwin.cc index 824aa56..914ba77 100644 --- a/src/org/xwt/plat/Darwin.cc +++ b/src/org/xwt/plat/Darwin.cc @@ -1,2 +1,1061 @@ -#include -#include "X11.cc" +// Copyright 2003 Adam Megacz, see the COPYING file for licensing [LGPL] +// Authors: Brian Alliet and Evan Jones +#ifndef __APPLE_CC__ +#define FSF_GCC +#define __APPLE_CC__ +#else +#define APPLE_GCC +#endif + +#include "POSIX.cc" +#include "OpenGL.cc" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +// For proxy stuff +#include +// For LSOpenURLRef +#include + +#include + +#include + +using namespace org::xwt::plat; +using gnu::gcj::RawData; +using org::xwt::util::Semaphore; +using java::lang::Object; + +namespace org { namespace xwt { namespace plat { + +namespace carbon { } +using namespace carbon; + +#pragma mark ------ Carbon Namespace ------ +namespace carbon { + // We put everything that isn't in org.xwt.plat.Carbon in + // org.xwt.plat.carbon to prevent namespace conflicts + + template static inline int CompileTimeCheck() { const int something_is_wrong=1; something_is_wrong++; return 0; } + template <> static inline int CompileTimeCheck() { return 0; } + const static int unichar_check = CompileTimeCheck(); + + void funcFailed(char *func,int r); + static inline void checkStatus(OSStatus r, char *func) { if(r != noErr) funcFailed(func,r); } + static inline void checkStatus(GLboolean b, char *func) { if(!b) funcFailed(func,-1); } + static inline void checkStatus(void *p, char *func) { if(!p) funcFailed(func,-1); } + + jstring cfStringToJString(CFStringRef s) { + CFIndex length = CFStringGetLength(s); + CFRange range = CFRangeMake(0,length); + jstring js = JvAllocString(length); + UniChar *buf = (UniChar*)JvGetStringChars(js); + CFStringGetCharacters(s,range,buf); + return js; + } + + #pragma mark ------ SmartCFString ------ + class SmartCFString { + private: + CFStringRef p; + void release() { if(p) CFRelease(p); } + void checkNull() { if(!p) throw new java::lang::Error(JvNewStringLatin1("CFString function failed")); } + public: + // Constructors + SmartCFString() : p(0) { } + SmartCFString(const char *s) : p(0) { *this = s; } + SmartCFString(jstring js) : p(0) { *this = js; } + SmartCFString(CFStringRef cf) : p(0) { *this = cf; } + // Destructor + ~SmartCFString() { release(); } + // Assignment + SmartCFString& operator= (const char *s) { + release(); + if(!s) s = "(null)"; + p = CFStringCreateWithCString(kCFAllocatorDefault,s,kCFStringEncodingISOLatin1); + checkNull(); + return *this; + } + SmartCFString& operator= (jstring js) { + if(!js) return *this = "(null)"; + release(); + UniChar *buf = (UniChar*) JvGetStringChars(js); + CFIndex length = js->length(); + p = CFStringCreateWithCharacters(kCFAllocatorDefault,buf,length); + checkNull(); + return *this; + } + SmartCFString& operator= (CFStringRef cf) { + if(cf == NULL) return *this = "(null)"; + release(); + p = cf; + return *this; + } + operator CFStringRef() { return p; } + operator jstring() { return getJString(); } + + jstring getJString() { return cfStringToJString(p); } + + bool equals(const char *s) { + SmartCFString cfs(s); + return equals(cfs); + } + + bool equals(CFStringRef cfs) { + return CFStringCompare(p,cfs,0) == kCFCompareEqualTo; + } + }; + + // CHECKME: Is just making up your own four char codes really correct? + const static UInt32 kEventClassCarbonMessage = 'xwta'; + const static UInt32 kEventCarbonMessage = 'xwtb'; + const static UInt32 kEventParamCarbonMessage = 'xwtc'; + + pascal OSStatus carbon::carbonMessageEventHandler(EventHandlerCallRef handler, EventRef e, void *userData); + void fileDialogEventHandler(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *userData); + +} // end namespace + +jboolean Carbon::isJaguar() { + SInt32 version; + OSStatus r = Gestalt(gestaltSystemVersion, &version); + checkStatus(r,"Gestalt"); + return version >= 0x1020; +} + +void Carbon$CarbonMessage::natInit() { + OSStatus r; + + EventHandlerUPP upp = NewEventHandlerUPP(carbonMessageEventHandler); + EventTypeSpec eventTypes = { kEventClassCarbonMessage, kEventCarbonMessage }; + r = InstallEventHandler(GetApplicationEventTarget(),upp,1,&eventTypes,NULL,NULL); + checkStatus(r,"InstallEventHandler"); +} + +void Carbon$CarbonMessage::add(Carbon$CarbonMessage *msg) { + EventRef event; + OSStatus r; + + GCJ$Retainer::retain(msg); + + r = CreateEvent(kCFAllocatorDefault,kEventClassCarbonMessage,kEventCarbonMessage,0,kEventAttributeNone,&event); + checkStatus(r,"CreateEvent"); + r = SetEventParameter(event,kEventParamCarbonMessage,typeVoidPtr,sizeof(msg),(void*)&msg); + checkStatus(r,"SetEventParameter"); + r = PostEventToQueue(GetMainEventQueue(),event,kEventPriorityHigh); + checkStatus(r,"PostEventToQueue"); + ReleaseEvent(event); +} + + +pascal OSStatus carbon::carbonMessageEventHandler(EventHandlerCallRef handler, EventRef e, void *userData) { + UInt32 eKind = GetEventKind(e); + UInt32 eClass = GetEventClass(e); + OSStatus r; + Carbon$CarbonMessage *msg; + if(eClass != kEventClassCarbonMessage || eKind != kEventCarbonMessage) + return eventNotHandledErr; + r = GetEventParameter(e,kEventParamCarbonMessage,typeVoidPtr,NULL,sizeof(msg),NULL,&msg); + checkStatus(r,"GetEventParameter"); + msg->perform(); + GCJ$Retainer::release(msg); + return noErr; +} + + +#pragma mark ------ Utility Functions ------ + +void carbon::funcFailed(char *func,int r){ + fprintf(stderr,"%s() failed (%d)\n",func,r); + exit(EXIT_FAILURE); +} + +#pragma mark ------ CarbonPicture Methods ------ + +#pragma mark ----- Carbon Surface Methods ---- + + +void Carbon$CarbonSurface::natSyncCursor(jint n) { + ThemeCursor c; + // see Carbon.java for what these numbers mean + switch(n) { + case 1: c = kThemeWatchCursor; + case 2: c = kThemePlusCursor; + case 3: c = kThemeIBeamCursor; + case 4: c = kThemePointingHandCursor; + case 5: c = kThemeOpenHandCursor; + case 6: c = kThemeResizeLeftRightCursor; + default: c = kThemeArrowCursor; + } + SetThemeCursor(c); +} + +void Carbon$CarbonSurface::natSetInvisible(jboolean b) { + WindowRef window = (WindowRef) rawWindowRef; + fprintf(stderr,"Making window %s\n",b?"invisible":"visible"); + if(b) HideWindow(window); + else ShowWindow(window); +} + +void Carbon$CarbonSurface::nat_setMaximized(jboolean b) { + WindowRef window = (WindowRef) rawWindowRef; + Point ideal = { 10000, 10000 }; + OSStatus r = ZoomWindowIdeal(window,(b?inZoomOut:inZoomIn),&ideal); + checkStatus(r,"ZoomWindowIdeal"); +} + +void Carbon$CarbonSurface::nat_setMinimized(jboolean b) { + WindowRef window = (WindowRef) rawWindowRef; + if((IsWindowCollapsed(window) ? 1 : 0) == (b ? 1 : 0)) return; + OSStatus r = CollapseWindow(window,b); + checkStatus(r,"CollapseWindow"); +} + +void Carbon$CarbonSurface::natSetTitleBarText(jstring js) { + SmartCFString s = js; + WindowRef window = (WindowRef) rawWindowRef; + SetWindowTitleWithCFString(window,s); +} + +void Carbon$CarbonSurface::natToBack() { + WindowRef window = (WindowRef) rawWindowRef; + SendBehind(window,NULL); +} + +void Carbon$CarbonSurface::natToFront() { + WindowRef window = (WindowRef) rawWindowRef; + fprintf(stderr,"SelectWindow()\n"); + SelectWindow(window); +} + +#pragma mark ---- Window Event Handler ---- +namespace carbon { +static const EventTypeSpec eventTypeSpecs[] = { + // kEventClassCommand + // { kEventClassCommand, ??? }, + + // kEventClassWindow + { kEventClassWindow, kEventWindowUpdate }, + { kEventClassWindow, kEventWindowBoundsChanged }, + { kEventClassWindow, kEventWindowActivated }, + { kEventClassWindow, kEventWindowDeactivated }, + { kEventClassWindow, kEventWindowZoomed }, + { kEventClassWindow, kEventWindowCollapsed }, + { kEventClassWindow, kEventWindowExpanded }, + { kEventClassWindow, kEventWindowClose }, + { kEventClassWindow, kEventWindowClosed }, + + // kEventClassKeyboard + { kEventClassKeyboard, kEventRawKeyDown }, + { kEventClassKeyboard, kEventRawKeyRepeat }, + { kEventClassKeyboard, kEventRawKeyUp }, + { kEventClassKeyboard, kEventRawKeyModifiersChanged }, + + // kEventClassMouse + { kEventClassMouse, kEventMouseDown }, + { kEventClassMouse, kEventMouseUp }, + { kEventClassMouse, kEventMouseMoved }, + { kEventClassMouse, kEventMouseDragged }, + { kEventClassMouse, kEventMouseWheelMoved }, +}; + +pascal OSStatus windowEventHandler(EventHandlerCallRef handler, EventRef e, void *userData) { + Carbon$CarbonSurface *surface = (Carbon$CarbonSurface*) userData; + UInt32 eKind = GetEventKind(e); + UInt32 eClass = GetEventClass(e); + OSStatus r; + + switch(eClass) { + case kEventClassCommand: + switch(eKind) { + // TODO: handle menu items + } + break; + case kEventClassKeyboard: + switch(eKind) { + case kEventRawKeyDown: + case kEventRawKeyRepeat: + case kEventRawKeyUp: { + UInt32 keyCode; + jstring js; + + r = GetEventParameter(e,kEventParamKeyCode,typeUInt32,NULL,sizeof(keyCode),NULL,&keyCode); + checkStatus(r,"GetEventParameter"); + + switch(keyCode) { + // These values were obtained by experimentation. I can't find any constants for them + // in the header files + case 126: js = JvNewStringLatin1("up"); break; + case 125: js = JvNewStringLatin1("down"); break; + case 124: js = JvNewStringLatin1("right"); break; + case 123: js = JvNewStringLatin1("left"); break; + case 122: js = JvNewStringLatin1("f1"); break; + case 120: js = JvNewStringLatin1("f2"); break; + case 99: js = JvNewStringLatin1("f3"); break; + case 118: js = JvNewStringLatin1("f4"); break; + case 96: js = JvNewStringLatin1("f5"); break; + case 97: js = JvNewStringLatin1("f6"); break; + case 98: js = JvNewStringLatin1("f7"); break; + case 100: js = JvNewStringLatin1("f8"); break; + case 101: js = JvNewStringLatin1("f9"); break; + case 109: js = JvNewStringLatin1("f10"); break; + case 103: js = JvNewStringLatin1("f11"); break; + case 111: js = JvNewStringLatin1("f12"); break; + case 105: js = JvNewStringLatin1("f13"); break; + case 114: js = JvNewStringLatin1("insert"); break; + case 117: js = JvNewStringLatin1("delete"); break; + case 116: js = JvNewStringLatin1("page_up"); break; + case 121: js = JvNewStringLatin1("page_down"); break; + case 115: js = JvNewStringLatin1("home"); break; + case 119: js = JvNewStringLatin1("end"); break; + case 71: js = JvNewStringLatin1("num_lock"); break; + case 53: js = JvNewStringLatin1("escape"); break; + case 51: js = JvNewStringLatin1("back_space"); break; + case 36: js = JvNewStringLatin1("enter"); break; + case 48: js = JvNewStringLatin1("tab"); break; + case 76: js = JvNewStringLatin1("enter"); break; // number pad enter + default: { + UInt32 size; + UInt32 modifiers = surface->modifiers; + r = GetEventParameter(e,kEventParamKeyUnicodes,typeUnicodeText,NULL,0,&size,NULL); + checkStatus(r,"GetEventParameter"); + if(size == 0 || (modifiers & controlKey && size>sizeof(UniChar))) return eventNotHandledErr; + + js = JvAllocString(size/sizeof(UniChar)); + UniChar *buf = (UniChar*)JvGetStringChars(js); + r = GetEventParameter(e,kEventParamKeyUnicodes,typeUnicodeText,NULL,size,NULL,buf); + checkStatus(r,"GetEventParameter"); + + if(!buf[0]) return eventNotHandledErr; // shouldn't happen + // odd, when the ctrl key is pressed a-"`" become 1-31, this brings them back to the corect values + if(modifiers & controlKey && buf[0] < 32) buf[0] += 0x60; + break; + } + } + + if(eKind == kEventRawKeyUp) + surface->KeyReleased(js); + else + surface->KeyPressed(js); + return noErr; + } + case kEventRawKeyModifiersChanged: { + const static struct { + UInt32 mask; + jstring xwtKey; + } modifiersTable[] = { + { shiftKey, JvNewStringLatin1("shift") }, + { alphaLock, JvNewStringLatin1("caps_lock") }, + { controlKey, JvNewStringLatin1("control") }, + { optionKey, JvNewStringLatin1("alt") }, + { kEventKeyModifierNumLockMask, JvNewStringLatin1("num_lock") }, + { 0, 0 } + }; + + UInt32 oldModifiers = (UInt32) surface->modifiers; + UInt32 newModifiers; + r = GetEventParameter(e,kEventParamKeyModifiers,typeUInt32,NULL,sizeof(newModifiers),NULL,&newModifiers); + checkStatus(r,"GetEventParameter"); + surface->modifiers = (jint) newModifiers; + UInt32 changedModifiers = oldModifiers ^ newModifiers; + + for(int i=0;modifiersTable[i].mask;i++) { + UInt32 mask = modifiersTable[i].mask; + if(!(changedModifiers & mask)) continue; + if(newModifiers & mask) + surface->KeyPressed(modifiersTable[i].xwtKey); + else + surface->KeyReleased(modifiersTable[i].xwtKey); + } + return noErr; + } + } + break; + case kEventClassMouse: + // The default handler gets first dibs on mouse events + // (this catches the titlebar, resize box, etc) + r = CallNextEventHandler(handler, e); + if(r != eventNotHandledErr && eKind != kEventMouseMoved && eKind != kEventMouseDragged) return r; + + switch(eKind) { + case kEventMouseMoved: + case kEventMouseDragged: { + WindowRef window = (WindowRef) surface->rawWindowRef; + Point p; + Rect rect; + + r = GetEventParameter(e,kEventParamMouseLocation,typeQDPoint,NULL,sizeof(p),NULL,&p); + checkStatus(r,"GetEventParameter"); + r = GetWindowBounds(window,kWindowContentRgn,&rect); + checkStatus(r,"GetWindowBounds"); + surface->Move(p.h-rect.left,p.v-rect.top); + return noErr; + } + case kEventMouseDown: + case kEventMouseUp: { + EventMouseButton button; + UInt32 clickCount; + jint xwtButton; + r = GetEventParameter(e,kEventParamMouseButton,typeMouseButton,NULL,sizeof(button),NULL,&button); + checkStatus(r,"GetEventParameter"); + r = GetEventParameter(e,kEventParamClickCount,typeUInt32,NULL,sizeof(clickCount),NULL,&clickCount); + checkStatus(r,"GetEventParameter"); + + switch(button) { + case kEventMouseButtonPrimary: xwtButton = 1; break; + case kEventMouseButtonSecondary: xwtButton = 2; break; + case kEventMouseButtonTertiary: xwtButton = 3; break; + default: return noErr; + } + if(eKind == kEventMouseDown) { + surface->Press(xwtButton); + } else { + surface->Release(xwtButton); + while(clickCount > 1) { + surface->DoubleClick(xwtButton); + clickCount-=2; + } + if(clickCount) surface->Click(xwtButton); + } + return noErr; + } + case kEventMouseWheelMoved: { + EventMouseWheelAxis axis; + SInt32 delta; + r = GetEventParameter(e,kEventParamMouseWheelAxis,typeMouseWheelAxis,NULL,sizeof(axis),NULL,&axis); + checkStatus(r,"GetEventParameter"); + if(axis != kEventMouseWheelAxisY) break; + r = GetEventParameter(e,kEventParamMouseWheelDelta,typeSInt32,NULL,sizeof(delta),NULL,&delta); + checkStatus(r,"GetEventParameter"); + fprintf(stderr,"kEventMouseWheelMoved: delta: %d",delta); + // surface->MouseWheelMoved(...) IMPROVMENT: mouse wheel support in xwt + return noErr; + } + } + break; + + case kEventClassWindow: { + WindowRef window; + r = GetEventParameter(e,kEventParamDirectObject,typeWindowRef,NULL,sizeof(window),NULL,&window); + checkStatus(r,"kEventClassWindow/GetEventParameter"); + + if((RawData*)window != surface->rawWindowRef) Carbon::abort(JvNewStringLatin1("window != surface->window")); + + switch(eKind) { + case kEventWindowUpdate: { + surface->Dirty(0,0,surface->width,surface->height); + return noErr; + } + case kEventWindowBoundsChanged: { + UInt32 attr; + Rect rect; + r = GetEventParameter(e,kEventParamAttributes,typeUInt32,NULL,sizeof(attr),NULL,&attr); + checkStatus(r,"kEventWindowBoundsChanged/GetEventParameter"); + r = GetWindowBounds(window,kWindowContentRgn,&rect); + checkStatus(r,"GetWindowBounds"); + if(attr & kWindowBoundsChangeSizeChanged) { + jint w = rect.right-rect.left; + jint h = rect.bottom-rect.top; + if(attr & kWindowBoundsChangeUserResize && surface->maximized) + surface->Maximized(false); + surface->reshape(w,h); + surface->SizeChange(w,h); + surface->Dirty(0,0,w,h); + surface->blitDirtyScreenRegions(); + } + if(attr & kWindowBoundsChangeOriginChanged) { + surface->PosChange(rect.left,rect.top); + } + return noErr; + } + case kEventWindowActivated: + case kEventWindowDeactivated: { + surface->Focused(eKind == kEventWindowActivated); + return noErr; + } + case kEventWindowZoomed: { + fprintf(stderr,"Zoomed....\n"); + surface->Maximized(true); + return noErr; + } + case kEventWindowCollapsed: { + surface->Minimized(true); + return noErr; + } + case kEventWindowExpanded: { + surface->Minimized(false); + return noErr; + } + case kEventWindowClose: { + surface->Close(); + return noErr; + } + case kEventWindowClosed: { + DisposeEventHandlerUPP((EventHandlerUPP)surface->rawEventHandlerUPP); + GCJ$Retainer::release(surface); + return noErr; + } + } + } + break; + } + return eventNotHandledErr; +} +} // end namespace + +void Carbon$CarbonSurface::natInit(jboolean framed) { + WindowRef window; + Rect rect; + WindowClass wc = framed ? kDocumentWindowClass : kPlainWindowClass; + // FIXME: unframed windows should appear in the window menu + // This probably needs a hack similar to whats in Cocoa.mm + WindowAttributes attr = kWindowStandardHandlerAttribute| + (framed ? kWindowInWindowMenuAttribute|kWindowStandardDocumentAttributes|kWindowLiveResizeAttribute : 0); + OSStatus r; + + rect.top = 0; rect.left = 0; rect.bottom = 10; rect.right=10; + r = CreateNewWindow(wc,attr,&rect,&window); + checkStatus(r,"CreateNewWindow"); + + GCJ$Retainer::retain(this); // Need to account for the EventHandlers pointer to us + EventHandlerUPP upp = NewEventHandlerUPP(windowEventHandler); + + r = InstallWindowEventHandler(window,upp,sizeof(eventTypeSpecs)/sizeof(EventTypeSpec),eventTypeSpecs,this,NULL); + checkStatus(r,"InstallWindowEventHandler"); + + rawWindowRef = (RawData*) window; + rawEventHandlerUPP = (RawData*) upp; +} + +void Carbon$CarbonSurface::natDispose() { + WindowRef window = (WindowRef) rawWindowRef; + DisposeWindow(window); +} + +void Carbon$CarbonSurface::natSetIcon(org::xwt::Picture *_p) { +} + +void Carbon$CarbonSurface::natSetLocation(jint x, jint y) { + WindowRef window = (WindowRef) rawWindowRef; + Rect rect; + OSStatus r = GetWindowBounds(window,kWindowStructureRgn,&rect); + checkStatus(r,"GetWindowBounds"); + rect.bottom = y + (rect.bottom - rect.top); + rect.right = x + (rect.right - rect.left); + rect.top = y; + rect.left = x; + r = SetWindowBounds(window,kWindowStructureRgn,&rect); + checkStatus(r,"SetWindowBounds"); + r = ConstrainWindowToScreen(window,kWindowStructureRgn,kWindowConstrainMoveRegardlessOfFit,NULL,NULL); + checkStatus(r,"ConstrainWindowToScreen"); +} + +void Carbon$CarbonSurface::natSetSize(jint w, jint h) { + WindowRef window = (WindowRef) rawWindowRef; + Rect rect; + OSStatus r = GetWindowBounds(window,kWindowStructureRgn,&rect); + checkStatus(r,"GetWindowBounds"); + rect.bottom = rect.top + h; + rect.right = rect.left + w; + r = SetWindowBounds(window,kWindowStructureRgn,&rect); + checkStatus(r,"SetWindowBounds"); + r = ConstrainWindowToScreen(window,kWindowStructureRgn,kWindowConstrainMoveRegardlessOfFit,NULL,NULL); + checkStatus(r,"ConstrainWindowToScreen"); +} + +void Carbon$CarbonSurface::natSetLimits(jint minw, jint minh, jint maxw, jint maxh) { + WindowRef window = (WindowRef) rawWindowRef; + const int maxMax = 32767; + const int minMinW = 80; + const int minMinH = 20; + HISize min,max; + min.width = minw > maxMax ? maxMax : (minw < minMinW ? minMinW : minw); + min.height = minh > maxMax ? maxMax : (minh < minMinH ? minMinH : minh); + max.width = maxw > maxMax ? maxMax : (maxw < minMinW ? minMinW : maxw); + max.height = maxh > maxMax ? maxMax : (maxh < minMinH ? minMinH : maxh); + OSStatus r = SetWindowResizeLimits(window,&min,&max); + checkStatus(r,"SetWindowResizeLimits"); +} + + +#pragma mark ------ Carbon Methods ------ +void carbon::fileDialogEventHandler(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *userData) { + Carbon$FileDialogHelper *helper = (Carbon$FileDialogHelper*) userData; + NavDialogRef dialog = callBackParms->context; + OSStatus r; + switch(callBackSelector) { + case kNavCBUserAction: { + NavUserAction action = NavDialogGetUserAction(dialog); + if(action == kNavUserActionNone || action == kNavUserActionCancel) { + helper->fileName = 0; + } else { + NavReplyRecord reply; + r = NavDialogGetReply(dialog,&reply); + checkStatus(r,"NavDialogGetReply"); + + AEKeyword keyword; + FSRef ref; + char buf[4096]; + r = AEGetNthPtr(&reply.selection,1,typeFSRef,&keyword,NULL,&ref,sizeof(ref),NULL); + checkStatus(r,"AEGetNthPtr"); + r = FSRefMakePath(&ref,(UInt8*)buf,sizeof(buf)-1); + checkStatus(r,"FSRefMakePath"); + helper->fileName = JvNewStringLatin1(buf); + if(helper->save) helper->saveName = cfStringToJString(reply.saveFileName); + r = NavDisposeReply(&reply); + checkStatus(r,"NavDialogGetReply"); + } + helper->sem->release(); + break; + } + case kNavCBTerminate: + DisposeNavEventUPP((NavEventUPP)helper->rawUPP); + NavDialogDispose(dialog); + break; + } +} + +void Carbon::natFileDialog(Carbon$FileDialogHelper *helper,jstring suggestion_, jboolean write) { + NavDialogRef dlg; + SmartCFString suggestion = suggestion_; + CFStringRef message = CFSTR("By selecting a file in this dialog you are giving this XWT application permission to access that file."); + OSStatus r; + WindowRef window = FrontWindow(); + NavDialogCreationOptions options; + + NavEventUPP handler = NewNavEventUPP(carbon::fileDialogEventHandler); + + NavGetDefaultDialogCreationOptions(&options); + options.optionFlags = + (options.optionFlags|kNavAllFilesInPopup|kNavSelectAllReadableItem|kNavDontUseCustomFrame|kNavDontConfirmReplacement) + &~(kNavAllowStationery|kNavAllowMultipleFiles); + options.clientName = CFSTR("XWT"); + if(write) + options.saveFileName = suggestion; + options.message = message; + options.modality = window ? kWindowModalityWindowModal : kWindowModalityAppModal; + options.parentWindow = window; + + if(write) + r = NavCreatePutFileDialog(&options,0,0,handler,helper,&dlg); + else + r = NavCreateGetFileDialog(&options,NULL,handler,NULL,NULL,helper,&dlg); + checkStatus(r,"NavCreate(Get/Put)FileDialog"); + + helper->rawUPP = (RawData*)handler; + NavDialogRun(dlg); +} + +jstring Carbon::natGetClipBoard() { + ScrapRef scrap; + OSStatus r; + Size size,size2; + + r = GetCurrentScrap(&scrap); + checkStatus(r,"GetCurrentScrap"); + + r = GetScrapFlavorSize( scrap, kScrapFlavorTypeUnicode, &size); + if(r == scrapFlavorNotFoundErr) return JvNewStringLatin1(""); + checkStatus(r,"GetScrapFlavorSize"); + + unsigned int length = size/sizeof(UniChar); + + jstring js = JvAllocString(length); + UniChar *buf = (UniChar*) JvGetStringChars(js); + size2 = size; + r = GetScrapFlavorData(scrap,kScrapFlavorTypeUnicode,&size2,buf); + if(r == scrapFlavorNotFoundErr); + checkStatus(r,"GetScrapFlavorData"); + if(size2 != size) return JvNewStringLatin1(""); + + return js; +} + +void Carbon::natSetClipBoard(jstring js) { + unsigned int length = js->length(); + ScrapRef scrap; + OSStatus r; + + r = GetCurrentScrap(&scrap); + checkStatus(r,"GetCurrentScrap"); + + r = PutScrapFlavor(scrap,kScrapFlavorTypeUnicode,0,sizeof(UniChar)*length,JvGetStringChars(js)); + checkStatus(r,"PutScrapFlavor"); +} + +Proxy *Carbon::natDetectProxy() { + using org::xwt::Proxy; + Proxy *p=0; + CFStringRef string; + CFNumberRef number; + SmartCFString smartString; + CFArrayRef exceptionList; + int i; + + CFDictionaryRef proxyInfo = SCDynamicStoreCopyProxies(NULL); + if(proxyInfo == NULL) return 0; + +#define doproto(proto,var) \ + number = (CFNumberRef) CFDictionaryGetValue(proxyInfo,kSCPropNetProxies ## proto ## Enable); \ + if(number != NULL && CFGetTypeID(number) != CFNumberGetTypeID()) number = NULL; \ + if(number && CFNumberGetValue(number,kCFNumberIntType,&i) && i) { \ + string = (CFStringRef) CFDictionaryGetValue(proxyInfo, kSCPropNetProxies ## proto ## Proxy);\ + if(string != NULL && CFGetTypeID(string) != CFStringGetTypeID()) string = NULL; \ + number = (CFNumberRef) CFDictionaryGetValue(proxyInfo, kSCPropNetProxies ## proto ## Port); \ + if(number != NULL && CFGetTypeID(number) != CFNumberGetTypeID()) number = NULL; \ + if(string && number && CFNumberGetValue(number,kCFNumberIntType,&i) && i) { \ + if(!p) p = new Proxy(); \ + p->var ## ProxyHost = cfStringToJString(string); \ + p->var ## ProxyPort = i; \ + } \ + } +doproto(HTTP,http) +doproto(HTTPS,https) +doproto(SOCKS,socks) +#undef doproto + + exceptionList = (CFArrayRef) CFDictionaryGetValue(proxyInfo,kSCPropNetProxiesExceptionsList); + if(exceptionList != NULL && CFGetTypeID(exceptionList) != CFArrayGetTypeID()) exceptionList = NULL; + if(p && exceptionList && CFArrayGetCount(exceptionList)) { + CFIndex count = CFArrayGetCount(exceptionList); + p->excluded = (JArray*) + JvNewObjectArray(count,&java::lang::String::class$,0); + for(i=0;iexcluded)[i] = string ? cfStringToJString(string) : JvNewStringLatin1("(null)"); + } + } + CFRelease(proxyInfo); + + return p; +/* + exceptionList = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesExceptionsList]; + if(p && exceptionList && [exceptionList count]) { + NSLog(@"excl: %@",exceptionList); + p->excluded = (JArray*) + JvNewObjectArray([exceptionList count],&java::lang::String::class$,0); + for(i=0;i<[exceptionList count];i++) + elements(p->excluded)[i] = [[exceptionList objectAtIndex: i] jstring]; + } + return p; + */ + +/* + using org::xwt::Proxy; + AutoARP pool; + Proxy *p=0; + NSString *host; + NSNumber *port; + NSArray *exceptionList; + unsigned int i; + NSDictionary *proxyInfo = (NSDictionary*)SCDynamicStoreCopyProxies(NULL); + + if(proxyInfo == NULL) return 0; + if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPEnable] boolValue]) { + host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPProxy]; + port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPPort]; + if(host && [port intValue]) { + if(!p) p = new Proxy(); + p->httpProxyHost = [host jstring]; + p->httpProxyPort = [port intValue]; + } + } + if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSEnable] boolValue]) { + host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSProxy]; + port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSPort]; + if(host && [port intValue]) { + if(!p) p = new Proxy(); + p->httpsProxyHost = [host jstring]; + p->httpsProxyPort = [port intValue]; + } + } + if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSEnable] boolValue]) { + host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSProxy]; + port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSPort]; + if(host && [port intValue]) { + if(!p) p = new Proxy(); + p->socksProxyHost = [host jstring]; + p->socksProxyPort = [port intValue]; + } + } + + exceptionList = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesExceptionsList]; + if(p && exceptionList && [exceptionList count]) { + NSLog(@"excl: %@",exceptionList); + p->excluded = (JArray*) + JvNewObjectArray([exceptionList count],&java::lang::String::class$,0); + for(i=0;i<[exceptionList count];i++) + elements(p->excluded)[i] = [[exceptionList objectAtIndex: i] jstring]; + } + return p; +*/ +} + +jint Carbon::cgScreenWidth() { + return CGDisplayPixelsWide(kCGDirectMainDisplay); +} + +jint Carbon::cgScreenHeight() { + return CGDisplayPixelsHigh(kCGDirectMainDisplay); +} + +void Carbon::_newBrowserWindow(jstring js) { + SmartCFString cfs = js; + CFURLRef url = CFURLCreateWithString(kCFAllocatorDefault,cfs,NULL); + SmartCFString scheme = CFURLCopyScheme(url); + if(scheme.equals(CFStringRef("http"))) + LSOpenCFURLRef(url,NULL); + CFRelease(url); +} + +void Carbon::_exit() { + QuitApplicationEventLoop(); +} + +#define XWT_CARBON_NO_BUNDLE_HACK +#ifdef XWT_CARBON_NO_BUNDLE_HACK +extern "C" { + OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn); + OSErr CPSSetFrontProcess(ProcessSerialNumber *psn); +} +#endif +void Carbon::natInit() { + OSStatus r; + #ifdef XWT_CARBON_NO_BUNDLE_HACK + { + ProcessSerialNumber currentProcess = { 0, kCurrentProcess }; + + ::fprintf(stderr,"Doing XWT_CARBON_NO_BUNDLE_HACK\n"); + r = GetCurrentProcess(¤tProcess); + checkStatus(r,"GetCurrentProcess"); + r = CPSEnableForegroundOperation( ¤tProcess ); + checkStatus(r,"CPSEnableForegroundOperation"); + r = CPSSetFrontProcess(¤tProcess); + checkStatus(r,"CPSSetFrontProcess"); + } + #else + { + IBNibRef nib; + r = CreateNibReference(CFSTR("MainMenu"), &nib); + checkStatus(r,"CreateNibReference"); + r = SetMenuBarFromNib(nib, CFSTR("MenuBar")); + checkStatus(r,"SetMenuBarFromNib"); + DisposeNibReference(nib); + + // FIXME: Install menu event handler + } + #endif +} + +void Carbon::_running() { + RunApplicationEventLoop(); + ExitToShell(); +} + +#pragma mark ------ OpenGL Functions ----- + +void Carbon$CarbonOpenGL::activateSharedContext() { + AGLContext ctx = (AGLContext) rawSharedContext; + aglSetCurrentContext(ctx); +} + +jboolean Carbon$CarbonOpenGL::initPixelFormat() { + GLint attr[] = { + AGL_NO_RECOVERY, + AGL_RGBA, + AGL_DEPTH_SIZE, 32, + AGL_RED_SIZE, 8, + AGL_GREEN_SIZE, 8, + AGL_RED_SIZE, 8, + AGL_ALPHA_SIZE, 8, + AGL_NONE + }; + + rawPixelFormat = (RawData*) aglChoosePixelFormat(NULL,0,attr); + return rawPixelFormat != 0; +} + +void Carbon$CarbonOpenGL::initSharedContext() { + AGLPixelFormat fmt = (AGLPixelFormat) rawPixelFormat; + rawSharedContext = (RawData*) aglCreateContext(fmt,NULL); + checkStatus(rawSharedContext,"aglCreateContext"); +} + +void Carbon$GLCarbonDoubleBuffer::natInit() { + WindowClass wc = kPlainWindowClass; + WindowAttributes attr = 0; + WindowRef window; + Rect rect; + OSStatus r; + AGLContext ctx,shared; + AGLPixelFormat fmt; + GLboolean b; + GLuint tex; + GLuint target; + + rect.top = rect.left = 0; + rect.right = width + rect.left; + rect.bottom = height + rect.top; + + r = CreateNewWindow(wc,attr,&rect,&window); + checkStatus(r,"CreateNewWindow"); + + shared = (AGLContext) gl->rawSharedContext; + fmt = (AGLPixelFormat) gl->rawPixelFormat; + ctx = aglCreateContext(fmt,shared); + checkStatus(ctx, "aglCreateContext"); + + b = aglSetDrawable(ctx,GetWindowPort(window)); + checkStatus(b,"aglSetDrawable"); + + aglSetCurrentContext(ctx); + aglUpdateContext(ctx); + drawableInit(width,height); + glClear(GL_COLOR_BUFFER_BIT); + + aglSetCurrentContext(shared); + target = rectTexture ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D; + glEnable(target); + glGenTextures(1,&tex); + glBindTexture(target,tex); + glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + aglSurfaceTexture (shared, target, GL_RGBA, ctx); + checkGLError(); + glDisable(target); + + //ShowWindow(window); + textureName = (jint) tex; + rawWindowRef = (RawData*) window; + rawCTX = (RawData*) ctx; +} + +void Carbon$GLCarbonDoubleBuffer::activateContext() { + AGLContext ctx = (AGLContext) rawCTX; + aglSetCurrentContext(ctx); +} + +void Carbon$GLCarbonDoubleBuffer::natCleanup(RawData* rawWindowRef, RawData* rawCTX) { + WindowRef window = (WindowRef) rawWindowRef; + AGLContext ctx = (AGLContext) rawCTX; + aglDestroyContext(ctx); + DisposeWindow(window); +} + +void Carbon$GLCarbonSurface::natBlit(Carbon$GLCarbonDoubleBuffer *db, jint sx1, jint sy1, jint dx1, jint dy1, jint dx2, jint dy2) { + AGLContext ctx = (AGLContext) rawCTX; + int sx2 = sx1 + (dx2-dx1); + int sy2 = sy1 + (dy2-dy1); + db->activateContext(); + glFlush(); + checkGLError(); + aglSetCurrentContext(ctx); + checkGLError(); + if(db->rectTexture) { + glEnable(GL_TEXTURE_RECTANGLE_EXT); + checkGLError(); + glBindTexture(GL_TEXTURE_RECTANGLE_EXT, db->textureName); + checkGLError(); + glBegin(GL_QUADS); + glTexCoord2i (sx1, sy1 ); + glVertex3i (dx1, dy1, 0); + glTexCoord2i (sx2, sy1 ); + glVertex3i (dx2, dy1, 0); + glTexCoord2i (sx2, sy2 ); + glVertex3i (dx2, dy2, 0); + glTexCoord2i (sx1, sy2 ); + glVertex3i (dx1, dy2, 0); + glEnd(); + checkGLError(); + glDisable(GL_TEXTURE_RECTANGLE_EXT); + checkGLError(); + } else { + float tx1,ty1,tx2,ty2; // normalized texture coords + tx1 = (float) sx1 / (float) db->width; + ty1 = (float) sy1 / (float) db->height; + tx2 = (float) sx2 / (float) db->width; + ty2 = (float) sy2 / (float) db->height; + + glColor4f(1.0f,1.0f,1.0f,1.0f); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, db->textureName); + checkGLError(); + glBegin(GL_QUADS); + glTexCoord2f (tx1, ty1 ); + glVertex3i (dx1, dy1, 0); + glTexCoord2f (tx2, ty1 ); + glVertex3i (dx2, dy1, 0); + glTexCoord2f (tx2, ty2 ); + glVertex3i (dx2, dy2, 0); + glTexCoord2f (tx1, ty2 ); + glVertex3i (dx1, dy2, 0); + glEnd(); + glDisable(GL_TEXTURE_2D); + checkGLError(); + } + glFlush(); +} + +void Carbon$GLCarbonSurface::natReshape(jint w, jint h) { + AGLContext ctx = (AGLContext) rawCTX; + + aglSetCurrentContext (ctx); + aglUpdateContext(ctx); + + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, w, h, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef (0.375, 0.375, 0.0); + checkGLError(); +} + +void Carbon$GLCarbonSurface::natInit() { + WindowRef window = (WindowRef) rawWindowRef; + AGLContext ctx,shared; + AGLPixelFormat fmt; + GLboolean b; + + shared = (AGLContext) gl->rawSharedContext; + fmt = (AGLPixelFormat) gl->rawPixelFormat; + ctx = aglCreateContext(fmt,shared); + checkStatus(ctx, "aglCreateContext"); + + b = aglSetDrawable(ctx,GetWindowPort(window)); + checkStatus(b,"aglSetDrawable"); + + aglSetCurrentContext(ctx); + checkGLError(); + + rawCTX = (RawData*)ctx; + + reshape(10,10); + + aglSetCurrentContext(ctx); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); +} + +void Carbon$GLCarbonSurface::natDispose() { + AGLContext ctx = (AGLContext) rawCTX; + aglDestroyContext(ctx); + Carbon$CarbonSurface::natDispose(); +} + +} } } // end namepsace org::xwt::plat diff --git a/src/org/xwt/plat/Darwin.java b/src/org/xwt/plat/Darwin.java index cc755d1..c6ec350 100644 --- a/src/org/xwt/plat/Darwin.java +++ b/src/org/xwt/plat/Darwin.java @@ -1,8 +1,321 @@ -// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] +// Copyright 2003 Adam Megacz, see the COPYING file for licensing [LGPL] +// Authors: Brian Alliet and Evan Jones + package org.xwt.plat; +import gnu.gcj.RawData; +import org.xwt.util.*; import org.xwt.*; +import java.util.*; + +public class Carbon extends POSIX { + static Carbon singleton; + private CarbonOpenGL openGL; + boolean jaguar; // true if we are on OS X >= 10.2 + + // TEMPORARY HACKS (remove these when we ditch platform fonts) + protected int _stringWidth(String font, String text) { return (int)Math.round(6.5 * text.length()); } + protected int _getMaxAscent(String font) { return 10; } + protected int _getMaxDescent(String font) { return 2; } + + // General Methods + protected String _getAltKeyName() { return "Option"; } + protected boolean _needsAutoClick() { return false; } + protected boolean _needsAutoDoubleClick() { return false; } + protected String getDescriptiveName() { return "GCJ Carbon Binary"; } + protected boolean _isCaseSensitive() { return false; /* Well, not always, could be UFS */ } + + + // Native Methods + protected int _getScreenWidth() { return cgScreenWidth(); } + protected int _getScreenHeight() { return cgScreenHeight(); } + private native static int cgScreenWidth(); + private native static int cgScreenHeight(); + protected native void _newBrowserWindow(String url); + protected native Proxy natDetectProxy(); + private native void natInit(); + protected native void _exit(); + + private native String natGetClipBoard(); + private native void natSetClipBoard(String text); + protected void _setClipBoard(final String text) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetClipBoard(text); } }); } + protected String _getClipBoard() { + final Semaphore sem = new Semaphore(); + final String[] result = new String[1]; // Kind of like a pointer + CarbonMessage.add(new CarbonMessage() { public void perform() { result[0] = natGetClipBoard(); sem.release(); } }); + sem.block(); + return result[0]; + } + + private static class FileDialogHelper { + public FileDialogHelper(boolean save) { this.save = save; } + public boolean save; + public Semaphore sem = new Semaphore(); + public String fileName; + public String saveName; + public RawData rawUPP; + } + private native void natFileDialog(FileDialogHelper helper, String suggestedFileName, boolean write); + protected String _fileDialog(final String fn, final boolean w) { + final FileDialogHelper helper = new FileDialogHelper(w); + CarbonMessage.add(new CarbonMessage() { public void perform() { natFileDialog(helper,fn,w); } }); + helper.sem.block(); + if(w) + return helper.fileName + "/" + helper.saveName; + else + return helper.fileName; + } + + + // Called by main thread after initialization, this is the event handler + protected native void _running(); + + static void abort(String err) { + throw new Error(err); + } + + public Carbon() { + synchronized(Carbon.class) { + if(singleton != null) abort("Tried to instansiate Carbon more than once"); + singleton = this; + } + } + + protected synchronized Proxy _detectProxy() { + return natDetectProxy(); + } + + private static native final boolean isJaguar(); + + public void init() { + super.init(); + jaguar = isJaguar(); + try { + openGL = new CarbonOpenGL(); + openGL.init(); + } catch(OpenGL.NotSupportedException e) { + Log.log(this,"WARNING: OpenGL support not available: " + e); + // FIXME: We need to fallback to Quartz2D + throw new Error("No OpenGL support"); + } + natInit(); + } + + private final class CarbonOpenGL extends OpenGL { + public RawData rawPixelFormat; + public RawData rawSharedContext; + public int maxAglSurfaceTexSize; + public int maxSurfaceWidth; + public int maxSurfaceHeight; + + private native boolean initPixelFormat(); + private native void initSharedContext(); + + public CarbonOpenGL() throws NotSupportedException { + if(!jaguar) + throw new NotSupportedException("OpenGL requires Mac OS X 10.2 or greater"); + if(!initPixelFormat()) + throw new NotSupportedException("Couldn't get an acceptable pixel format"); + initSharedContext(); + } + + public void init() throws NotSupportedException { + super.init(); + maxAglSurfaceTexSize = rectangularTextures ? maxRectTexSize : maxTexSize; + if(renderer.startsWith("ATI Radeon 7500")) { + maxAglSurfaceTexSize = Math.min(rectangularTextures ? 1600 : 1024,maxAglSurfaceTexSize); + Log.log(this,"Working around Radeon 7500 bug: maxAglSurfaceTexSize: " + maxAglSurfaceTexSize); + } + maxSurfaceWidth = maxSurfaceHeight = maxAglSurfaceTexSize; + } + protected native void activateSharedContext(); + } + + static abstract class CarbonSurface extends Surface { + RawData rawWindowRef; + RawData rawEventHandlerUPP; + int modifiers; + + private native void natSetInvisible(boolean i); + public void setInvisible(final boolean i) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetInvisible(i); } }); } + private native void nat_setMaximized(boolean b); + public void _setMaximized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMaximized(b); } }); } + private native void nat_setMinimized(boolean b); + public void _setMinimized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMinimized(b); } }); } + private native void natSetIcon(Picture p); + public void setIcon(final Picture p) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetIcon(p); } }); } + private native void natSetTitleBarText(String s); + public void setTitleBarText(final String s) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetTitleBarText(s); } }); } + private native void natSetSize(int w, int h); + public void setSize(final int w, final int h) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetSize(w,h); } }); } + private native void natSetLocation(int x, int y); + public void setLocation(final int x, final int y) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLocation(x,y); } }); } + private native void natToFront(); + public void toFront() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToFront(); } }); } + private native void natToBack(); + public void toBack() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToBack(); } }); } + private native void natSetLimits(int minWidth, int minHeight, int maxWidth, int maxHeight); + public void setLimits(final int mnw, final int mnh, final int mxw, final int mxh) { + if(Carbon.singleton.jaguar) + CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLimits(mnw,mnh,mxw,mxh); } }); + } + private native void natSyncCursor(int n); + public void syncCursor() { + int n; + if(cursor.equals("default")) n = 0; + else if(cursor.equals("wait")) n = 1; + else if(cursor.equals("crosshair")) n = 2; + else if(cursor.equals("text")) n = 3; + else if(cursor.equals("hand")) n = 4; + else if(cursor.equals("move")) n = 5; + else if(cursor.equals("east") || cursor.equals("west")) n = 6; + else n = 0; + final int n_ = n; + CarbonMessage.add(new CarbonMessage() { public void perform() { natSyncCursor(n_); } }); + } + + public void _sizeChange(int w, int h) { SizeChange(w,h); } + + /* Drawing stuff */ + public abstract void blit(DoubleBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2); + + public final void _dispose() { CarbonMessage.add(new CarbonMessage() { public void perform() { natDispose(); } }); } + public native void natDispose(); + + public final native void natInit(boolean framed); + + public CarbonSurface(Box root, final boolean framed) { + super(root); + final Semaphore sem = new Semaphore(); + CarbonMessage.add(new CarbonMessage() { public void perform() { CarbonSurface.this.natInit(framed); sem.release(); } }); + sem.block(); + } + + public void reshape(int w, int h) { } + } + + static class GLCarbonDoubleBuffer extends OpenGL.GLDoubleBuffer { + RawData rawCTX; + RawData rawWindowRef; + int textureName; + boolean rectTexture; + CarbonOpenGL gl; + + private native void natInit(); + private static native void natCleanup(RawData rawWindowRef, RawData rawCTX); + + + private static final int fixupDimension(CarbonOpenGL gl, int n) { + if(!gl.rectangularTextures) n = OpenGL.roundToPowerOf2(n); + return Math.min(n,gl.maxAglSurfaceTexSize); + } + public GLCarbonDoubleBuffer(int w, int h, final CarbonOpenGL gl) { + super(fixupDimension(gl,w),fixupDimension(gl,h)); + this.gl = gl; + rectTexture = gl.hasRectangularTextures(); + final Semaphore sem = new Semaphore(); + CarbonMessage.add(new CarbonMessage() { public void perform() { GLCarbonDoubleBuffer.this.natInit(); sem.release(); } }); + sem.block(); + } + public native void activateContext(); + protected void finalize() { + CarbonMessage.add(new CarbonMessage() { public void perform() { natCleanup(rawWindowRef,rawCTX); } }); + gl.deleteTexture(textureName); + } + } + + static class GLCarbonSurface extends CarbonSurface { + RawData rawCTX; + CarbonOpenGL gl; + boolean sizeChange; + + private final native void natInit(); + + public GLCarbonSurface(Box root, boolean framed, CarbonOpenGL gl) { + super(root,framed); + this.gl = gl; + natInit(); + } + + public void setLimits(int mnw,int mnh, int mxw, int mxh) { + mxw = Math.min(mxw,gl.maxSurfaceWidth); + mxh = Math.min(mxh,gl.maxSurfaceHeight); + super.setLimits(mnw,mnh,mxw,mxh); + } + public void _sizeChange(int w, int h) { + sizeChange = true; + super._sizeChange(w,h); + } + + public void setSize(int w, int h) { + sizeChange = true; + w = Math.min(w,gl.maxSurfaceWidth); + h = Math.min(h,gl.maxSurfaceWidth); + super.setSize(w,h); + } + + private native void natBlit(GLCarbonDoubleBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2); + public synchronized void blit(DoubleBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2) { + natBlit((GLCarbonDoubleBuffer)db,sx,sy,dx,dy,dx2,dy2); + } + + private native void natReshape(int w, int h); + public synchronized void reshape(int w, int h) { natReshape(w,h); } + + public native void natDispose(); + } -/** All Darwin-derived operating systems (Mac OS X, OpenDarwin) */ -public abstract class Darwin extends X11 { + /*private class QZCarbonDoubleBuffer extends DoubleBuffer { + + public QZCarbonDoubleBuffer(int width, int height) { + } + } + + private class QZCarbonSurface extends CarbonSurface { + public QZCarbonSurface(Box root, boolean framed) { + super(b,root); + } + public native void blit(DoubleBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2); + } + + private class QZCarbonPicture extends Picture { + int width; + int height; + + public final int getWidth() { return width; } + public final int getHeight() { return height; } + + public QZCarbonPicture(int w, int h) { + this.width = w; + this.height = h; + } + }*/ + + protected DoubleBuffer _createDoubleBuffer(int w, int h, Surface owner) { + if(openGL != null) + return new GLCarbonDoubleBuffer(w,h,openGL); + else + return /*new QZCarbonDoubleBuffer(w,h)*/ null; + } + protected Surface _createSurface(Box b, boolean framed) { + if(openGL != null) + return new GLCarbonSurface(b,framed, openGL); + else + return /*new QZCarbonSufrace(b,framed)*/ null; + } + protected Picture _createPicture(int[] data, int w, int h) { + if(openGL != null) + return openGL.createPicture(data,w,h); + else + return /*new QZCarbonPicture(data,w,h);*/ null; + } + + /* A message that is sent through the carbon event queue */ + private static abstract class CarbonMessage { + public abstract void perform(); + + static { natInit(); } + public static native void natInit(); + public static native void add(CarbonMessage m); + } } -- 1.7.10.4