3 #import <AppKit/NSApplication.h>
4 #import <AppKit/NSEvent.h>
5 #import <Foundation/NSAutoReleasePool.h>
6 #import <Foundation/NSRunLoop.h>
7 #import <ApplicationServices/ApplicationServices.h>
8 #include "cocoadisplay.h"
10 void convert_event(NSEvent *, CocoaEvent *);
15 NSAutoreleasePool *arp;
16 CFMutableArrayRef event_queue;
19 void make_foreground_app(NSApplication *);
20 const void *copy_event(CFAllocatorRef, const void *);
21 void free_event(CFAllocatorRef, const void *);
23 CocoaDisplay *create_display()
25 CocoaDisplay *display = (CocoaDisplay *)malloc(sizeof(CocoaDisplay));
26 display->arp = [[NSAutoreleasePool alloc] init];
27 display->app = [NSApplication sharedApplication];
28 make_foreground_app(display->app);
29 [display->app finishLaunching];
31 CFArrayCallBacks callbacks;
32 callbacks.version = 0;
33 callbacks.retain = copy_event;
34 callbacks.release = free_event;
35 callbacks.copyDescription = NULL;
36 callbacks.equal = NULL;
37 display->event_queue = CFArrayCreateMutable(NULL, 0, &callbacks);
42 void make_foreground_app(NSApplication *app)
44 #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
45 // This makes windows appear when run from terminal
46 if([app respondsToSelector:@selector(setActivationPolicy:)])
48 [app setActivationPolicy:NSApplicationActivationPolicyRegular];
55 ProcessSerialNumber psn = { 0, kCurrentProcess };
56 TransformProcessType(&psn, kProcessTransformToForegroundApplication);
57 SetFrontProcess(&psn);
60 void destroy_display(CocoaDisplay *display)
62 CFRelease(display->event_queue);
63 [display->arp release];
67 void queue_event(CocoaDisplay *display, CocoaEvent *event)
69 CFArrayAppendValue(display->event_queue, event);
72 bool get_event(CocoaDisplay *display, CocoaEvent *buf)
74 if(CFArrayGetCount(display->event_queue))
76 *buf = *(const CocoaEvent *)CFArrayGetValueAtIndex(display->event_queue, 0);
77 CFArrayRemoveValueAtIndex(display->event_queue, 0);
81 NSEvent *event = [display->app nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES];
85 [display->app sendEvent:event];
86 convert_event(event, buf);
94 const void *copy_event(CFAllocatorRef allocator, const void *event)
96 void *copy = CFAllocatorAllocate(allocator, sizeof(CocoaEvent), 0);
97 memcpy(copy, event, sizeof(CocoaEvent));
101 void free_event(CFAllocatorRef allocator, const void *event)
103 CFAllocatorDeallocate(allocator, (void *)event);