rev |
line source |
nuclear@19
|
1 /* SimplyGL window system module for Cocoa */
|
nuclear@13
|
2 /* mac-framework: -framework Cocoa */
|
nuclear@13
|
3
|
nuclear@13
|
4 #include "config.h"
|
nuclear@13
|
5
|
nuclear@13
|
6 #ifdef USE_WSYS_MODULE_COCOA
|
nuclear@13
|
7
|
nuclear@15
|
8 #import <Cocoa/Cocoa.h>
|
nuclear@13
|
9 #include "sgl.h"
|
nuclear@15
|
10 #include "wsys.h"
|
nuclear@31
|
11 #include "log.h"
|
nuclear@31
|
12
|
nuclear@15
|
13 @interface OpenGLView : NSOpenGLView
|
nuclear@13
|
14 {
|
nuclear@15
|
15 int foo;
|
nuclear@13
|
16 }
|
nuclear@13
|
17
|
nuclear@17
|
18 -(id) initWithFrame: (NSRect) frame pixelFormat: (NSOpenGLPixelFormat*) pf;
|
nuclear@13
|
19
|
nuclear@13
|
20 -(void) drawRect: (NSRect) rect;
|
nuclear@13
|
21 -(void) reshape;
|
nuclear@33
|
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@33
|
32 -(void) otherMouseDragged: (NSEvent*) ev;
|
nuclear@13
|
33
|
nuclear@13
|
34 -(BOOL) acceptsFirstResponder;
|
nuclear@13
|
35 @end
|
nuclear@13
|
36
|
nuclear@17
|
37
|
nuclear@17
|
38 @interface AppDelegate : NSObject
|
nuclear@16
|
39 {
|
nuclear@33
|
40 int foo;
|
nuclear@16
|
41 }
|
nuclear@31
|
42
|
nuclear@31
|
43 -(void) applicationWillFinishLaunching: (NSNotification*) notification;
|
nuclear@31
|
44 -(void) applicationDidFinishLaunching: (NSNotification*) notification;
|
nuclear@31
|
45
|
nuclear@17
|
46 -(BOOL) applicationShouldTerminate: (NSApplication*) app;
|
nuclear@31
|
47 -(BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) app;
|
nuclear@31
|
48 -(void) applicationWillTerminate: (NSNotification*) notification;
|
nuclear@32
|
49 @end
|
nuclear@32
|
50
|
nuclear@32
|
51 struct window;
|
nuclear@32
|
52
|
nuclear@32
|
53 @interface WinDelegate : NSObject <NSWindowDelegate>
|
nuclear@32
|
54 {
|
nuclear@33
|
55 @public
|
nuclear@32
|
56 struct window *win;
|
nuclear@32
|
57 }
|
nuclear@32
|
58 -(id) init;
|
nuclear@32
|
59 -(void) dealloc;
|
nuclear@32
|
60
|
nuclear@32
|
61 -(void) windowDidExpose: (NSNotification*) notification;
|
nuclear@32
|
62 -(void) windowDidResize: (NSNotification*) notification;
|
nuclear@31
|
63 -(BOOL) windowShouldClose: (id) win;
|
nuclear@31
|
64 -(void) windowWillClose: (NSNotification*) notification;
|
nuclear@16
|
65 @end
|
nuclear@16
|
66
|
nuclear@17
|
67
|
nuclear@13
|
68 struct window {
|
nuclear@13
|
69 int wid;
|
nuclear@15
|
70 int width, height;
|
nuclear@13
|
71 NSWindow *win;
|
nuclear@15
|
72 OpenGLView *view;
|
nuclear@15
|
73 NSOpenGLContext *ctx;
|
nuclear@15
|
74 int needs_redisplay;
|
nuclear@13
|
75 struct window *next;
|
nuclear@13
|
76 };
|
nuclear@13
|
77
|
nuclear@13
|
78
|
nuclear@13
|
79 static int init(void);
|
nuclear@13
|
80 static void shutdown(void);
|
nuclear@13
|
81
|
nuclear@13
|
82 /* video mode switching */
|
nuclear@13
|
83 static int set_vidmode(int xsz, int ysz);
|
nuclear@13
|
84 static int get_vidmode(int *xsz, int *ysz);
|
nuclear@13
|
85
|
nuclear@13
|
86 /* create/destroy windows */
|
nuclear@13
|
87 static int create_window(int xsz, int ysz, unsigned int flags);
|
nuclear@13
|
88 static void close_window(int wid);
|
nuclear@13
|
89
|
nuclear@13
|
90 /* window management */
|
nuclear@13
|
91 static int set_active(int wid);
|
nuclear@13
|
92 static struct window *find_window(int wid);
|
nuclear@13
|
93 static int activate_window(struct window *win);
|
nuclear@13
|
94 static int set_title(const char *str);
|
nuclear@13
|
95 static void redisplay(void);
|
nuclear@13
|
96 static void swap_buffers(void);
|
nuclear@13
|
97
|
nuclear@13
|
98 static int get_modifiers(void);
|
nuclear@13
|
99
|
nuclear@13
|
100 /* event handling and friends */
|
nuclear@13
|
101 static void set_event(int idx, int enable);
|
nuclear@13
|
102 static int process_events(void);
|
nuclear@17
|
103
|
nuclear@33
|
104 static void select_event_window(NSEvent *ev);
|
nuclear@33
|
105 static void handle_key(NSEvent *ev, int state);
|
nuclear@33
|
106 static void handle_mouse(NSEvent *ev, int state);
|
nuclear@33
|
107 static void handle_motion(NSEvent *ev);
|
nuclear@33
|
108
|
nuclear@17
|
109 static void fill_attr(NSOpenGLPixelFormatAttribute *attr, unsigned int flags);
|
nuclear@13
|
110
|
nuclear@13
|
111
|
nuclear@13
|
112 static struct wsys_module ws = {
|
nuclear@13
|
113 "cocoa", 0,
|
nuclear@13
|
114 init,
|
nuclear@13
|
115 shutdown,
|
nuclear@13
|
116 set_vidmode,
|
nuclear@13
|
117 get_vidmode,
|
nuclear@13
|
118 create_window,
|
nuclear@13
|
119 close_window,
|
nuclear@13
|
120 set_active,
|
nuclear@13
|
121 set_title,
|
nuclear@13
|
122 redisplay,
|
nuclear@13
|
123 swap_buffers,
|
nuclear@13
|
124 get_modifiers,
|
nuclear@13
|
125 set_event,
|
nuclear@13
|
126 process_events,
|
nuclear@13
|
127 0
|
nuclear@13
|
128 };
|
nuclear@13
|
129
|
nuclear@13
|
130 static struct window *winlist, *active_win;
|
nuclear@17
|
131 static int quit_main_loop;
|
nuclear@13
|
132
|
nuclear@31
|
133 static NSAutoreleasePool *global_pool;
|
nuclear@13
|
134
|
nuclear@13
|
135 void sgl_register_cocoa(void)
|
nuclear@13
|
136 {
|
nuclear@15
|
137 sgl_register_module(&ws);
|
nuclear@13
|
138 }
|
nuclear@13
|
139
|
nuclear@13
|
140
|
nuclear@15
|
141 @implementation OpenGLView
|
nuclear@16
|
142
|
nuclear@17
|
143 -(id) initWithFrame: (NSRect) frame pixelFormat: (NSOpenGLPixelFormat*) pf
|
nuclear@16
|
144 {
|
nuclear@17
|
145 self = [super initWithFrame: frame pixelFormat: pf];
|
nuclear@17
|
146 return self;
|
nuclear@16
|
147 }
|
nuclear@13
|
148
|
nuclear@13
|
149 -(void) drawRect: (NSRect) rect
|
nuclear@13
|
150 {
|
nuclear@13
|
151 sgl_display_callback_t func = sgl_get_callback(SGL_DISPLAY);
|
nuclear@13
|
152 if(func) {
|
nuclear@13
|
153 func();
|
nuclear@13
|
154 }
|
nuclear@13
|
155 }
|
nuclear@13
|
156
|
nuclear@13
|
157 -(void) reshape
|
nuclear@13
|
158 {
|
nuclear@15
|
159 NSSize sz;
|
nuclear@15
|
160 sgl_reshape_callback_t func;
|
nuclear@15
|
161
|
nuclear@15
|
162 sz = [self bounds].size;
|
nuclear@15
|
163
|
nuclear@15
|
164 if((func = sgl_get_callback(SGL_RESHAPE)) && (sz.width != active_win->width ||
|
nuclear@15
|
165 sz.height != active_win->height)) {
|
nuclear@15
|
166 active_win->width = sz.width;
|
nuclear@15
|
167 active_win->height = sz.height;
|
nuclear@15
|
168 func(sz.width, sz.height);
|
nuclear@13
|
169 }
|
nuclear@13
|
170 }
|
nuclear@13
|
171
|
nuclear@33
|
172 -(void) keyDown: (NSEvent*) ev
|
nuclear@33
|
173 {
|
nuclear@33
|
174 handle_key(ev, 1);
|
nuclear@33
|
175 }
|
nuclear@33
|
176
|
nuclear@33
|
177 -(void) keyUp: (NSEvent*) ev
|
nuclear@33
|
178 {
|
nuclear@33
|
179 handle_key(ev, 0);
|
nuclear@33
|
180 }
|
nuclear@33
|
181
|
nuclear@33
|
182 -(void) mouseDown: (NSEvent*) ev
|
nuclear@33
|
183 {
|
nuclear@33
|
184 handle_mouse(ev, 1);
|
nuclear@33
|
185 }
|
nuclear@33
|
186
|
nuclear@33
|
187 -(void) mouseUp: (NSEvent*) ev
|
nuclear@33
|
188 {
|
nuclear@33
|
189 handle_mouse(ev, 0);
|
nuclear@33
|
190 }
|
nuclear@33
|
191
|
nuclear@33
|
192 -(void) rightMouseDown: (NSEvent*) ev
|
nuclear@33
|
193 {
|
nuclear@33
|
194 handle_mouse(ev, 1);
|
nuclear@33
|
195 }
|
nuclear@33
|
196
|
nuclear@33
|
197 -(void) rightMouseUp: (NSEvent*) ev
|
nuclear@33
|
198 {
|
nuclear@33
|
199 handle_mouse(ev, 0);
|
nuclear@33
|
200 }
|
nuclear@33
|
201
|
nuclear@33
|
202 -(void) otherMouseDown: (NSEvent*) ev
|
nuclear@33
|
203 {
|
nuclear@33
|
204 handle_mouse(ev, 1);
|
nuclear@33
|
205 }
|
nuclear@33
|
206
|
nuclear@33
|
207 -(void) otherMouseUp: (NSEvent*) ev
|
nuclear@33
|
208 {
|
nuclear@33
|
209 handle_mouse(ev, 0);
|
nuclear@33
|
210 }
|
nuclear@33
|
211
|
nuclear@33
|
212 -(void) mouseDragged: (NSEvent*) ev
|
nuclear@33
|
213 {
|
nuclear@33
|
214 handle_motion(ev);
|
nuclear@33
|
215 }
|
nuclear@33
|
216
|
nuclear@33
|
217 -(void) rightMouseDragged: (NSEvent*) ev
|
nuclear@33
|
218 {
|
nuclear@33
|
219 handle_motion(ev);
|
nuclear@33
|
220 }
|
nuclear@33
|
221
|
nuclear@33
|
222 -(void) otherMouseDragged: (NSEvent*) ev
|
nuclear@33
|
223 {
|
nuclear@33
|
224 handle_motion(ev);
|
nuclear@33
|
225 }
|
nuclear@33
|
226
|
nuclear@33
|
227
|
nuclear@13
|
228 -(BOOL) acceptsFirstResponder
|
nuclear@13
|
229 {
|
nuclear@13
|
230 return YES;
|
nuclear@13
|
231 }
|
nuclear@13
|
232 @end
|
nuclear@13
|
233
|
nuclear@17
|
234 @implementation AppDelegate
|
nuclear@31
|
235 -(void) applicationWillFinishLaunching: (NSNotification*) notification
|
nuclear@31
|
236 {
|
nuclear@31
|
237 }
|
nuclear@31
|
238
|
nuclear@31
|
239 -(void) applicationDidFinishLaunching: (NSNotification*) notification
|
nuclear@31
|
240 {
|
nuclear@31
|
241 }
|
nuclear@31
|
242
|
nuclear@17
|
243 -(BOOL) applicationShouldTerminate: (NSApplication*) app
|
nuclear@17
|
244 {
|
nuclear@17
|
245 return NSTerminateNow;
|
nuclear@17
|
246 }
|
nuclear@17
|
247
|
nuclear@17
|
248 -(BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) app
|
nuclear@16
|
249 {
|
nuclear@16
|
250 return YES;
|
nuclear@16
|
251 }
|
nuclear@17
|
252
|
nuclear@17
|
253 -(void) applicationWillTerminate: (NSNotification*) notification
|
nuclear@17
|
254 {
|
nuclear@32
|
255 /*[NSApp setDelegate: nil];
|
nuclear@32
|
256 [global_pool drain];*/
|
nuclear@32
|
257 }
|
nuclear@32
|
258 @end
|
nuclear@32
|
259
|
nuclear@32
|
260 @implementation WinDelegate
|
nuclear@32
|
261 -(id) init
|
nuclear@32
|
262 {
|
nuclear@32
|
263 self = [super init];
|
nuclear@32
|
264 return self;
|
nuclear@32
|
265 }
|
nuclear@32
|
266
|
nuclear@32
|
267 -(void) dealloc
|
nuclear@32
|
268 {
|
nuclear@32
|
269 [super dealloc];
|
nuclear@32
|
270 }
|
nuclear@32
|
271
|
nuclear@32
|
272 -(void) windowDidExpose: (NSNotification*) notification
|
nuclear@32
|
273 {
|
nuclear@32
|
274 }
|
nuclear@32
|
275
|
nuclear@32
|
276 -(void) windowDidResize: (NSNotification*) notification
|
nuclear@32
|
277 {
|
nuclear@17
|
278 }
|
nuclear@17
|
279
|
nuclear@17
|
280 -(BOOL) windowShouldClose: (id) win
|
nuclear@17
|
281 {
|
nuclear@32
|
282 assert(self->win);
|
nuclear@32
|
283 close_window(self->win->wid);
|
nuclear@17
|
284 return YES;
|
nuclear@17
|
285 }
|
nuclear@17
|
286
|
nuclear@17
|
287 -(void) windowWillClose: (NSNotification*) notification
|
nuclear@17
|
288 {
|
nuclear@31
|
289 /*[NSApp terminate: nil];*/
|
nuclear@17
|
290 }
|
nuclear@16
|
291 @end
|
nuclear@16
|
292
|
nuclear@13
|
293 static int init(void)
|
nuclear@13
|
294 {
|
nuclear@17
|
295 AppDelegate *delegate;
|
nuclear@16
|
296
|
nuclear@31
|
297 global_pool = [[NSAutoreleasePool alloc] init];
|
nuclear@31
|
298
|
nuclear@16
|
299 [NSApplication sharedApplication];
|
nuclear@17
|
300
|
nuclear@17
|
301 delegate = [[AppDelegate alloc] init];
|
nuclear@16
|
302 [NSApp setDelegate: delegate];
|
nuclear@15
|
303 return 0;
|
nuclear@13
|
304 }
|
nuclear@13
|
305
|
nuclear@13
|
306 static void shutdown(void)
|
nuclear@13
|
307 {
|
nuclear@13
|
308 while(winlist) {
|
nuclear@31
|
309 close_window(winlist->wid);
|
nuclear@13
|
310 }
|
nuclear@16
|
311
|
nuclear@17
|
312 quit_main_loop = 1;
|
nuclear@32
|
313 [NSApp terminate: nil];
|
nuclear@13
|
314 }
|
nuclear@13
|
315
|
nuclear@13
|
316
|
nuclear@13
|
317 /* video mode switching */
|
nuclear@13
|
318 static int set_vidmode(int xsz, int ysz)
|
nuclear@13
|
319 {
|
nuclear@13
|
320 return 0; /* TODO */
|
nuclear@13
|
321 }
|
nuclear@13
|
322
|
nuclear@13
|
323 static int get_vidmode(int *xsz, int *ysz)
|
nuclear@13
|
324 {
|
nuclear@13
|
325 return 0; /* TODO */
|
nuclear@13
|
326 }
|
nuclear@13
|
327
|
nuclear@13
|
328
|
nuclear@13
|
329 /* create/destroy windows */
|
nuclear@13
|
330 static int create_window(int xsz, int ysz, unsigned int flags)
|
nuclear@13
|
331 {
|
nuclear@17
|
332 NSAutoreleasePool *pool;
|
nuclear@32
|
333 WinDelegate *delegate;
|
nuclear@13
|
334 NSWindow *nswin;
|
nuclear@13
|
335 NSRect rect;
|
nuclear@15
|
336 OpenGLView *view;
|
nuclear@17
|
337 NSOpenGLPixelFormat *pf;
|
nuclear@17
|
338 NSOpenGLPixelFormatAttribute attr[32];
|
nuclear@13
|
339 unsigned int style;
|
nuclear@15
|
340 struct window *win;
|
nuclear@13
|
341 static int next_id = 1;
|
nuclear@13
|
342
|
nuclear@13
|
343 if(!(win = malloc(sizeof *win))) {
|
nuclear@13
|
344 return -1;
|
nuclear@13
|
345 }
|
nuclear@13
|
346
|
nuclear@17
|
347 pool = [[NSAutoreleasePool alloc] init];
|
nuclear@17
|
348
|
nuclear@17
|
349 /* create the view */
|
nuclear@17
|
350 fill_attr(attr, flags);
|
nuclear@17
|
351 pf = [[[NSOpenGLPixelFormat alloc] initWithAttributes: attr] autorelease];
|
nuclear@17
|
352 view = [[OpenGLView alloc] initWithFrame: rect pixelFormat: pf];
|
nuclear@17
|
353
|
nuclear@13
|
354 /* create the window and attach the OpenGL view */
|
nuclear@15
|
355 rect.origin.x = rect.origin.y = 0;
|
nuclear@15
|
356 rect.size.width = xsz;
|
nuclear@15
|
357 rect.size.height = ysz;
|
nuclear@13
|
358
|
nuclear@15
|
359 style = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask |
|
nuclear@15
|
360 NSResizableWindowMask;
|
nuclear@13
|
361
|
nuclear@13
|
362 nswin = [[NSWindow alloc] initWithContentRect: rect styleMask: style
|
nuclear@13
|
363 backing: NSBackingStoreBuffered defer: YES];
|
nuclear@17
|
364
|
nuclear@32
|
365 delegate = [[WinDelegate alloc] init];
|
nuclear@32
|
366
|
nuclear@32
|
367 [nswin setDelegate: delegate];
|
nuclear@16
|
368 [nswin setTitle: @"OpenGL/Cocoa"];
|
nuclear@17
|
369 [nswin setReleasedWhenClosed: YES];
|
nuclear@13
|
370 [nswin setContentView: view];
|
nuclear@16
|
371 [nswin makeFirstResponder: view];
|
nuclear@16
|
372 [nswin makeKeyAndOrderFront: nil];
|
nuclear@15
|
373 [view release];
|
nuclear@13
|
374
|
nuclear@13
|
375 win->win = nswin;
|
nuclear@13
|
376 win->view = view;
|
nuclear@15
|
377 win->ctx = [view openGLContext];
|
nuclear@13
|
378 win->wid = next_id++;
|
nuclear@15
|
379 win->needs_redisplay = 1;
|
nuclear@13
|
380 win->next = winlist;
|
nuclear@13
|
381 winlist = win;
|
nuclear@13
|
382
|
nuclear@32
|
383 delegate->win = win;
|
nuclear@32
|
384
|
nuclear@15
|
385 if(!active_win) {
|
nuclear@15
|
386 activate_window(win);
|
nuclear@15
|
387 }
|
nuclear@17
|
388
|
nuclear@17
|
389 [pool drain];
|
nuclear@13
|
390 return win->wid;
|
nuclear@13
|
391 }
|
nuclear@13
|
392
|
nuclear@13
|
393 static void close_window(int wid)
|
nuclear@13
|
394 {
|
nuclear@13
|
395 struct window *win, *prev, dummy;
|
nuclear@13
|
396 sgl_close_callback_t close_func;
|
nuclear@13
|
397
|
nuclear@13
|
398 dummy.next = win = winlist;
|
nuclear@13
|
399 prev = &dummy;
|
nuclear@13
|
400
|
nuclear@13
|
401 while(win) {
|
nuclear@13
|
402 if(win->wid == wid) {
|
nuclear@32
|
403 if((close_func = sgl_get_callback(SGL_CLOSE))) {
|
nuclear@13
|
404 close_func(wid);
|
nuclear@13
|
405 }
|
nuclear@13
|
406 [win->win close];
|
nuclear@13
|
407
|
nuclear@31
|
408 prev->next = win->next;
|
nuclear@31
|
409
|
nuclear@31
|
410 if(!dummy.next) {
|
nuclear@31
|
411 winlist = 0;
|
nuclear@31
|
412 }
|
nuclear@31
|
413
|
nuclear@13
|
414 if(active_win == win) {
|
nuclear@13
|
415 activate_window(winlist);
|
nuclear@13
|
416 }
|
nuclear@13
|
417 free(win);
|
nuclear@31
|
418 break;
|
nuclear@13
|
419 }
|
nuclear@13
|
420 prev = win;
|
nuclear@13
|
421 win = win->next;
|
nuclear@13
|
422 }
|
nuclear@31
|
423
|
nuclear@32
|
424 if(!dummy.next) {
|
nuclear@32
|
425 winlist = 0;
|
nuclear@31
|
426 shutdown();
|
nuclear@31
|
427 }
|
nuclear@13
|
428 }
|
nuclear@13
|
429
|
nuclear@13
|
430
|
nuclear@13
|
431 /* window management */
|
nuclear@13
|
432 static int set_active(int wid)
|
nuclear@13
|
433 {
|
nuclear@15
|
434 struct window *win = find_window(wid);
|
nuclear@15
|
435 return activate_window(win);
|
nuclear@13
|
436 }
|
nuclear@13
|
437
|
nuclear@13
|
438 static struct window *find_window(int wid)
|
nuclear@13
|
439 {
|
nuclear@13
|
440 struct window *win = winlist;
|
nuclear@13
|
441
|
nuclear@13
|
442 while(win) {
|
nuclear@15
|
443 if(win->wid == wid) {
|
nuclear@13
|
444 return win;
|
nuclear@13
|
445 }
|
nuclear@13
|
446 win = win->next;
|
nuclear@13
|
447 }
|
nuclear@13
|
448 return 0;
|
nuclear@13
|
449 }
|
nuclear@13
|
450
|
nuclear@13
|
451 static int activate_window(struct window *win)
|
nuclear@13
|
452 {
|
nuclear@13
|
453 if(!win) {
|
nuclear@13
|
454 return -1;
|
nuclear@13
|
455 }
|
nuclear@13
|
456 [win->ctx makeCurrentContext];
|
nuclear@13
|
457 active_win = win;
|
nuclear@13
|
458 return 0;
|
nuclear@13
|
459 }
|
nuclear@13
|
460
|
nuclear@13
|
461 static int set_title(const char *str)
|
nuclear@13
|
462 {
|
nuclear@13
|
463 NSString *nsstr;
|
nuclear@13
|
464
|
nuclear@13
|
465 nsstr = [[NSString alloc] initWithCString: str encoding: NSASCIIStringEncoding];
|
nuclear@13
|
466 [active_win->win setTitle: nsstr];
|
nuclear@13
|
467 [nsstr release];
|
nuclear@15
|
468 return 0;
|
nuclear@13
|
469 }
|
nuclear@13
|
470
|
nuclear@13
|
471 static void redisplay(void)
|
nuclear@13
|
472 {
|
nuclear@15
|
473 active_win->needs_redisplay = 1;
|
nuclear@13
|
474 }
|
nuclear@13
|
475
|
nuclear@13
|
476 static void swap_buffers(void)
|
nuclear@13
|
477 {
|
nuclear@15
|
478 [active_win->ctx flushBuffer];
|
nuclear@13
|
479 }
|
nuclear@13
|
480
|
nuclear@13
|
481
|
nuclear@13
|
482 static int get_modifiers(void)
|
nuclear@13
|
483 {
|
nuclear@33
|
484 unsigned int nsmod = [NSEvent modifierFlags];
|
nuclear@33
|
485 unsigned int mod = 0;
|
nuclear@33
|
486
|
nuclear@33
|
487 if(nsmod & NSShiftKeyMask) {
|
nuclear@33
|
488 mod |= SGL_MOD_SHIFT;
|
nuclear@33
|
489 }
|
nuclear@33
|
490 if(nsmod & NSControlKeyMask) {
|
nuclear@33
|
491 mod |= SGL_MOD_CONTROL;
|
nuclear@33
|
492 }
|
nuclear@33
|
493 if(nsmod & NSAlternateKeyMask) {
|
nuclear@33
|
494 mod |= SGL_MOD_ALT;
|
nuclear@33
|
495 }
|
nuclear@33
|
496 return mod;
|
nuclear@13
|
497 }
|
nuclear@13
|
498
|
nuclear@13
|
499
|
nuclear@13
|
500 /* event handling and friends */
|
nuclear@13
|
501 static void set_event(int idx, int enable)
|
nuclear@13
|
502 {
|
nuclear@13
|
503 }
|
nuclear@13
|
504
|
nuclear@13
|
505 static int process_events(void)
|
nuclear@13
|
506 {
|
nuclear@13
|
507 NSAutoreleasePool *pool;
|
nuclear@17
|
508 NSRunLoop *runloop;
|
nuclear@17
|
509 NSDate *block, *nonblock, *limdate;
|
nuclear@17
|
510
|
nuclear@14
|
511 sgl_idle_callback_t idle;
|
nuclear@15
|
512 sgl_display_callback_t disp;
|
nuclear@15
|
513 struct window *win;
|
nuclear@15
|
514
|
nuclear@15
|
515 pool = [[NSAutoreleasePool alloc] init];
|
nuclear@16
|
516
|
nuclear@16
|
517 idle = sgl_get_callback(SGL_IDLE);
|
nuclear@15
|
518 disp = sgl_get_callback(SGL_DISPLAY);
|
nuclear@13
|
519
|
nuclear@15
|
520 win = winlist;
|
nuclear@15
|
521 while(win) {
|
nuclear@15
|
522 if(win->needs_redisplay && disp) {
|
nuclear@15
|
523 activate_window(win);
|
nuclear@15
|
524 disp();
|
nuclear@15
|
525 win->needs_redisplay = 0;
|
nuclear@15
|
526 }
|
nuclear@15
|
527 win = win->next;
|
nuclear@15
|
528 }
|
nuclear@15
|
529
|
nuclear@17
|
530 runloop = [[NSRunLoop currentRunLoop] retain];
|
nuclear@17
|
531 block = [runloop limitDateForMode: NSDefaultRunLoopMode];
|
nuclear@17
|
532 nonblock = [[NSDate distantPast] retain];
|
nuclear@16
|
533 limdate = idle ? nonblock : block;
|
nuclear@15
|
534
|
nuclear@17
|
535 while(!quit_main_loop) {
|
nuclear@16
|
536 NSEvent *ev = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: limdate
|
nuclear@16
|
537 inMode: NSDefaultRunLoopMode dequeue: YES];
|
nuclear@16
|
538 if(!ev) break;
|
nuclear@16
|
539
|
nuclear@16
|
540 [NSApp sendEvent: ev];
|
nuclear@16
|
541 if(limdate == block) {
|
nuclear@16
|
542 limdate = nonblock;
|
nuclear@13
|
543 }
|
nuclear@15
|
544 }
|
nuclear@15
|
545
|
nuclear@15
|
546 if(idle) {
|
nuclear@15
|
547 idle();
|
nuclear@15
|
548 }
|
nuclear@15
|
549
|
nuclear@17
|
550 [runloop release];
|
nuclear@15
|
551 [pool drain];
|
nuclear@31
|
552
|
nuclear@31
|
553 /*sgl_log("%s returning: %d\n", __func__, quit_main_loop ? -1 : 0);*/
|
nuclear@17
|
554 return quit_main_loop ? -1 : 0;
|
nuclear@13
|
555 }
|
nuclear@13
|
556
|
nuclear@33
|
557 static void select_event_window(NSEvent *ev)
|
nuclear@33
|
558 {
|
nuclear@33
|
559 NSWindow *nswin;
|
nuclear@33
|
560 WinDelegate *del;
|
nuclear@33
|
561 struct window *win;
|
nuclear@33
|
562
|
nuclear@33
|
563 if(!ev || !(nswin = [ev window])) {
|
nuclear@33
|
564 sgl_log("%s failed\n", __func__);
|
nuclear@33
|
565 return;
|
nuclear@33
|
566 }
|
nuclear@33
|
567 del = [nswin delegate];
|
nuclear@33
|
568 win = del->win;
|
nuclear@33
|
569
|
nuclear@33
|
570 activate_window(win);
|
nuclear@33
|
571 }
|
nuclear@33
|
572
|
nuclear@33
|
573 static void handle_key(NSEvent *ev, int state)
|
nuclear@33
|
574 {
|
nuclear@33
|
575 NSString *str;
|
nuclear@33
|
576 sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
|
nuclear@33
|
577
|
nuclear@33
|
578 if(func) {
|
nuclear@33
|
579 str = [ev characters];
|
nuclear@33
|
580 if([str length]) {
|
nuclear@33
|
581 unichar c = [str characterAtIndex: 0];
|
nuclear@33
|
582
|
nuclear@33
|
583 select_event_window(ev);
|
nuclear@33
|
584 func(c, state);
|
nuclear@33
|
585 }
|
nuclear@33
|
586 }
|
nuclear@33
|
587 }
|
nuclear@33
|
588
|
nuclear@33
|
589 static void handle_mouse(NSEvent *ev, int state)
|
nuclear@33
|
590 {
|
nuclear@33
|
591 int bn;
|
nuclear@33
|
592 NSPoint pt;
|
nuclear@33
|
593 sgl_mouse_callback_t func = sgl_get_callback(SGL_MOUSE);
|
nuclear@33
|
594
|
nuclear@33
|
595 if(func) {
|
nuclear@33
|
596 bn = [ev buttonNumber];
|
nuclear@33
|
597 if(bn == 2) {
|
nuclear@33
|
598 bn = 1;
|
nuclear@33
|
599 } else if(bn == 1) {
|
nuclear@33
|
600 bn = 2;
|
nuclear@33
|
601 }
|
nuclear@33
|
602 pt = [ev locationInWindow];
|
nuclear@33
|
603
|
nuclear@33
|
604 select_event_window(ev);
|
nuclear@33
|
605 func(0, bn, state, pt.x, pt.y - 1);
|
nuclear@33
|
606 }
|
nuclear@33
|
607 }
|
nuclear@33
|
608
|
nuclear@33
|
609 static void handle_motion(NSEvent *ev)
|
nuclear@33
|
610 {
|
nuclear@33
|
611 NSPoint pt;
|
nuclear@33
|
612 sgl_motion_callback_t func = sgl_get_callback(SGL_MOTION);
|
nuclear@33
|
613
|
nuclear@33
|
614 if(func) {
|
nuclear@33
|
615 pt = [ev locationInWindow];
|
nuclear@33
|
616
|
nuclear@33
|
617 select_event_window(ev);
|
nuclear@33
|
618 func(0, pt.x, pt.y - 1);
|
nuclear@33
|
619 }
|
nuclear@33
|
620 }
|
nuclear@33
|
621
|
nuclear@17
|
622 static void fill_attr(NSOpenGLPixelFormatAttribute *attr, unsigned int flags)
|
nuclear@13
|
623 {
|
nuclear@17
|
624 int i = 0;
|
nuclear@14
|
625
|
nuclear@17
|
626 /* this is very important. makes pixelformat selection behave like GLX
|
nuclear@17
|
627 * where any non-zero value will denote "choose highest possible". This
|
nuclear@17
|
628 * is pretty much what we intend, as the user doesn't actually pass any
|
nuclear@17
|
629 * of these numbers.
|
nuclear@17
|
630 */
|
nuclear@17
|
631 attr[i++] = NSOpenGLPFAMaximumPolicy;
|
nuclear@17
|
632
|
nuclear@17
|
633 attr[i++] = NSOpenGLPFAColorSize;
|
nuclear@17
|
634 attr[i++] = 1;
|
nuclear@17
|
635
|
nuclear@17
|
636 if(flags & SGL_DOUBLE) {
|
nuclear@17
|
637 attr[i++] = NSOpenGLPFADoubleBuffer;
|
nuclear@15
|
638 }
|
nuclear@17
|
639 if(flags & SGL_DEPTH) {
|
nuclear@17
|
640 attr[i++] = NSOpenGLPFADepthSize;
|
nuclear@17
|
641 attr[i++] = 1;
|
nuclear@17
|
642 }
|
nuclear@17
|
643 if(flags & SGL_STENCIL) {
|
nuclear@17
|
644 attr[i++] = NSOpenGLPFAStencilSize;
|
nuclear@17
|
645 attr[i++] = 8; /* max-policy has no effect on stencil selection */
|
nuclear@17
|
646 }
|
nuclear@17
|
647 if(flags & SGL_STEREO) {
|
nuclear@17
|
648 attr[i++] = NSOpenGLPFAStereo;
|
nuclear@17
|
649 }
|
nuclear@17
|
650 if(flags & SGL_MULTISAMPLE) {
|
nuclear@17
|
651 attr[i++] = NSOpenGLPFASampleBuffers;
|
nuclear@17
|
652 attr[i++] = 1;
|
nuclear@17
|
653 attr[i++] = NSOpenGLPFASamples;
|
nuclear@17
|
654 attr[i++] = 4; /* TODO don't hardcode, query */
|
nuclear@17
|
655 }
|
nuclear@17
|
656 attr[i++] = 0;
|
nuclear@13
|
657 }
|
nuclear@13
|
658
|
nuclear@20
|
659 #else
|
nuclear@20
|
660 int sgl_wsys_cocoa_silence_the_fucking_empty_file_warnings;
|
nuclear@13
|
661 #endif /* USE_WSYS_MODULE_COCOA */
|