sgl

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