sgl

annotate src/wsys_cocoa.m @ 15:a16b34ac3f2a

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