# 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"
# 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
(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); \
$(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"
+++ /dev/null
-// 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 <java/lang/Object.h>
-#include <java/lang/Error.h>
-
-#include <org/xwt/plat/Carbon.h>
-#include <org/xwt/plat/Carbon$CarbonSurface.h>
-#include <org/xwt/plat/Carbon$GLCarbonSurface.h>
-#include <org/xwt/plat/Carbon$GLCarbonDoubleBuffer.h>
-#include <org/xwt/plat/Carbon$CarbonMessage.h>
-#include <org/xwt/plat/Carbon$CarbonOpenGL.h>
-#include <org/xwt/plat/Carbon$FileDialogHelper.h>
-#include <org/xwt/plat/GCJ$Retainer.h>
-#include <org/xwt/Proxy.h>
-#include <org/xwt/util/Semaphore.h>
-
-#include <Carbon/Carbon.h>
-#include <CoreFoundation/CoreFoundation.h>
-// For proxy stuff
-#include <SystemConfiguration/SystemConfiguration.h>
-// For LSOpenURLRef
-#include <ApplicationServices/ApplicationServices.h>
-
-#include <AGL/agl.h>
-
-#include <stdlib.h>
-
-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 <bool CHECK> static inline int CompileTimeCheck() { const int something_is_wrong=1; something_is_wrong++; return 0; }
- template <> static inline int CompileTimeCheck<true>() { return 0; }
- const static int unichar_check = CompileTimeCheck<sizeof(jchar)==sizeof(UniChar)>();
-
- 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<java::lang::String*>*)
- JvNewObjectArray(count,&java::lang::String::class$,0);
- for(i=0;i<count;i++) {
- string = (CFStringRef) CFArrayGetValueAtIndex(exceptionList,i);
- if(string != NULL && CFGetTypeID(string) != CFStringGetTypeID()) string = NULL;
- elements(p->excluded)[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<java::lang::String*>*)
- 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<java::lang::String*>*)
- 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
+++ /dev/null
-// 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);
- }
-}
-#include <sys/types.h>
-#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 <java/lang/Object.h>
+#include <java/lang/Error.h>
+
+#include <org/xwt/plat/Carbon.h>
+#include <org/xwt/plat/Carbon$CarbonSurface.h>
+#include <org/xwt/plat/Carbon$GLCarbonSurface.h>
+#include <org/xwt/plat/Carbon$GLCarbonDoubleBuffer.h>
+#include <org/xwt/plat/Carbon$CarbonMessage.h>
+#include <org/xwt/plat/Carbon$CarbonOpenGL.h>
+#include <org/xwt/plat/Carbon$FileDialogHelper.h>
+#include <org/xwt/plat/GCJ$Retainer.h>
+#include <org/xwt/Proxy.h>
+#include <org/xwt/util/Semaphore.h>
+
+#include <Carbon/Carbon.h>
+#include <CoreFoundation/CoreFoundation.h>
+// For proxy stuff
+#include <SystemConfiguration/SystemConfiguration.h>
+// For LSOpenURLRef
+#include <ApplicationServices/ApplicationServices.h>
+
+#include <AGL/agl.h>
+
+#include <stdlib.h>
+
+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 <bool CHECK> static inline int CompileTimeCheck() { const int something_is_wrong=1; something_is_wrong++; return 0; }
+ template <> static inline int CompileTimeCheck<true>() { return 0; }
+ const static int unichar_check = CompileTimeCheck<sizeof(jchar)==sizeof(UniChar)>();
+
+ 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<java::lang::String*>*)
+ JvNewObjectArray(count,&java::lang::String::class$,0);
+ for(i=0;i<count;i++) {
+ string = (CFStringRef) CFArrayGetValueAtIndex(exceptionList,i);
+ if(string != NULL && CFGetTypeID(string) != CFStringGetTypeID()) string = NULL;
+ elements(p->excluded)[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<java::lang::String*>*)
+ 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<java::lang::String*>*)
+ 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
-// 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);
+ }
}