sgl
diff src/wsys_cocoa.m @ 17:ee7b3a898b6b
fooing with cocoa
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 25 Jun 2011 05:17:16 +0300 |
parents | a16b34ac3f2a |
children | 33acb6b2d7a4 |
line diff
1.1 --- a/src/wsys_cocoa.m Tue May 17 11:21:09 2011 +0300 1.2 +++ b/src/wsys_cocoa.m Sat Jun 25 05:17:16 2011 +0300 1.3 @@ -13,7 +13,7 @@ 1.4 int foo; 1.5 } 1.6 1.7 -/*-(id) initWithFrame: (NSRect) frameRect;*/ 1.8 +-(id) initWithFrame: (NSRect) frame pixelFormat: (NSOpenGLPixelFormat*) pf; 1.9 1.10 -(void) drawRect: (NSRect) rect; 1.11 -(void) reshape; 1.12 @@ -32,6 +32,16 @@ 1.13 -(BOOL) acceptsFirstResponder; 1.14 @end 1.15 1.16 + 1.17 +@interface AppDelegate : NSObject 1.18 +{ 1.19 + int foo; 1.20 +} 1.21 +-(BOOL) applicationShouldTerminate: (NSApplication*) app; 1.22 +-(BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*)app; 1.23 +@end 1.24 + 1.25 + 1.26 struct window { 1.27 int wid; 1.28 int width, height; 1.29 @@ -67,7 +77,8 @@ 1.30 /* event handling and friends */ 1.31 static void set_event(int idx, int enable); 1.32 static int process_events(void); 1.33 -static int handle_event(NSEvent *ev); 1.34 + 1.35 +static void fill_attr(NSOpenGLPixelFormatAttribute *attr, unsigned int flags); 1.36 1.37 1.38 static struct wsys_module ws = { 1.39 @@ -88,8 +99,8 @@ 1.40 0 1.41 }; 1.42 1.43 -static NSApplication *app; 1.44 static struct window *winlist, *active_win; 1.45 +static int quit_main_loop; 1.46 1.47 1.48 void sgl_register_cocoa(void) 1.49 @@ -100,6 +111,12 @@ 1.50 1.51 @implementation OpenGLView 1.52 1.53 +-(id) initWithFrame: (NSRect) frame pixelFormat: (NSOpenGLPixelFormat*) pf 1.54 +{ 1.55 + self = [super initWithFrame: frame pixelFormat: pf]; 1.56 + return self; 1.57 +} 1.58 + 1.59 -(void) drawRect: (NSRect) rect 1.60 { 1.61 sgl_display_callback_t func = sgl_get_callback(SGL_DISPLAY); 1.62 @@ -129,9 +146,41 @@ 1.63 } 1.64 @end 1.65 1.66 +@implementation AppDelegate 1.67 +-(BOOL) applicationShouldTerminate: (NSApplication*) app 1.68 +{ 1.69 + return NSTerminateNow; 1.70 +} 1.71 + 1.72 +-(BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) app 1.73 +{ 1.74 + return YES; 1.75 +} 1.76 + 1.77 +-(void) applicationWillTerminate: (NSNotification*) notification 1.78 +{ 1.79 + printf("applicationWillTerminate\n"); 1.80 +} 1.81 + 1.82 +-(BOOL) windowShouldClose: (id) win 1.83 +{ 1.84 + return YES; 1.85 +} 1.86 + 1.87 +-(void) windowWillClose: (NSNotification*) notification 1.88 +{ 1.89 + [NSApp terminate: nil]; 1.90 +} 1.91 +@end 1.92 + 1.93 static int init(void) 1.94 { 1.95 - app = [NSApplication sharedApplication]; 1.96 + AppDelegate *delegate; 1.97 + 1.98 + [NSApplication sharedApplication]; 1.99 + 1.100 + delegate = [[AppDelegate alloc] init]; 1.101 + [NSApp setDelegate: delegate]; 1.102 return 0; 1.103 } 1.104 1.105 @@ -144,6 +193,8 @@ 1.106 /* TODO destroy window */ 1.107 free(win); 1.108 } 1.109 + 1.110 + quit_main_loop = 1; 1.111 } 1.112 1.113 1.114 @@ -162,9 +213,12 @@ 1.115 /* create/destroy windows */ 1.116 static int create_window(int xsz, int ysz, unsigned int flags) 1.117 { 1.118 + NSAutoreleasePool *pool; 1.119 NSWindow *nswin; 1.120 NSRect rect; 1.121 OpenGLView *view; 1.122 + NSOpenGLPixelFormat *pf; 1.123 + NSOpenGLPixelFormatAttribute attr[32]; 1.124 unsigned int style; 1.125 struct window *win; 1.126 static int next_id = 1; 1.127 @@ -173,6 +227,13 @@ 1.128 return -1; 1.129 } 1.130 1.131 + pool = [[NSAutoreleasePool alloc] init]; 1.132 + 1.133 + /* create the view */ 1.134 + fill_attr(attr, flags); 1.135 + pf = [[[NSOpenGLPixelFormat alloc] initWithAttributes: attr] autorelease]; 1.136 + view = [[OpenGLView alloc] initWithFrame: rect pixelFormat: pf]; 1.137 + 1.138 /* create the window and attach the OpenGL view */ 1.139 rect.origin.x = rect.origin.y = 0; 1.140 rect.size.width = xsz; 1.141 @@ -183,8 +244,12 @@ 1.142 1.143 nswin = [[NSWindow alloc] initWithContentRect: rect styleMask: style 1.144 backing: NSBackingStoreBuffered defer: YES]; 1.145 - view = [[OpenGLView alloc] initWithFrame: rect]; 1.146 + 1.147 + [nswin setTitle: @"OpenGL/Cocoa"]; 1.148 + [nswin setReleasedWhenClosed: YES]; 1.149 [nswin setContentView: view]; 1.150 + [nswin makeFirstResponder: view]; 1.151 + [nswin makeKeyAndOrderFront: nil]; 1.152 [view release]; 1.153 1.154 win->win = nswin; 1.155 @@ -198,6 +263,8 @@ 1.156 if(!active_win) { 1.157 activate_window(win); 1.158 } 1.159 + 1.160 + [pool drain]; 1.161 return win->wid; 1.162 } 1.163 1.164 @@ -295,6 +362,9 @@ 1.165 static int process_events(void) 1.166 { 1.167 NSAutoreleasePool *pool; 1.168 + NSRunLoop *runloop; 1.169 + NSDate *block, *nonblock, *limdate; 1.170 + 1.171 sgl_idle_callback_t idle; 1.172 sgl_display_callback_t disp; 1.173 struct window *win; 1.174 @@ -315,36 +385,66 @@ 1.175 win = win->next; 1.176 } 1.177 1.178 - for(;;) { 1.179 - NSEvent *ev = [app nextEventMatchingMask: NSAnyEventMask 1.180 - untilDate: [NSDate distantPast] inMode: NSDefaultRunLoopMode dequeue: YES]; 1.181 - if(ev == nil) { 1.182 - break; 1.183 + runloop = [[NSRunLoop currentRunLoop] retain]; 1.184 + block = [runloop limitDateForMode: NSDefaultRunLoopMode]; 1.185 + nonblock = [[NSDate distantPast] retain]; 1.186 + limdate = idle ? nonblock : block; 1.187 + 1.188 + while(!quit_main_loop) { 1.189 + NSEvent *ev = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: limdate 1.190 + inMode: NSDefaultRunLoopMode dequeue: YES]; 1.191 + if(!ev) break; 1.192 + 1.193 + [NSApp sendEvent: ev]; 1.194 + if(limdate == block) { 1.195 + limdate = nonblock; 1.196 } 1.197 - 1.198 - res = handle_event(ev); 1.199 } 1.200 1.201 if(idle) { 1.202 idle(); 1.203 } 1.204 1.205 + [runloop release]; 1.206 [pool drain]; 1.207 - return 0; 1.208 + return quit_main_loop ? -1 : 0; 1.209 } 1.210 1.211 -static int handle_event(NSEvent *ev) 1.212 +static void fill_attr(NSOpenGLPixelFormatAttribute *attr, unsigned int flags) 1.213 { 1.214 - switch([ev type]) { 1.215 - case NSKeyDown: 1.216 - case NSKeyUp: 1.217 - printf("key pressed\n"); 1.218 - break; 1.219 + int i = 0; 1.220 1.221 - default: 1.222 - break; 1.223 + /* this is very important. makes pixelformat selection behave like GLX 1.224 + * where any non-zero value will denote "choose highest possible". This 1.225 + * is pretty much what we intend, as the user doesn't actually pass any 1.226 + * of these numbers. 1.227 + */ 1.228 + attr[i++] = NSOpenGLPFAMaximumPolicy; 1.229 + 1.230 + attr[i++] = NSOpenGLPFAColorSize; 1.231 + attr[i++] = 1; 1.232 + 1.233 + if(flags & SGL_DOUBLE) { 1.234 + attr[i++] = NSOpenGLPFADoubleBuffer; 1.235 } 1.236 - return 0; 1.237 + if(flags & SGL_DEPTH) { 1.238 + attr[i++] = NSOpenGLPFADepthSize; 1.239 + attr[i++] = 1; 1.240 + } 1.241 + if(flags & SGL_STENCIL) { 1.242 + attr[i++] = NSOpenGLPFAStencilSize; 1.243 + attr[i++] = 8; /* max-policy has no effect on stencil selection */ 1.244 + } 1.245 + if(flags & SGL_STEREO) { 1.246 + attr[i++] = NSOpenGLPFAStereo; 1.247 + } 1.248 + if(flags & SGL_MULTISAMPLE) { 1.249 + attr[i++] = NSOpenGLPFASampleBuffers; 1.250 + attr[i++] = 1; 1.251 + attr[i++] = NSOpenGLPFASamples; 1.252 + attr[i++] = 4; /* TODO don't hardcode, query */ 1.253 + } 1.254 + attr[i++] = 0; 1.255 } 1.256 1.257 #endif /* USE_WSYS_MODULE_COCOA */