# HG changeset patch # User John Tsiombikas # Date 1308968236 -10800 # Node ID ee7b3a898b6b6ee58052027fe4b91c4dec917231 # Parent a16b34ac3f2ab91828f3d93225205d4f6c4159df fooing with cocoa diff -r a16b34ac3f2a -r ee7b3a898b6b src/wsys_cocoa.m --- a/src/wsys_cocoa.m Tue May 17 11:21:09 2011 +0300 +++ b/src/wsys_cocoa.m Sat Jun 25 05:17:16 2011 +0300 @@ -13,7 +13,7 @@ int foo; } -/*-(id) initWithFrame: (NSRect) frameRect;*/ +-(id) initWithFrame: (NSRect) frame pixelFormat: (NSOpenGLPixelFormat*) pf; -(void) drawRect: (NSRect) rect; -(void) reshape; @@ -32,6 +32,16 @@ -(BOOL) acceptsFirstResponder; @end + +@interface AppDelegate : NSObject +{ + int foo; +} +-(BOOL) applicationShouldTerminate: (NSApplication*) app; +-(BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*)app; +@end + + struct window { int wid; int width, height; @@ -67,7 +77,8 @@ /* event handling and friends */ static void set_event(int idx, int enable); static int process_events(void); -static int handle_event(NSEvent *ev); + +static void fill_attr(NSOpenGLPixelFormatAttribute *attr, unsigned int flags); static struct wsys_module ws = { @@ -88,8 +99,8 @@ 0 }; -static NSApplication *app; static struct window *winlist, *active_win; +static int quit_main_loop; void sgl_register_cocoa(void) @@ -100,6 +111,12 @@ @implementation OpenGLView +-(id) initWithFrame: (NSRect) frame pixelFormat: (NSOpenGLPixelFormat*) pf +{ + self = [super initWithFrame: frame pixelFormat: pf]; + return self; +} + -(void) drawRect: (NSRect) rect { sgl_display_callback_t func = sgl_get_callback(SGL_DISPLAY); @@ -129,9 +146,41 @@ } @end +@implementation AppDelegate +-(BOOL) applicationShouldTerminate: (NSApplication*) app +{ + return NSTerminateNow; +} + +-(BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) app +{ + return YES; +} + +-(void) applicationWillTerminate: (NSNotification*) notification +{ + printf("applicationWillTerminate\n"); +} + +-(BOOL) windowShouldClose: (id) win +{ + return YES; +} + +-(void) windowWillClose: (NSNotification*) notification +{ + [NSApp terminate: nil]; +} +@end + static int init(void) { - app = [NSApplication sharedApplication]; + AppDelegate *delegate; + + [NSApplication sharedApplication]; + + delegate = [[AppDelegate alloc] init]; + [NSApp setDelegate: delegate]; return 0; } @@ -144,6 +193,8 @@ /* TODO destroy window */ free(win); } + + quit_main_loop = 1; } @@ -162,9 +213,12 @@ /* create/destroy windows */ static int create_window(int xsz, int ysz, unsigned int flags) { + NSAutoreleasePool *pool; NSWindow *nswin; NSRect rect; OpenGLView *view; + NSOpenGLPixelFormat *pf; + NSOpenGLPixelFormatAttribute attr[32]; unsigned int style; struct window *win; static int next_id = 1; @@ -173,6 +227,13 @@ return -1; } + pool = [[NSAutoreleasePool alloc] init]; + + /* create the view */ + fill_attr(attr, flags); + pf = [[[NSOpenGLPixelFormat alloc] initWithAttributes: attr] autorelease]; + view = [[OpenGLView alloc] initWithFrame: rect pixelFormat: pf]; + /* create the window and attach the OpenGL view */ rect.origin.x = rect.origin.y = 0; rect.size.width = xsz; @@ -183,8 +244,12 @@ nswin = [[NSWindow alloc] initWithContentRect: rect styleMask: style backing: NSBackingStoreBuffered defer: YES]; - view = [[OpenGLView alloc] initWithFrame: rect]; + + [nswin setTitle: @"OpenGL/Cocoa"]; + [nswin setReleasedWhenClosed: YES]; [nswin setContentView: view]; + [nswin makeFirstResponder: view]; + [nswin makeKeyAndOrderFront: nil]; [view release]; win->win = nswin; @@ -198,6 +263,8 @@ if(!active_win) { activate_window(win); } + + [pool drain]; return win->wid; } @@ -295,6 +362,9 @@ static int process_events(void) { NSAutoreleasePool *pool; + NSRunLoop *runloop; + NSDate *block, *nonblock, *limdate; + sgl_idle_callback_t idle; sgl_display_callback_t disp; struct window *win; @@ -315,36 +385,66 @@ win = win->next; } - for(;;) { - NSEvent *ev = [app nextEventMatchingMask: NSAnyEventMask - untilDate: [NSDate distantPast] inMode: NSDefaultRunLoopMode dequeue: YES]; - if(ev == nil) { - break; + runloop = [[NSRunLoop currentRunLoop] retain]; + block = [runloop limitDateForMode: NSDefaultRunLoopMode]; + nonblock = [[NSDate distantPast] retain]; + limdate = idle ? nonblock : block; + + while(!quit_main_loop) { + NSEvent *ev = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: limdate + inMode: NSDefaultRunLoopMode dequeue: YES]; + if(!ev) break; + + [NSApp sendEvent: ev]; + if(limdate == block) { + limdate = nonblock; } - - res = handle_event(ev); } if(idle) { idle(); } + [runloop release]; [pool drain]; - return 0; + return quit_main_loop ? -1 : 0; } -static int handle_event(NSEvent *ev) +static void fill_attr(NSOpenGLPixelFormatAttribute *attr, unsigned int flags) { - switch([ev type]) { - case NSKeyDown: - case NSKeyUp: - printf("key pressed\n"); - break; + int i = 0; - default: - break; + /* this is very important. makes pixelformat selection behave like GLX + * where any non-zero value will denote "choose highest possible". This + * is pretty much what we intend, as the user doesn't actually pass any + * of these numbers. + */ + attr[i++] = NSOpenGLPFAMaximumPolicy; + + attr[i++] = NSOpenGLPFAColorSize; + attr[i++] = 1; + + if(flags & SGL_DOUBLE) { + attr[i++] = NSOpenGLPFADoubleBuffer; } - return 0; + if(flags & SGL_DEPTH) { + attr[i++] = NSOpenGLPFADepthSize; + attr[i++] = 1; + } + if(flags & SGL_STENCIL) { + attr[i++] = NSOpenGLPFAStencilSize; + attr[i++] = 8; /* max-policy has no effect on stencil selection */ + } + if(flags & SGL_STEREO) { + attr[i++] = NSOpenGLPFAStereo; + } + if(flags & SGL_MULTISAMPLE) { + attr[i++] = NSOpenGLPFASampleBuffers; + attr[i++] = 1; + attr[i++] = NSOpenGLPFASamples; + attr[i++] = 4; /* TODO don't hardcode, query */ + } + attr[i++] = 0; } #endif /* USE_WSYS_MODULE_COCOA */ diff -r a16b34ac3f2a -r ee7b3a898b6b tests/simple/Simple.app/Contents/Info.plist --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/simple/Simple.app/Contents/Info.plist Sat Jun 25 05:17:16 2011 +0300 @@ -0,0 +1,16 @@ + + + + + CFBundleDevelopmentRegionGlobal + CFBundleExecutablesimple + CFBundleDisplayNamesimplesgltest + CFBundleNameSGL Simple Example + CFBundleIdentifiercom.mindlapse.sglsimple + CFBundlePackageTypeAPPL + CFBundleSignaturecglt + CFBundleShortVersionString0.1 + CFBundleVersion0.1 + CFBundleInfoDictionaryVersion6.0 + + diff -r a16b34ac3f2a -r ee7b3a898b6b tests/tests-makefile --- a/tests/tests-makefile Tue May 17 11:21:09 2011 +0300 +++ b/tests/tests-makefile Sat Jun 25 05:17:16 2011 +0300 @@ -31,3 +31,9 @@ .PHONY: clean clean: rm -f $(obj) $(bin) + +.PHONY: install +install: + mkdir -p Simple.app/Contents/MacOS + cp simple Simple.app/Contents/MacOS/simple + install_name_tool -change libsgl.dylib @executable_path/../Frameworks/libsgl.dylib Simple.app/Contents/MacOS/simple