diff options
Diffstat (limited to 'libraries/ecore/src/lib/ecore_sdl/ecore_sdl.c')
-rw-r--r-- | libraries/ecore/src/lib/ecore_sdl/ecore_sdl.c | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_sdl/ecore_sdl.c b/libraries/ecore/src/lib/ecore_sdl/ecore_sdl.c new file mode 100644 index 0000000..3f28216 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_sdl/ecore_sdl.c | |||
@@ -0,0 +1,335 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <SDL/SDL.h> | ||
6 | |||
7 | #include "Eina.h" | ||
8 | #include "Ecore_Sdl.h" | ||
9 | #include "Ecore_Input.h" | ||
10 | #include "Ecore.h" | ||
11 | #include "ecore_sdl_private.h" | ||
12 | #include "ecore_private.h" | ||
13 | #include "Ecore_Sdl_Keys.h" | ||
14 | |||
15 | #include <eina_rbtree.h> | ||
16 | |||
17 | int _ecore_sdl_log_dom = -1; | ||
18 | |||
19 | typedef struct _Ecore_SDL_Pressed Ecore_SDL_Pressed; | ||
20 | struct _Ecore_SDL_Pressed | ||
21 | { | ||
22 | EINA_RBTREE; | ||
23 | |||
24 | SDLKey key; | ||
25 | }; | ||
26 | |||
27 | EAPI int ECORE_SDL_EVENT_GOT_FOCUS = 0; | ||
28 | EAPI int ECORE_SDL_EVENT_LOST_FOCUS = 0; | ||
29 | EAPI int ECORE_SDL_EVENT_RESIZE = 0; | ||
30 | EAPI int ECORE_SDL_EVENT_EXPOSE = 0; | ||
31 | |||
32 | static int _ecore_sdl_init_count = 0; | ||
33 | static Eina_Rbtree *repeat = NULL; | ||
34 | |||
35 | static Eina_Rbtree_Direction | ||
36 | _ecore_sdl_pressed_key(const Ecore_SDL_Pressed *left, | ||
37 | const Ecore_SDL_Pressed *right, | ||
38 | __UNUSED__ void *data) | ||
39 | { | ||
40 | return left->key < right->key ? EINA_RBTREE_LEFT : EINA_RBTREE_RIGHT; | ||
41 | } | ||
42 | |||
43 | static int | ||
44 | _ecore_sdl_pressed_node(const Ecore_SDL_Pressed *node, | ||
45 | const SDLKey *key, | ||
46 | __UNUSED__ int length, | ||
47 | __UNUSED__ void *data) | ||
48 | { | ||
49 | return node->key - *key; | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * @defgroup Ecore_Sdl_Library_Group SDL Library Functions | ||
54 | * | ||
55 | * Functions used to set up and shut down the Ecore_Sdl functions. | ||
56 | */ | ||
57 | |||
58 | /** | ||
59 | * Sets up the Ecore_Sdl library. | ||
60 | * @param name device target name | ||
61 | * @return @c 0 on failure. Otherwise, the number of times the library has | ||
62 | * been initialised without being shut down. | ||
63 | * @ingroup Ecore_SDL_Library_Group | ||
64 | */ | ||
65 | EAPI int | ||
66 | ecore_sdl_init(const char *name __UNUSED__) | ||
67 | { | ||
68 | if(++_ecore_sdl_init_count != 1) | ||
69 | return _ecore_sdl_init_count; | ||
70 | _ecore_sdl_log_dom = eina_log_domain_register | ||
71 | ("ecore_sdl", ECORE_SDL_DEFAULT_LOG_COLOR); | ||
72 | if(_ecore_sdl_log_dom < 0) | ||
73 | { | ||
74 | EINA_LOG_ERR("Impossible to create a log domain for the Ecore SDL module."); | ||
75 | return --_ecore_sdl_init_count; | ||
76 | } | ||
77 | if (!ecore_event_init()) | ||
78 | return --_ecore_sdl_init_count; | ||
79 | |||
80 | ECORE_SDL_EVENT_GOT_FOCUS = ecore_event_type_new(); | ||
81 | ECORE_SDL_EVENT_LOST_FOCUS = ecore_event_type_new(); | ||
82 | ECORE_SDL_EVENT_RESIZE = ecore_event_type_new(); | ||
83 | ECORE_SDL_EVENT_EXPOSE = ecore_event_type_new(); | ||
84 | |||
85 | SDL_EnableKeyRepeat(200, 100); | ||
86 | |||
87 | return _ecore_sdl_init_count; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * Shuts down the Ecore_Sdl library. | ||
92 | * @return @c The number of times the system has been initialised without | ||
93 | * being shut down. | ||
94 | * @ingroup Ecore_SDL_Library_Group | ||
95 | */ | ||
96 | EAPI int | ||
97 | ecore_sdl_shutdown(void) | ||
98 | { | ||
99 | if (--_ecore_sdl_init_count != 0) | ||
100 | return _ecore_sdl_init_count; | ||
101 | |||
102 | ecore_event_shutdown(); | ||
103 | eina_log_domain_unregister(_ecore_sdl_log_dom); | ||
104 | _ecore_sdl_log_dom = -1; | ||
105 | return _ecore_sdl_init_count; | ||
106 | } | ||
107 | |||
108 | static unsigned int | ||
109 | _ecore_sdl_event_modifiers(int mod) | ||
110 | { | ||
111 | unsigned int modifiers = 0; | ||
112 | |||
113 | if(mod & KMOD_LSHIFT) modifiers |= ECORE_EVENT_MODIFIER_SHIFT; | ||
114 | if(mod & KMOD_RSHIFT) modifiers |= ECORE_EVENT_MODIFIER_SHIFT; | ||
115 | if(mod & KMOD_LCTRL) modifiers |= ECORE_EVENT_MODIFIER_CTRL; | ||
116 | if(mod & KMOD_RCTRL) modifiers |= ECORE_EVENT_MODIFIER_CTRL; | ||
117 | if(mod & KMOD_LALT) modifiers |= ECORE_EVENT_MODIFIER_ALT; | ||
118 | if(mod & KMOD_RALT) modifiers |= ECORE_EVENT_MODIFIER_ALT; | ||
119 | if(mod & KMOD_NUM) modifiers |= ECORE_EVENT_LOCK_NUM; | ||
120 | if(mod & KMOD_CAPS) modifiers |= ECORE_EVENT_LOCK_CAPS; | ||
121 | |||
122 | return modifiers; | ||
123 | } | ||
124 | |||
125 | static Ecore_Event_Key* | ||
126 | _ecore_sdl_event_key(SDL_Event *event, double time) | ||
127 | { | ||
128 | Ecore_Event_Key *ev; | ||
129 | unsigned int i; | ||
130 | |||
131 | ev = malloc(sizeof(Ecore_Event_Key)); | ||
132 | if (!ev) return NULL; | ||
133 | |||
134 | ev->timestamp = time; | ||
135 | ev->window = 0; | ||
136 | ev->event_window = 0; | ||
137 | ev->modifiers = _ecore_sdl_event_modifiers(SDL_GetModState()); | ||
138 | ev->key = NULL; | ||
139 | ev->compose = NULL; | ||
140 | |||
141 | for (i = 0; i < sizeof(keystable) / sizeof(struct _ecore_sdl_keys_s); ++i) | ||
142 | if (keystable[i].code == event->key.keysym.sym) | ||
143 | { | ||
144 | ev->keyname = keystable[i].name; | ||
145 | ev->string = keystable[i].compose; | ||
146 | |||
147 | return ev; | ||
148 | } | ||
149 | |||
150 | free(ev); | ||
151 | return NULL; | ||
152 | } | ||
153 | |||
154 | EAPI void | ||
155 | ecore_sdl_feed_events(void) | ||
156 | { | ||
157 | SDL_Event event; | ||
158 | unsigned int time; | ||
159 | |||
160 | while(SDL_PollEvent(&event)) | ||
161 | { | ||
162 | time = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff); | ||
163 | switch(event.type) | ||
164 | { | ||
165 | case SDL_MOUSEMOTION: | ||
166 | { | ||
167 | Ecore_Event_Mouse_Move *ev; | ||
168 | |||
169 | ev = malloc(sizeof(Ecore_Event_Mouse_Move)); | ||
170 | if (!ev) return ; | ||
171 | |||
172 | ev->timestamp = time; | ||
173 | ev->window = 0; | ||
174 | ev->event_window = 0; | ||
175 | ev->modifiers = 0; /* FIXME: keep modifier around. */ | ||
176 | ev->x = event.motion.x; | ||
177 | ev->y = event.motion.y; | ||
178 | ev->root.x = ev->x; | ||
179 | ev->root.y = ev->y; | ||
180 | |||
181 | /* Must set multi touch device to 0 or it will get ignored */ | ||
182 | ev->multi.device = 0; | ||
183 | ev->multi.radius = ev->multi.radius_x = ev->multi.radius_y = 0; | ||
184 | ev->multi.pressure = ev->multi.angle = 0; | ||
185 | ev->multi.x = ev->multi.y = ev->multi.root.x = ev->multi.root.y = 0; | ||
186 | |||
187 | ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); | ||
188 | break; | ||
189 | } | ||
190 | case SDL_MOUSEBUTTONDOWN: | ||
191 | { | ||
192 | if (event.button.button == SDL_BUTTON_WHEELUP || | ||
193 | event.button.button == SDL_BUTTON_WHEELDOWN) | ||
194 | { | ||
195 | Ecore_Event_Mouse_Wheel *ev; | ||
196 | |||
197 | ev = malloc(sizeof(Ecore_Event_Mouse_Wheel)); | ||
198 | if (!ev) return ; | ||
199 | |||
200 | ev->timestamp = time; | ||
201 | ev->window = 0; | ||
202 | ev->event_window = 0; | ||
203 | ev->modifiers = 0; /* FIXME: keep modifier around. */ | ||
204 | ev->direction = 0; | ||
205 | ev->z = event.button.button == SDL_BUTTON_WHEELDOWN ? -1 : 1; | ||
206 | |||
207 | ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL); | ||
208 | } | ||
209 | else | ||
210 | { | ||
211 | Ecore_Event_Mouse_Button *ev; | ||
212 | |||
213 | ev = malloc(sizeof(Ecore_Event_Mouse_Button)); | ||
214 | if (!ev) return ; | ||
215 | |||
216 | ev->timestamp = time; | ||
217 | ev->window = 0; | ||
218 | ev->event_window = 0; | ||
219 | ev->modifiers = 0; /* FIXME: keep modifier around. */ | ||
220 | ev->buttons = event.button.button; | ||
221 | ev->double_click = 0; | ||
222 | ev->triple_click = 0; | ||
223 | |||
224 | /* Must set multi touch device to 0 or it will get ignored */ | ||
225 | ev->multi.device = 0; | ||
226 | ev->multi.radius = ev->multi.radius_x = ev->multi.radius_y = 0; | ||
227 | ev->multi.pressure = ev->multi.angle = 0; | ||
228 | ev->multi.x = ev->multi.y = ev->multi.root.x = ev->multi.root.y = 0; | ||
229 | |||
230 | ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); | ||
231 | } | ||
232 | break; | ||
233 | } | ||
234 | case SDL_MOUSEBUTTONUP: | ||
235 | { | ||
236 | Ecore_Event_Mouse_Button *ev; | ||
237 | |||
238 | ev = malloc(sizeof(Ecore_Event_Mouse_Button)); | ||
239 | if (!ev) return ; | ||
240 | ev->timestamp = time; | ||
241 | ev->window = 0; | ||
242 | ev->event_window = 0; | ||
243 | ev->modifiers = 0; /* FIXME: keep modifier around. */ | ||
244 | ev->buttons = event.button.button; | ||
245 | ev->double_click = 0; | ||
246 | ev->triple_click = 0; | ||
247 | |||
248 | /* Must set multi touch device to 0 or it will get ignored */ | ||
249 | ev->multi.device = 0; | ||
250 | ev->multi.radius = ev->multi.radius_x = ev->multi.radius_y = 0; | ||
251 | ev->multi.pressure = ev->multi.angle = 0; | ||
252 | ev->multi.x = ev->multi.y = ev->multi.root.x = ev->multi.root.y = 0; | ||
253 | |||
254 | ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); | ||
255 | break; | ||
256 | } | ||
257 | case SDL_VIDEORESIZE: | ||
258 | { | ||
259 | Ecore_Sdl_Event_Video_Resize *ev; | ||
260 | |||
261 | ev = malloc(sizeof (Ecore_Sdl_Event_Video_Resize)); | ||
262 | ev->w = event.resize.w; | ||
263 | ev->h = event.resize.h; | ||
264 | |||
265 | ecore_event_add(ECORE_SDL_EVENT_RESIZE, ev, NULL, NULL); | ||
266 | break; | ||
267 | } | ||
268 | case SDL_VIDEOEXPOSE: | ||
269 | ecore_event_add(ECORE_SDL_EVENT_EXPOSE, NULL, NULL, NULL); | ||
270 | break; | ||
271 | case SDL_QUIT: | ||
272 | ecore_main_loop_quit(); | ||
273 | break; | ||
274 | |||
275 | case SDL_KEYDOWN: | ||
276 | { | ||
277 | Ecore_SDL_Pressed *entry; | ||
278 | Ecore_Event_Key *ev; | ||
279 | |||
280 | entry = (Ecore_SDL_Pressed*) eina_rbtree_inline_lookup(repeat, &event.key.keysym.sym, sizeof (event.key.keysym.sym), | ||
281 | EINA_RBTREE_CMP_KEY_CB(_ecore_sdl_pressed_node), NULL); | ||
282 | if (entry) | ||
283 | { | ||
284 | ev = _ecore_sdl_event_key(&event, time); | ||
285 | if (ev) ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL); | ||
286 | } | ||
287 | |||
288 | ev = _ecore_sdl_event_key(&event, time); | ||
289 | if (ev) ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL); | ||
290 | |||
291 | if (!entry) | ||
292 | { | ||
293 | entry = malloc(sizeof (Ecore_SDL_Pressed)); | ||
294 | if (!entry) break; | ||
295 | |||
296 | entry->key = event.key.keysym.sym; | ||
297 | |||
298 | repeat = eina_rbtree_inline_insert(repeat, EINA_RBTREE_GET(entry), | ||
299 | EINA_RBTREE_CMP_NODE_CB(_ecore_sdl_pressed_key), NULL); | ||
300 | } | ||
301 | break; | ||
302 | } | ||
303 | case SDL_KEYUP: | ||
304 | { | ||
305 | Ecore_Event_Key *ev; | ||
306 | Ecore_SDL_Pressed *entry; | ||
307 | |||
308 | entry = (Ecore_SDL_Pressed*) eina_rbtree_inline_lookup(repeat, &event.key.keysym.sym, sizeof (event.key.keysym.sym), | ||
309 | EINA_RBTREE_CMP_KEY_CB(_ecore_sdl_pressed_node), NULL); | ||
310 | if (entry) | ||
311 | { | ||
312 | repeat = eina_rbtree_inline_remove(repeat, EINA_RBTREE_GET(entry), | ||
313 | EINA_RBTREE_CMP_NODE_CB(_ecore_sdl_pressed_key), NULL); | ||
314 | free(entry); | ||
315 | } | ||
316 | |||
317 | ev = _ecore_sdl_event_key(&event, time); | ||
318 | if (ev) ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL); | ||
319 | break; | ||
320 | } | ||
321 | case SDL_ACTIVEEVENT: | ||
322 | /* FIXME: Focus gain. */ | ||
323 | break; | ||
324 | case SDL_SYSWMEVENT: | ||
325 | case SDL_USEREVENT: | ||
326 | case SDL_JOYAXISMOTION: | ||
327 | case SDL_JOYBALLMOTION: | ||
328 | case SDL_JOYHATMOTION: | ||
329 | case SDL_JOYBUTTONDOWN: | ||
330 | case SDL_JOYBUTTONUP: | ||
331 | default: | ||
332 | break; | ||
333 | } | ||
334 | } | ||
335 | } | ||