sgl

annotate src/wsys_cocoa.m @ 16:01a576351090

trying to fix the cocoa module
author John Tsiombikas <nuclear@siggraph.org>
date Fri, 20 May 2011 10:42:54 +0300
parents a16b34ac3f2a
children 33acb6b2d7a4
rev   line source
nuclear@13 1 /* mac-framework: -framework Cocoa */
nuclear@13 2
nuclear@13 3 #include "config.h"
nuclear@13 4
nuclear@13 5 #ifdef USE_WSYS_MODULE_COCOA
nuclear@13 6
nuclear@16 7 #import <Foundation/Foundation.h>
nuclear@16 8 #import <AppKit/AppKit.h>
nuclear@16 9
nuclear@13 10 #include "sgl.h"
nuclear@15 11 #include "wsys.h"
nuclear@13 12
nuclear@16 13 @interface GLView : NSOpenGLView
nuclear@13 14 {
nuclear@16 15 struct window *win;
nuclear@13 16 }
nuclear@13 17
nuclear@16 18 -(id) initWithFrame: (NSRect) frameRect;
nuclear@13 19
nuclear@13 20 -(void) drawRect: (NSRect) rect;
nuclear@13 21 -(void) reshape;
nuclear@16 22 -(void) keyDown: (NSEvent*) ev;
nuclear@13 23 -(void) keyUp: (NSEvent*) ev;
nuclear@13 24 -(void) mouseDown: (NSEvent*) ev;
nuclear@13 25 -(void) mouseUp: (NSEvent*) ev;
nuclear@13 26 -(void) rightMouseDown: (NSEvent*) ev;
nuclear@13 27 -(void) rightMouseUp: (NSEvent*) ev;
nuclear@13 28 -(void) otherMouseDown: (NSEvent*) ev;
nuclear@13 29 -(void) otherMouseUp: (NSEvent*) ev;
nuclear@13 30 -(void) mouseDragged: (NSEvent*) ev;
nuclear@13 31 -(void) rightMouseDragged: (NSEvent*) ev;
nuclear@16 32 -(void) otherMouseDragged: (NSEvent*) ev;
nuclear@13 33
nuclear@13 34 -(BOOL) acceptsFirstResponder;
nuclear@13 35 @end
nuclear@13 36
nuclear@16 37 @interface AppDelegate
nuclear@16 38 {
nuclear@16 39 }
nuclear@16 40 -(BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*)app;
nuclear@16 41 @end
nuclear@16 42
nuclear@13 43 struct window {
nuclear@13 44 int wid;
nuclear@15 45 int width, height;
nuclear@13 46 NSWindow *win;
nuclear@16 47 GLView *view;
nuclear@15 48 NSOpenGLContext *ctx;
nuclear@13 49 struct window *next;
nuclear@13 50 };
nuclear@13 51
nuclear@13 52
nuclear@13 53 static int init(void);
nuclear@13 54 static void shutdown(void);
nuclear@13 55
nuclear@13 56 /* video mode switching */
nuclear@13 57 static int set_vidmode(int xsz, int ysz);
nuclear@13 58 static int get_vidmode(int *xsz, int *ysz);
nuclear@13 59
nuclear@13 60 /* create/destroy windows */
nuclear@13 61 static int create_window(int xsz, int ysz, unsigned int flags);
nuclear@13 62 static void close_window(int wid);
nuclear@13 63
nuclear@13 64 /* window management */
nuclear@13 65 static int set_active(int wid);
nuclear@13 66 static struct window *find_window(int wid);
nuclear@13 67 static int activate_window(struct window *win);
nuclear@13 68 static int set_title(const char *str);
nuclear@13 69 static void redisplay(void);
nuclear@13 70 static void swap_buffers(void);
nuclear@13 71
nuclear@13 72 static int get_modifiers(void);
nuclear@13 73
nuclear@13 74 /* event handling and friends */
nuclear@13 75 static void set_event(int idx, int enable);
nuclear@13 76 static int process_events(void);
nuclear@13 77 static int handle_event(NSEvent *ev);
nuclear@13 78
nuclear@13 79
nuclear@13 80 static struct wsys_module ws = {
nuclear@13 81 "cocoa", 0,
nuclear@13 82 init,
nuclear@13 83 shutdown,
nuclear@13 84 set_vidmode,
nuclear@13 85 get_vidmode,
nuclear@13 86 create_window,
nuclear@13 87 close_window,
nuclear@13 88 set_active,
nuclear@13 89 set_title,
nuclear@13 90 redisplay,
nuclear@13 91 swap_buffers,
nuclear@13 92 get_modifiers,
nuclear@13 93 set_event,
nuclear@13 94 process_events,
nuclear@13 95 0
nuclear@13 96 };
nuclear@13 97
nuclear@13 98 static struct window *winlist, *active_win;
nuclear@16 99 static NSDate *block, *nonblock;
nuclear@16 100 static NSRunLoop *runloop;
nuclear@13 101
nuclear@13 102
nuclear@13 103 void sgl_register_cocoa(void)
nuclear@13 104 {
nuclear@15 105 sgl_register_module(&ws);
nuclear@13 106 }
nuclear@13 107
nuclear@13 108
nuclear@16 109 @implementation GLView
nuclear@16 110
nuclear@16 111 -(id) initWithFrame: (NSRect) frameRect
nuclear@16 112 {
nuclear@16 113 }
nuclear@13 114
nuclear@13 115 -(void) drawRect: (NSRect) rect
nuclear@13 116 {
nuclear@13 117 sgl_display_callback_t func = sgl_get_callback(SGL_DISPLAY);
nuclear@13 118 if(func) {
nuclear@13 119 func();
nuclear@13 120 }
nuclear@13 121 }
nuclear@13 122
nuclear@13 123 -(void) reshape
nuclear@13 124 {
nuclear@15 125 NSSize sz;
nuclear@15 126 sgl_reshape_callback_t func;
nuclear@15 127
nuclear@15 128 sz = [self bounds].size;
nuclear@15 129
nuclear@15 130 if((func = sgl_get_callback(SGL_RESHAPE)) && (sz.width != active_win->width ||
nuclear@15 131 sz.height != active_win->height)) {
nuclear@15 132 active_win->width = sz.width;
nuclear@15 133 active_win->height = sz.height;
nuclear@15 134 func(sz.width, sz.height);
nuclear@13 135 }
nuclear@13 136 }
nuclear@13 137
nuclear@13 138 -(BOOL) acceptsFirstResponder
nuclear@13 139 {
nuclear@13 140 return YES;
nuclear@13 141 }
nuclear@13 142 @end
nuclear@13 143
nuclear@16 144 @implementation AppDelegate : NSObject
nuclear@16 145 -(BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*)app
nuclear@16 146 {
nuclear@16 147 return YES;
nuclear@16 148 }
nuclear@16 149 @end
nuclear@16 150
nuclear@13 151 static int init(void)
nuclear@13 152 {
nuclear@16 153 if(NSApp) {
nuclear@16 154 sgl_log("wsys_cocoa: multiple calls to init\n");
nuclear@16 155 return 0;
nuclear@16 156 }
nuclear@16 157
nuclear@16 158 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
nuclear@16 159
nuclear@16 160 [NSApplication sharedApplication];
nuclear@16 161 [NSApp setDelegate: delegate];
nuclear@16 162
nuclear@16 163 runloop = [[NSRunLoop currentRunLoop] retain];
nuclear@16 164 block = [runloop limitDateForMode: NSDefaultRunLoopMode];
nuclear@16 165 nonblock = [[NSDate distantPast] retain];
nuclear@16 166
nuclear@16 167 [pool drain];
nuclear@15 168 return 0;
nuclear@13 169 }
nuclear@13 170
nuclear@13 171 static void shutdown(void)
nuclear@13 172 {
nuclear@13 173 while(winlist) {
nuclear@13 174 struct window *win = winlist;
nuclear@13 175 winlist = winlist->next;
nuclear@13 176
nuclear@16 177 [win->win close];
nuclear@13 178 free(win);
nuclear@13 179 }
nuclear@16 180
nuclear@16 181 [NSApp stop: nil];
nuclear@16 182 [NSApp terminate: nil];
nuclear@16 183 NSApp = 0;
nuclear@13 184 }
nuclear@13 185
nuclear@13 186
nuclear@13 187 /* video mode switching */
nuclear@13 188 static int set_vidmode(int xsz, int ysz)
nuclear@13 189 {
nuclear@13 190 return 0; /* TODO */
nuclear@13 191 }
nuclear@13 192
nuclear@13 193 static int get_vidmode(int *xsz, int *ysz)
nuclear@13 194 {
nuclear@13 195 return 0; /* TODO */
nuclear@13 196 }
nuclear@13 197
nuclear@13 198
nuclear@13 199 /* create/destroy windows */
nuclear@13 200 static int create_window(int xsz, int ysz, unsigned int flags)
nuclear@13 201 {
nuclear@13 202 NSWindow *nswin;
nuclear@13 203 NSRect rect;
nuclear@16 204 GLView *view;
nuclear@13 205 unsigned int style;
nuclear@13 206 static int next_id = 1;
nuclear@13 207
nuclear@13 208 if(!(win = malloc(sizeof *win))) {
nuclear@13 209 return -1;
nuclear@13 210 }
nuclear@13 211
nuclear@13 212 /* create the window and attach the OpenGL view */
nuclear@16 213 rect = NSMakeRect(0, 0, xsz, ysz);
nuclear@16 214 view = [[GLView alloc] initWithFrame: rect];
nuclear@13 215
nuclear@16 216 style = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask |
nuclear@16 217 NSMiniaturizableWindowMask;
nuclear@13 218
nuclear@13 219 nswin = [[NSWindow alloc] initWithContentRect: rect styleMask: style
nuclear@13 220 backing: NSBackingStoreBuffered defer: YES];
nuclear@16 221 [nswin setTitle: @"OpenGL/Cocoa"];
nuclear@16 222 [nswin setReleaseWhenClosed: YES];
nuclear@13 223 [nswin setContentView: view];
nuclear@16 224 [nswin makeFirstResponder: view];
nuclear@16 225 [nswin makeKeyAndOrderFront: nil];
nuclear@16 226
nuclear@16 227 [pool drain];
nuclear@13 228
nuclear@13 229 win->win = nswin;
nuclear@13 230 win->view = view;
nuclear@13 231 win->wid = next_id++;
nuclear@13 232 win->next = winlist;
nuclear@13 233 winlist = win;
nuclear@13 234
nuclear@15 235 if(!active_win) {
nuclear@15 236 activate_window(win);
nuclear@15 237 }
nuclear@13 238 return win->wid;
nuclear@13 239 }
nuclear@13 240
nuclear@13 241 static void close_window(int wid)
nuclear@13 242 {
nuclear@13 243 struct window *win, *prev, dummy;
nuclear@13 244 sgl_close_callback_t close_func;
nuclear@13 245
nuclear@13 246 dummy.next = win = winlist;
nuclear@13 247 prev = &dummy;
nuclear@13 248
nuclear@13 249 while(win) {
nuclear@13 250 if(win->wid == wid) {
nuclear@13 251 if(!(close_func = sgl_get_callback(SGL_CLOSE))) {
nuclear@13 252 close_func(wid);
nuclear@13 253 }
nuclear@13 254 [win->win close];
nuclear@13 255
nuclear@13 256 if(active_win == win) {
nuclear@13 257 activate_window(winlist);
nuclear@13 258 }
nuclear@13 259
nuclear@13 260 prev->next = win->next;
nuclear@13 261 free(win);
nuclear@13 262 return;
nuclear@13 263 }
nuclear@13 264 prev = win;
nuclear@13 265 win = win->next;
nuclear@13 266 }
nuclear@13 267 }
nuclear@13 268
nuclear@13 269
nuclear@13 270 /* window management */
nuclear@13 271 static int set_active(int wid)
nuclear@13 272 {
nuclear@15 273 struct window *win = find_window(wid);
nuclear@15 274 return activate_window(win);
nuclear@13 275 }
nuclear@13 276
nuclear@13 277 static struct window *find_window(int wid)
nuclear@13 278 {
nuclear@13 279 struct window *win = winlist;
nuclear@13 280
nuclear@13 281 while(win) {
nuclear@15 282 if(win->wid == wid) {
nuclear@13 283 return win;
nuclear@13 284 }
nuclear@13 285 win = win->next;
nuclear@13 286 }
nuclear@13 287 return 0;
nuclear@13 288 }
nuclear@13 289
nuclear@13 290 static int activate_window(struct window *win)
nuclear@13 291 {
nuclear@13 292 if(!win) {
nuclear@13 293 return -1;
nuclear@13 294 }
nuclear@13 295 [win->ctx makeCurrentContext];
nuclear@13 296 active_win = win;
nuclear@13 297 return 0;
nuclear@13 298 }
nuclear@13 299
nuclear@13 300 static int set_title(const char *str)
nuclear@13 301 {
nuclear@13 302 NSString *nsstr;
nuclear@13 303
nuclear@13 304 nsstr = [[NSString alloc] initWithCString: str encoding: NSASCIIStringEncoding];
nuclear@13 305 [active_win->win setTitle: nsstr];
nuclear@13 306 [nsstr release];
nuclear@15 307 return 0;
nuclear@13 308 }
nuclear@13 309
nuclear@13 310 static void redisplay(void)
nuclear@13 311 {
nuclear@15 312 active_win->needs_redisplay = 1;
nuclear@13 313 }
nuclear@13 314
nuclear@13 315 static void swap_buffers(void)
nuclear@13 316 {
nuclear@15 317 [active_win->ctx flushBuffer];
nuclear@13 318 }
nuclear@13 319
nuclear@13 320
nuclear@13 321 static int get_modifiers(void)
nuclear@13 322 {
nuclear@13 323 return 0; /* TODO */
nuclear@13 324 }
nuclear@13 325
nuclear@13 326
nuclear@13 327 /* event handling and friends */
nuclear@13 328 static void set_event(int idx, int enable)
nuclear@13 329 {
nuclear@13 330 }
nuclear@13 331
nuclear@13 332 static int process_events(void)
nuclear@13 333 {
nuclear@13 334 NSAutoreleasePool *pool;
nuclear@16 335 NSDate *limdate;
nuclear@14 336 sgl_idle_callback_t idle;
nuclear@16 337
nuclear@16 338 idle = sgl_get_callback(SGL_IDLE);
nuclear@13 339
nuclear@13 340 pool = [[NSAutoreleasePool alloc] init];
nuclear@16 341 limdate = idle ? nonblock : block;
nuclear@15 342
nuclear@13 343 for(;;) {
nuclear@16 344 NSEvent *ev = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: limdate
nuclear@16 345 inMode: NSDefaultRunLoopMode dequeue: YES];
nuclear@16 346 if(!ev) break;
nuclear@16 347
nuclear@16 348 [NSApp sendEvent: ev];
nuclear@16 349 if(limdate == block) {
nuclear@16 350 limdate = nonblock;
nuclear@13 351 }
nuclear@15 352 }
nuclear@15 353
nuclear@15 354 [pool drain];
nuclear@15 355 return 0;
nuclear@13 356 }
nuclear@13 357
nuclear@13 358 static int handle_event(NSEvent *ev)
nuclear@13 359 {
nuclear@14 360 switch([ev type]) {
nuclear@14 361 case NSKeyDown:
nuclear@14 362 case NSKeyUp:
nuclear@15 363 printf("key pressed\n");
nuclear@15 364 break;
nuclear@14 365
nuclear@15 366 default:
nuclear@15 367 break;
nuclear@15 368 }
nuclear@15 369 return 0;
nuclear@13 370 }
nuclear@13 371
nuclear@13 372 #endif /* USE_WSYS_MODULE_COCOA */