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