]> git.tdb.fi Git - libs/gui.git/blob - source/graphics/cocoa/cocoadisplay.m
c6485a76ef5bbbbbe4ce28ab6141b0ce7dd60209
[libs/gui.git] / source / graphics / cocoa / cocoadisplay.m
1 #include <stdlib.h>
2 #include <string.h>
3 #import <AppKit/NSApplication.h>
4 #import <AppKit/NSEvent.h>
5 #import <Foundation/NSAutoReleasePool.h>
6 #import <Foundation/NSRunLoop.h>
7 #include "cocoadisplay.h"
8
9 void convert_event(NSEvent *, CocoaEvent *);
10
11 struct _CocoaDisplay
12 {
13         NSApplication *app;
14         NSAutoreleasePool *arp;
15         CFMutableArrayRef event_queue;
16 };
17
18 const void *copy_event(CFAllocatorRef, const void *);
19 void free_event(CFAllocatorRef, const void *);
20
21 CocoaDisplay *create_display()
22 {
23         CocoaDisplay *display = (CocoaDisplay *)malloc(sizeof(CocoaDisplay));
24         display->arp = [[NSAutoreleasePool alloc] init];
25         display->app = [NSApplication sharedApplication];
26 #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
27         // This makes windows appear when run from terminal
28         if([display->app respondsToSelector:@selector(setActivationPolicy:)])
29                 [display->app setActivationPolicy:NSApplicationActivationPolicyRegular];
30 #endif
31         [display->app finishLaunching];
32
33         CFArrayCallBacks callbacks;
34         callbacks.version = 0;
35         callbacks.retain = copy_event;
36         callbacks.release = free_event;
37         callbacks.copyDescription = NULL;
38         callbacks.equal = NULL;
39         display->event_queue = CFArrayCreateMutable(NULL, 0, &callbacks);
40
41         return display;
42 }
43
44 void destroy_display(CocoaDisplay *display)
45 {
46         CFRelease(display->event_queue);
47         [display->arp release];
48         free(display);
49 }
50
51 void queue_event(CocoaDisplay *display, CocoaEvent *event)
52 {
53         CFArrayAppendValue(display->event_queue, event);
54 }
55
56 bool get_event(CocoaDisplay *display, CocoaEvent *buf)
57 {
58         if(CFArrayGetCount(display->event_queue))
59         {
60                 *buf = *(const CocoaEvent *)CFArrayGetValueAtIndex(display->event_queue, 0);
61                 CFArrayRemoveValueAtIndex(display->event_queue, 0);
62                 return true;
63         }
64
65         NSEvent *event = [display->app nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES];
66         if(event)
67         {
68                 [event retain];
69                 [display->app sendEvent:event];
70                 convert_event(event, buf);
71                 [event release];
72                 return true;
73         }
74
75         return false;
76 }
77
78 const void *copy_event(CFAllocatorRef allocator, const void *event)
79 {
80         void *copy = CFAllocatorAllocate(allocator, sizeof(CocoaEvent), 0);
81         memcpy(copy, event, sizeof(CocoaEvent));
82         return copy;
83 }
84
85 void free_event(CFAllocatorRef allocator, const void *event)
86 {
87         CFAllocatorDeallocate(allocator, (void *)event);
88 }