766bf309f74493ad358e043c7b6752fb3ba5dbe5
[profile/ivi/ecore.git] / src / lib / ecore_sdl / ecore_sdl.c
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 Framebuffer Library Functions
54  *
55  * Functions used to set up and shut down the Ecore_Framebuffer 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("EcoreSdl", ECORE_SDL_DEFAULT_LOG_COLOR);
71    if(_ecore_sdl_log_dom < 0)
72      {
73        EINA_LOG_ERR("Impossible to create a log domain for the Ecore SDL module.");
74        return --_ecore_sdl_init_count;
75      }
76    if (!ecore_event_init())
77      return --_ecore_sdl_init_count;
78
79    ECORE_SDL_EVENT_GOT_FOCUS  = ecore_event_type_new();
80    ECORE_SDL_EVENT_LOST_FOCUS = ecore_event_type_new();
81    ECORE_SDL_EVENT_RESIZE     = ecore_event_type_new();
82    ECORE_SDL_EVENT_EXPOSE     = ecore_event_type_new();
83
84    SDL_EnableKeyRepeat(200, 100);
85
86    return _ecore_sdl_init_count;
87 }
88
89 /**
90  * Shuts down the Ecore_Sdl library.
91  * @return  @c The number of times the system has been initialised without
92  *             being shut down.
93  * @ingroup Ecore_SDL_Library_Group
94  */
95 EAPI int
96 ecore_sdl_shutdown(void)
97 {
98    if (--_ecore_sdl_init_count != 0);
99    return _ecore_sdl_init_count;
100
101    ecore_event_shutdown();
102    eina_log_domain_unregister(_ecore_sdl_log_dom);
103    _ecore_sdl_log_dom = -1;
104    return _ecore_sdl_init_count;
105 }
106
107 static unsigned int
108 _ecore_sdl_event_modifiers(int mod)
109 {
110    unsigned int        modifiers = 0;
111
112    if(mod & KMOD_LSHIFT) modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
113    if(mod & KMOD_RSHIFT) modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
114    if(mod & KMOD_LCTRL) modifiers |= ECORE_EVENT_MODIFIER_CTRL;
115    if(mod & KMOD_RCTRL) modifiers |= ECORE_EVENT_MODIFIER_CTRL;
116    if(mod & KMOD_LALT) modifiers |= ECORE_EVENT_MODIFIER_ALT;
117    if(mod & KMOD_RALT) modifiers |= ECORE_EVENT_MODIFIER_ALT;
118    if(mod & KMOD_NUM) modifiers |= ECORE_EVENT_LOCK_NUM;
119    if(mod & KMOD_CAPS) modifiers |= ECORE_EVENT_LOCK_CAPS;
120
121    return modifiers;
122 }
123
124 static Ecore_Event_Key*
125 _ecore_sdl_event_key(SDL_Event *event, double time)
126 {
127    Ecore_Event_Key *ev;
128    unsigned int i;
129
130    ev = malloc(sizeof(Ecore_Event_Key));
131    if (!ev) return NULL;
132
133    ev->timestamp = time;
134    ev->window = 0;
135    ev->modifiers = _ecore_sdl_event_modifiers(SDL_GetModState());
136    ev->key = NULL;
137    ev->compose = NULL;
138
139    for (i = 0; i < sizeof(keystable) / sizeof(struct _ecore_sdl_keys_s); ++i)
140      if (keystable[i].code == event->key.keysym.sym)
141        {
142           ev->keyname = keystable[i].name;
143           ev->string = keystable[i].compose;
144
145           return ev;
146        }
147
148    free(ev);
149    return NULL;
150 }
151
152 EAPI void
153 ecore_sdl_feed_events(void)
154 {
155    SDL_Event    event;
156    unsigned int time;
157
158    while(SDL_PollEvent(&event))
159      {
160         time = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff);
161         switch(event.type)
162           {
163           case SDL_MOUSEMOTION:
164           {
165              Ecore_Event_Mouse_Move *ev;
166
167              ev = malloc(sizeof(Ecore_Event_Mouse_Move));
168              if (!ev) return ;
169
170              ev->timestamp = time;
171              ev->window = 0;
172              ev->modifiers = 0; /* FIXME: keep modifier around. */
173              ev->x = event.motion.x;
174              ev->y = event.motion.y;
175              ev->root.x = ev->x;
176              ev->root.y = ev->y;
177
178              ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL);
179              break;
180           }
181           case SDL_MOUSEBUTTONDOWN:
182           {
183              if (event.button.button == SDL_BUTTON_WHEELUP ||
184                  event.button.button == SDL_BUTTON_WHEELDOWN)
185                {
186                   Ecore_Event_Mouse_Wheel *ev;
187
188                   ev = malloc(sizeof(Ecore_Event_Mouse_Wheel));
189                   if (!ev) return ;
190
191                   ev->timestamp = time;
192                   ev->window = 0;
193                   ev->modifiers = 0; /* FIXME: keep modifier around. */
194                   ev->direction = 0;
195                   ev->z = event.button.button == SDL_BUTTON_WHEELDOWN ? -1 : 1;
196
197                   ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
198                }
199              else
200                {
201                   Ecore_Event_Mouse_Button *ev;
202
203                   ev = malloc(sizeof(Ecore_Event_Mouse_Button));
204                   if (!ev) return ;
205
206                   ev->timestamp = time;
207                   ev->window = 0;
208                   ev->modifiers = 0; /* FIXME: keep modifier around. */
209                   ev->buttons = event.button.button;
210                   ev->double_click = 0;
211                   ev->triple_click = 0;
212
213                   ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
214                }
215              break;
216           }
217           case SDL_MOUSEBUTTONUP:
218           {
219              Ecore_Event_Mouse_Button *ev;
220
221              ev = malloc(sizeof(Ecore_Event_Mouse_Button));
222              if (!ev) return ;
223              ev->timestamp = time;
224              ev->window = 0;
225              ev->modifiers = 0; /* FIXME: keep modifier around. */
226              ev->buttons = event.button.button;
227              ev->double_click = 0;
228              ev->triple_click = 0;
229
230              ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
231              break;
232           }
233           case SDL_VIDEORESIZE:
234           {
235              Ecore_Sdl_Event_Video_Resize       *ev;
236
237              ev = malloc(sizeof (Ecore_Sdl_Event_Video_Resize));
238              ev->w = event.resize.w;
239              ev->h = event.resize.h;
240
241              ecore_event_add(ECORE_SDL_EVENT_RESIZE, ev, NULL, NULL);
242              break;
243           }
244           case SDL_VIDEOEXPOSE:
245              ecore_event_add(ECORE_SDL_EVENT_EXPOSE, NULL, NULL, NULL);
246              break;
247           case SDL_QUIT:
248              ecore_main_loop_quit();
249              break;
250
251           case SDL_KEYDOWN:
252           {
253              Ecore_SDL_Pressed *entry;
254              Ecore_Event_Key *ev;
255
256              entry = (Ecore_SDL_Pressed*) eina_rbtree_inline_lookup(repeat, &event.key.keysym.sym, sizeof (event.key.keysym.sym),
257                                                                     EINA_RBTREE_CMP_KEY_CB(_ecore_sdl_pressed_node), NULL);
258              if (entry)
259                {
260                   ev = _ecore_sdl_event_key(&event, time);
261                   if (ev) ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL);
262                }
263
264              ev = _ecore_sdl_event_key(&event, time);
265              if (ev) ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL);
266
267              if (!entry)
268                {
269                   entry = malloc(sizeof (Ecore_SDL_Pressed));
270                   if (!entry) break;
271
272                   entry->key = event.key.keysym.sym;
273
274                   repeat = eina_rbtree_inline_insert(repeat, EINA_RBTREE_GET(entry),
275                                                      EINA_RBTREE_CMP_NODE_CB(_ecore_sdl_pressed_key), NULL);
276                }
277              break;
278           }
279           case SDL_KEYUP:
280           {
281              Ecore_Event_Key *ev;
282              Ecore_SDL_Pressed *entry;
283
284              entry = (Ecore_SDL_Pressed*) eina_rbtree_inline_lookup(repeat, &event.key.keysym.sym, sizeof (event.key.keysym.sym),
285                                                                     EINA_RBTREE_CMP_KEY_CB(_ecore_sdl_pressed_node), NULL);
286              if (entry)
287                {
288                   repeat = eina_rbtree_inline_remove(repeat, EINA_RBTREE_GET(entry),
289                                                      EINA_RBTREE_CMP_NODE_CB(_ecore_sdl_pressed_key), NULL);
290                   free(entry);
291                }
292
293              ev = _ecore_sdl_event_key(&event, time);
294              if (ev) ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL);
295              break;
296           }
297           case SDL_ACTIVEEVENT:
298              /* FIXME: Focus gain. */
299              break;
300           case SDL_SYSWMEVENT:
301           case SDL_USEREVENT:
302           case SDL_JOYAXISMOTION:
303           case SDL_JOYBALLMOTION:
304           case SDL_JOYHATMOTION:
305           case SDL_JOYBUTTONDOWN:
306           case SDL_JOYBUTTONUP:
307           default:
308              break;
309           }
310      }
311 }