--- /dev/null
+#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);
+}