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