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 */