nuclear@13: /* mac-framework: -framework Cocoa */ nuclear@13: nuclear@13: #include "config.h" nuclear@13: nuclear@13: #ifdef USE_WSYS_MODULE_COCOA nuclear@13: nuclear@16: #import nuclear@16: #import nuclear@16: nuclear@13: #include "sgl.h" nuclear@15: #include "wsys.h" nuclear@13: nuclear@16: @interface GLView : NSOpenGLView nuclear@13: { nuclear@16: struct window *win; nuclear@13: } nuclear@13: nuclear@16: -(id) initWithFrame: (NSRect) frameRect; nuclear@13: nuclear@13: -(void) drawRect: (NSRect) rect; nuclear@13: -(void) reshape; nuclear@16: -(void) keyDown: (NSEvent*) ev; nuclear@13: -(void) keyUp: (NSEvent*) ev; nuclear@13: -(void) mouseDown: (NSEvent*) ev; nuclear@13: -(void) mouseUp: (NSEvent*) ev; nuclear@13: -(void) rightMouseDown: (NSEvent*) ev; nuclear@13: -(void) rightMouseUp: (NSEvent*) ev; nuclear@13: -(void) otherMouseDown: (NSEvent*) ev; nuclear@13: -(void) otherMouseUp: (NSEvent*) ev; nuclear@13: -(void) mouseDragged: (NSEvent*) ev; nuclear@13: -(void) rightMouseDragged: (NSEvent*) ev; nuclear@16: -(void) otherMouseDragged: (NSEvent*) ev; nuclear@13: nuclear@13: -(BOOL) acceptsFirstResponder; nuclear@13: @end nuclear@13: nuclear@16: @interface AppDelegate nuclear@16: { nuclear@16: } nuclear@16: -(BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*)app; nuclear@16: @end nuclear@16: nuclear@13: struct window { nuclear@13: int wid; nuclear@15: int width, height; nuclear@13: NSWindow *win; nuclear@16: GLView *view; nuclear@15: NSOpenGLContext *ctx; nuclear@13: struct window *next; nuclear@13: }; nuclear@13: nuclear@13: nuclear@13: static int init(void); nuclear@13: static void shutdown(void); nuclear@13: nuclear@13: /* video mode switching */ nuclear@13: static int set_vidmode(int xsz, int ysz); nuclear@13: static int get_vidmode(int *xsz, int *ysz); nuclear@13: nuclear@13: /* create/destroy windows */ nuclear@13: static int create_window(int xsz, int ysz, unsigned int flags); nuclear@13: static void close_window(int wid); nuclear@13: nuclear@13: /* window management */ nuclear@13: static int set_active(int wid); nuclear@13: static struct window *find_window(int wid); nuclear@13: static int activate_window(struct window *win); nuclear@13: static int set_title(const char *str); nuclear@13: static void redisplay(void); nuclear@13: static void swap_buffers(void); nuclear@13: nuclear@13: static int get_modifiers(void); nuclear@13: nuclear@13: /* event handling and friends */ nuclear@13: static void set_event(int idx, int enable); nuclear@13: static int process_events(void); nuclear@13: static int handle_event(NSEvent *ev); nuclear@13: nuclear@13: nuclear@13: static struct wsys_module ws = { nuclear@13: "cocoa", 0, nuclear@13: init, nuclear@13: shutdown, nuclear@13: set_vidmode, nuclear@13: get_vidmode, nuclear@13: create_window, nuclear@13: close_window, nuclear@13: set_active, nuclear@13: set_title, nuclear@13: redisplay, nuclear@13: swap_buffers, nuclear@13: get_modifiers, nuclear@13: set_event, nuclear@13: process_events, nuclear@13: 0 nuclear@13: }; nuclear@13: nuclear@13: static struct window *winlist, *active_win; nuclear@16: static NSDate *block, *nonblock; nuclear@16: static NSRunLoop *runloop; nuclear@13: nuclear@13: nuclear@13: void sgl_register_cocoa(void) nuclear@13: { nuclear@15: sgl_register_module(&ws); nuclear@13: } nuclear@13: nuclear@13: nuclear@16: @implementation GLView nuclear@16: nuclear@16: -(id) initWithFrame: (NSRect) frameRect nuclear@16: { nuclear@16: } nuclear@13: nuclear@13: -(void) drawRect: (NSRect) rect nuclear@13: { nuclear@13: sgl_display_callback_t func = sgl_get_callback(SGL_DISPLAY); nuclear@13: if(func) { nuclear@13: func(); nuclear@13: } nuclear@13: } nuclear@13: nuclear@13: -(void) reshape nuclear@13: { nuclear@15: NSSize sz; nuclear@15: sgl_reshape_callback_t func; nuclear@15: nuclear@15: sz = [self bounds].size; nuclear@15: nuclear@15: if((func = sgl_get_callback(SGL_RESHAPE)) && (sz.width != active_win->width || nuclear@15: sz.height != active_win->height)) { nuclear@15: active_win->width = sz.width; nuclear@15: active_win->height = sz.height; nuclear@15: func(sz.width, sz.height); nuclear@13: } nuclear@13: } nuclear@13: nuclear@13: -(BOOL) acceptsFirstResponder nuclear@13: { nuclear@13: return YES; nuclear@13: } nuclear@13: @end nuclear@13: nuclear@16: @implementation AppDelegate : NSObject nuclear@16: -(BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*)app nuclear@16: { nuclear@16: return YES; nuclear@16: } nuclear@16: @end nuclear@16: nuclear@13: static int init(void) nuclear@13: { nuclear@16: if(NSApp) { nuclear@16: sgl_log("wsys_cocoa: multiple calls to init\n"); nuclear@16: return 0; nuclear@16: } nuclear@16: nuclear@16: NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; nuclear@16: nuclear@16: [NSApplication sharedApplication]; nuclear@16: [NSApp setDelegate: delegate]; nuclear@16: nuclear@16: runloop = [[NSRunLoop currentRunLoop] retain]; nuclear@16: block = [runloop limitDateForMode: NSDefaultRunLoopMode]; nuclear@16: nonblock = [[NSDate distantPast] retain]; nuclear@16: nuclear@16: [pool drain]; nuclear@15: return 0; nuclear@13: } nuclear@13: nuclear@13: static void shutdown(void) nuclear@13: { nuclear@13: while(winlist) { nuclear@13: struct window *win = winlist; nuclear@13: winlist = winlist->next; nuclear@13: nuclear@16: [win->win close]; nuclear@13: free(win); nuclear@13: } nuclear@16: nuclear@16: [NSApp stop: nil]; nuclear@16: [NSApp terminate: nil]; nuclear@16: NSApp = 0; nuclear@13: } nuclear@13: nuclear@13: nuclear@13: /* video mode switching */ nuclear@13: static int set_vidmode(int xsz, int ysz) nuclear@13: { nuclear@13: return 0; /* TODO */ nuclear@13: } nuclear@13: nuclear@13: static int get_vidmode(int *xsz, int *ysz) nuclear@13: { nuclear@13: return 0; /* TODO */ nuclear@13: } nuclear@13: nuclear@13: nuclear@13: /* create/destroy windows */ nuclear@13: static int create_window(int xsz, int ysz, unsigned int flags) nuclear@13: { nuclear@13: NSWindow *nswin; nuclear@13: NSRect rect; nuclear@16: GLView *view; nuclear@13: unsigned int style; nuclear@13: static int next_id = 1; nuclear@13: nuclear@13: if(!(win = malloc(sizeof *win))) { nuclear@13: return -1; nuclear@13: } nuclear@13: nuclear@13: /* create the window and attach the OpenGL view */ nuclear@16: rect = NSMakeRect(0, 0, xsz, ysz); nuclear@16: view = [[GLView alloc] initWithFrame: rect]; nuclear@13: nuclear@16: style = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | nuclear@16: NSMiniaturizableWindowMask; nuclear@13: nuclear@13: nswin = [[NSWindow alloc] initWithContentRect: rect styleMask: style nuclear@13: backing: NSBackingStoreBuffered defer: YES]; nuclear@16: [nswin setTitle: @"OpenGL/Cocoa"]; nuclear@16: [nswin setReleaseWhenClosed: YES]; nuclear@13: [nswin setContentView: view]; nuclear@16: [nswin makeFirstResponder: view]; nuclear@16: [nswin makeKeyAndOrderFront: nil]; nuclear@16: nuclear@16: [pool drain]; nuclear@13: nuclear@13: win->win = nswin; nuclear@13: win->view = view; nuclear@13: win->wid = next_id++; nuclear@13: win->next = winlist; nuclear@13: winlist = win; nuclear@13: nuclear@15: if(!active_win) { nuclear@15: activate_window(win); nuclear@15: } nuclear@13: return win->wid; nuclear@13: } nuclear@13: nuclear@13: static void close_window(int wid) nuclear@13: { nuclear@13: struct window *win, *prev, dummy; nuclear@13: sgl_close_callback_t close_func; nuclear@13: nuclear@13: dummy.next = win = winlist; nuclear@13: prev = &dummy; nuclear@13: nuclear@13: while(win) { nuclear@13: if(win->wid == wid) { nuclear@13: if(!(close_func = sgl_get_callback(SGL_CLOSE))) { nuclear@13: close_func(wid); nuclear@13: } nuclear@13: [win->win close]; nuclear@13: nuclear@13: if(active_win == win) { nuclear@13: activate_window(winlist); nuclear@13: } nuclear@13: nuclear@13: prev->next = win->next; nuclear@13: free(win); nuclear@13: return; nuclear@13: } nuclear@13: prev = win; nuclear@13: win = win->next; nuclear@13: } nuclear@13: } nuclear@13: nuclear@13: nuclear@13: /* window management */ nuclear@13: static int set_active(int wid) nuclear@13: { nuclear@15: struct window *win = find_window(wid); nuclear@15: return activate_window(win); nuclear@13: } nuclear@13: nuclear@13: static struct window *find_window(int wid) nuclear@13: { nuclear@13: struct window *win = winlist; nuclear@13: nuclear@13: while(win) { nuclear@15: if(win->wid == wid) { nuclear@13: return win; nuclear@13: } nuclear@13: win = win->next; nuclear@13: } nuclear@13: return 0; nuclear@13: } nuclear@13: nuclear@13: static int activate_window(struct window *win) nuclear@13: { nuclear@13: if(!win) { nuclear@13: return -1; nuclear@13: } nuclear@13: [win->ctx makeCurrentContext]; nuclear@13: active_win = win; nuclear@13: return 0; nuclear@13: } nuclear@13: nuclear@13: static int set_title(const char *str) nuclear@13: { nuclear@13: NSString *nsstr; nuclear@13: nuclear@13: nsstr = [[NSString alloc] initWithCString: str encoding: NSASCIIStringEncoding]; nuclear@13: [active_win->win setTitle: nsstr]; nuclear@13: [nsstr release]; nuclear@15: return 0; nuclear@13: } nuclear@13: nuclear@13: static void redisplay(void) nuclear@13: { nuclear@15: active_win->needs_redisplay = 1; nuclear@13: } nuclear@13: nuclear@13: static void swap_buffers(void) nuclear@13: { nuclear@15: [active_win->ctx flushBuffer]; nuclear@13: } nuclear@13: nuclear@13: nuclear@13: static int get_modifiers(void) nuclear@13: { nuclear@13: return 0; /* TODO */ nuclear@13: } nuclear@13: nuclear@13: nuclear@13: /* event handling and friends */ nuclear@13: static void set_event(int idx, int enable) nuclear@13: { nuclear@13: } nuclear@13: nuclear@13: static int process_events(void) nuclear@13: { nuclear@13: NSAutoreleasePool *pool; nuclear@16: NSDate *limdate; nuclear@14: sgl_idle_callback_t idle; nuclear@16: nuclear@16: idle = sgl_get_callback(SGL_IDLE); nuclear@13: nuclear@13: pool = [[NSAutoreleasePool alloc] init]; nuclear@16: limdate = idle ? nonblock : block; nuclear@15: nuclear@13: for(;;) { nuclear@16: NSEvent *ev = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: limdate nuclear@16: inMode: NSDefaultRunLoopMode dequeue: YES]; nuclear@16: if(!ev) break; nuclear@16: nuclear@16: [NSApp sendEvent: ev]; nuclear@16: if(limdate == block) { nuclear@16: limdate = nonblock; nuclear@13: } nuclear@15: } nuclear@15: nuclear@15: [pool drain]; nuclear@15: return 0; nuclear@13: } nuclear@13: nuclear@13: static int handle_event(NSEvent *ev) nuclear@13: { nuclear@14: switch([ev type]) { nuclear@14: case NSKeyDown: nuclear@14: case NSKeyUp: nuclear@15: printf("key pressed\n"); nuclear@15: break; nuclear@14: nuclear@15: default: nuclear@15: break; nuclear@15: } nuclear@15: return 0; nuclear@13: } nuclear@13: nuclear@13: #endif /* USE_WSYS_MODULE_COCOA */