svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_cocoa / ecore_cocoa.m
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <Cocoa/Cocoa.h>
6
7 #include <Eina.h>
8
9 #include <Ecore.h>
10 #include <ecore_private.h>
11 #include <Ecore_Input.h>
12
13 #include "Ecore_Cocoa.h"
14 #include "Ecore_Cocoa_Keys.h"
15
16 EAPI int ECORE_COCOA_EVENT_GOT_FOCUS = 0;
17 EAPI int ECORE_COCOA_EVENT_LOST_FOCUS = 0;
18 EAPI int ECORE_COCOA_EVENT_RESIZE = 0;
19 EAPI int ECORE_COCOA_EVENT_EXPOSE = 0;
20
21 static int _ecore_cocoa_init_count = 0;
22
23 static int old_flags;
24
25 EAPI int
26 ecore_cocoa_init(const char *name __UNUSED__)
27 {
28    if (++_ecore_cocoa_init_count != 1)
29      return _ecore_cocoa_init_count;
30
31    if (!ecore_event_init())
32      return --_ecore_cocoa_init_count;
33
34    ECORE_COCOA_EVENT_GOT_FOCUS  = ecore_event_type_new();
35    ECORE_COCOA_EVENT_LOST_FOCUS = ecore_event_type_new();
36    ECORE_COCOA_EVENT_RESIZE     = ecore_event_type_new();
37    ECORE_COCOA_EVENT_EXPOSE     = ecore_event_type_new();
38
39    return _ecore_cocoa_init_count;
40 }
41
42 /**
43  * Shuts down the Ecore_Cocoa library.
44  * @return  @c The number of times the system has been initialised without
45  *             being shut down.
46  * @ingroup Ecore_Cocoa_Library_Group
47  */
48 EAPI int
49 ecore_cocoa_shutdown(void)
50 {
51    if (--_ecore_cocoa_init_count != 0)
52      return _ecore_cocoa_init_count;
53
54    ecore_event_shutdown();
55
56    return _ecore_cocoa_init_count;
57 }
58
59 EAPI void
60 ecore_cocoa_feed_events(void)
61 {
62    NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0.001];
63    NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask
64                                        untilDate:date
65                                           inMode:NSDefaultRunLoopMode
66                                          dequeue:YES];
67    [date release];
68    if (!event) return; // SDL loops until null; maybe we should do that too. or not.
69
70    unsigned int time = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff);
71
72    switch([event type])
73    {
74       case NSMouseMoved:
75       case NSLeftMouseDragged:
76       case NSRightMouseDragged:
77       case NSOtherMouseDragged:
78       {
79          Ecore_Event_Mouse_Move * ev = calloc(1, sizeof(Ecore_Event_Mouse_Move));
80          if (!ev) return;
81          ev->x = [event locationInWindow].x;
82          ev->y = [event locationInWindow].y;
83          ev->root.x = ev->x;
84          ev->root.y = ev->y;
85          ev->timestamp = time;
86          ev->window = [event window];
87          ev->modifiers = 0; /* FIXME: keep modifier around. */
88
89          ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL);
90
91          [NSApp sendEvent:event]; // pass along mouse events, for window manager
92          break;
93       }
94       case NSLeftMouseDown:
95       case NSRightMouseDown:
96       case NSOtherMouseDown:
97       {
98          Ecore_Event_Mouse_Button * ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
99          if (!ev) return;
100          ev->x = [event locationInWindow].x;
101          ev->y = [event locationInWindow].y;
102          ev->root.x = ev->x;
103          ev->root.y = ev->y;
104          ev->timestamp = time;
105          ev->buttons = [event buttonNumber] + 1; // Apple indexes buttons from 0
106
107          if ([event clickCount] == 2)
108             ev->double_click = 1;
109          else
110             ev->double_click = 0;
111
112          if ([event clickCount] >= 3)
113             ev->triple_click = 1;
114          else
115             ev->triple_click = 0;
116
117          ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
118
119          [NSApp sendEvent:event]; // pass along mouse events, for window manager
120          break;
121       }
122       case NSLeftMouseUp:
123       case NSRightMouseUp:
124       case NSOtherMouseUp:
125       {
126          Ecore_Event_Mouse_Button * ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
127          if (!ev) return;
128          ev->x = [event locationInWindow].x;
129          ev->y = [event locationInWindow].y;
130          ev->root.x = ev->x;
131          ev->root.y = ev->y;
132          ev->timestamp = time;
133          ev->buttons = [event buttonNumber] + 1; // Apple indexes buttons from 0
134
135          if ([event clickCount] == 2)
136             ev->double_click = 1;
137          else
138             ev->double_click = 0;
139
140          if ([event clickCount] >= 3)
141             ev->triple_click = 1;
142          else
143             ev->triple_click = 0;
144
145          ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
146
147          [NSApp sendEvent:event]; // pass along mouse events, for window manager
148          break;
149       }
150       case NSKeyDown:
151       {
152          Ecore_Event_Key *ev;
153          unsigned int     i;
154
155          ev = calloc(1, sizeof (Ecore_Event_Key));
156          if (!ev) return;
157          ev->timestamp = time;
158
159          for (i = 0; i < sizeof (keystable) / sizeof (struct _ecore_cocoa_keys_s); ++i)
160          {
161             if (keystable[i].code == tolower([[event charactersIgnoringModifiers] characterAtIndex:0]))
162             {
163                ev->keyname = keystable[i].name;
164                ev->string = keystable[i].compose;
165
166                ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL);
167                return;
168             }
169          }
170
171          break;
172       }
173       case NSKeyUp:
174       {
175          Ecore_Event_Key *ev;
176          unsigned int     i;
177
178          ev = calloc(1, sizeof (Ecore_Event_Key));
179          if (!ev) return;
180          ev->timestamp = time;
181
182          for (i = 0; i < sizeof (keystable) / sizeof (struct _ecore_cocoa_keys_s); ++i)
183          {
184             if (keystable[i].code == tolower([[event charactersIgnoringModifiers] characterAtIndex:0]))
185             {
186                ev->keyname = keystable[i].name;
187                ev->string = keystable[i].compose;
188
189                ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL);
190                return;
191             }
192          }
193
194          break;
195       }
196       case NSFlagsChanged:
197       {
198          int flags = [event modifierFlags];
199
200          Ecore_Event_Key *evDown = NULL;
201          Ecore_Event_Key *evUp = NULL;
202
203          evDown = calloc(1, sizeof (Ecore_Event_Key));
204          if (!evDown) return;
205
206          evUp = calloc(1, sizeof (Ecore_Event_Key));
207          if (!evUp)
208            {
209               free(evDown);
210               return;
211            }
212
213          // Turn special key flags on
214          if (flags & NSShiftKeyMask)
215             evDown->keyname = "Shift_L";
216          else if (flags & NSControlKeyMask)
217             evDown->keyname = "Control_L";
218          else if (flags & NSAlternateKeyMask)
219             evDown->keyname = "Alt_L";
220          else if (flags & NSCommandKeyMask)
221             evDown->keyname = "Super_L";
222          else if (flags & NSAlphaShiftKeyMask)
223             evDown->keyname = "Caps_Lock";
224
225          if (evDown->keyname)
226          {
227             evDown->timestamp = time;
228             evDown->string = "";
229             ecore_event_add(ECORE_EVENT_KEY_DOWN, evDown, NULL, NULL);
230             old_flags = flags;
231             break;
232          }
233
234          int changed_flags = flags ^ old_flags;
235
236          // Turn special key flags off
237          if (changed_flags & NSShiftKeyMask)
238             evUp->keyname = "Shift_L";
239          else if (changed_flags & NSControlKeyMask)
240             evUp->keyname = "Control_L";
241          else if (changed_flags & NSAlternateKeyMask)
242             evUp->keyname = "Alt_L";
243          else if (changed_flags & NSCommandKeyMask)
244             evUp->keyname = "Super_L";
245          else if (changed_flags & NSAlphaShiftKeyMask)
246             evUp->keyname = "Caps_Lock";
247
248          if (evUp->keyname)
249          {
250             evUp->timestamp = time;
251             evUp->string = "";
252             ecore_event_add(ECORE_EVENT_KEY_UP, evUp, NULL, NULL);
253             old_flags = flags;
254             break;
255          }
256
257          break;
258       }
259       case NSAppKitDefined:
260       {
261          if ([event subtype] == NSApplicationActivatedEventType)
262             ecore_event_add(ECORE_COCOA_EVENT_GOT_FOCUS, NULL, NULL, NULL);
263          else if ([event subtype] == NSApplicationDeactivatedEventType)
264             ecore_event_add(ECORE_COCOA_EVENT_LOST_FOCUS, NULL, NULL, NULL);
265          [NSApp sendEvent:event]; // pass along AppKit events, for window manager
266          break;
267       }
268       case NSScrollWheel:
269       {
270          break;
271       }
272       default:
273       {
274          [NSApp sendEvent:event];
275          break;
276       }
277    }
278
279    [event release];
280 }