]> git.tdb.fi Git - libs/gui.git/blobdiff - source/graphics/cocoa/cocoadisplay.m
Basic OS X support
[libs/gui.git] / source / graphics / cocoa / cocoadisplay.m
diff --git a/source/graphics/cocoa/cocoadisplay.m b/source/graphics/cocoa/cocoadisplay.m
new file mode 100644 (file)
index 0000000..5b7b064
--- /dev/null
@@ -0,0 +1,76 @@
+#import <AppKit/NSApplication.h>
+#import <Foundation/NSRunLoop.h>
+#include "cocoadisplay.h"
+
+void convert_event(NSEvent *, CocoaEvent *);
+
+struct _CocoaDisplay
+{
+       NSApplication *app;
+       CFMutableArrayRef event_queue;
+};
+
+const void *copy_event(CFAllocatorRef, const void *);
+void free_event(CFAllocatorRef, const void *);
+
+CocoaDisplay *create_display()
+{
+       CocoaDisplay *display = (CocoaDisplay *)malloc(sizeof(CocoaDisplay));
+       display->app = [NSApplication sharedApplication];
+       // Since OS X 10.6
+       //[display->app setActivationPolicy:NSApplicationActivationPolicyRegular];
+       [display->app finishLaunching];
+
+       CFArrayCallBacks callbacks;
+       callbacks.version = 0;
+       callbacks.retain = copy_event;
+       callbacks.release = free_event;
+       callbacks.copyDescription = NULL;
+       callbacks.equal = NULL;
+       display->event_queue = CFArrayCreateMutable(NULL, 0, &callbacks);
+
+       return display;
+}
+
+void destroy_display(CocoaDisplay *display)
+{
+       CFRelease(display->event_queue);
+       free(display);
+}
+
+void queue_event(CocoaDisplay *display, CocoaEvent *event)
+{
+       CFArrayAppendValue(display->event_queue, event);
+}
+
+bool get_event(CocoaDisplay *display, CocoaEvent *buf)
+{
+       if(CFArrayGetCount(display->event_queue))
+       {
+               *buf = *(const CocoaEvent *)CFArrayGetValueAtIndex(display->event_queue, 0);
+               CFArrayRemoveValueAtIndex(display->event_queue, 0);
+               return true;
+       }
+
+       NSEvent *event = [display->app nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES];
+       if(event)
+       {
+               [display->app sendEvent:event];
+               convert_event(event, buf);
+               return true;
+       }
+
+       return false;
+}
+
+const void *copy_event(CFAllocatorRef allocator, const void *event)
+{
+       void *copy = CFAllocatorAllocate(allocator, sizeof(CocoaEvent), 0);
+       memcpy(copy, event, sizeof(CocoaEvent));
+       return copy;
+}
+
+void free_event(CFAllocatorRef allocator, const void *event)
+{
+       CFAllocatorDeallocate(allocator, (void *)event);
+}