946f18ed5d1e65d34f5bee7fd9922416b69129e1
[framework/uifw/ecore.git] / src / lib / ecore_evas / ecore_evas_sdl.c
1 #include "config.h"
2 #include "Ecore.h"
3 #include "ecore_private.h"
4 #include "ecore_evas_private.h"
5 #include "Ecore_Evas.h"
6 #ifdef BUILD_ECORE_EVAS_SDL
7 #include "Ecore_Sdl.h"
8 #include "Evas_Engine_SDL.h"
9 #endif
10
11 #ifdef BUILD_ECORE_EVAS_SDL
12
13 /* static char *ecore_evas_default_display = "0"; */
14 /* static Ecore_List *ecore_evas_input_devices = NULL; */
15
16 static int                      _ecore_evas_init_count = 0;
17 #ifndef _WIN32
18 static int                      _ecore_evas_fps_debug = 0;
19 #endif /* _WIN32 */
20 static Ecore_Evas               *ecore_evases = NULL;
21 static Ecore_Event_Handler      *ecore_evas_event_handlers[10] = {
22    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
23 };
24 static Ecore_Idle_Enterer       *ecore_evas_idle_enterer = NULL;
25 static Ecore_Idler              *ecore_evas_event = NULL;
26
27 static const char               *ecore_evas_sdl_default = "EFL SDL";
28
29 static void
30 _ecore_evas_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp)
31 {
32    ee->mouse.x = x;
33    ee->mouse.y = y;
34    if (ee->prop.cursor.object)
35      {
36         evas_object_show(ee->prop.cursor.object);
37         evas_object_move(ee->prop.cursor.object,
38                          x - ee->prop.cursor.hot.x,
39                          y - ee->prop.cursor.hot.y);
40      }
41    evas_event_feed_mouse_move(ee->evas, x, y, timestamp, NULL);
42 }
43
44 static Ecore_Evas *
45 _ecore_evas_sdl_match(void)
46 {
47    return ecore_evases;
48 }
49
50 static int
51 _ecore_evas_sdl_event_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
52 {
53    Ecore_Sdl_Event_Key_Down     *e;
54    Ecore_Evas                   *ee;
55
56    e = event;
57    ee = _ecore_evas_sdl_match();
58
59    if (!ee) return 1;
60    /* pass on event */
61    evas_event_feed_key_down(ee->evas, e->keyname, NULL, e->keycompose, NULL, e->time, NULL);
62
63    return 0; /* dont pass it on */
64 }
65
66 static int
67 _ecore_evas_sdl_event_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
68 {
69    Ecore_Sdl_Event_Key_Up       *e;
70    Ecore_Evas                   *ee;
71
72    e = event;
73    ee = _ecore_evas_sdl_match();
74
75    if (!ee) return 1;
76    /* pass on event */
77    evas_event_feed_key_up(ee->evas, e->keyname, NULL, e->keycompose, NULL, e->time, NULL);
78
79    return 0;
80 }
81
82 static int
83 _ecore_evas_sdl_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
84 {
85    Ecore_Sdl_Event_Mouse_Move *e;
86    Ecore_Evas *ee;
87
88    e = event;
89    ee = _ecore_evas_sdl_match();
90
91    if (!ee) return 1; /* pass on event */
92    _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
93
94    return 0;
95 }
96
97 static int
98 _ecore_evas_sdl_event_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
99 {
100    Ecore_Sdl_Event_Mouse_Button_Down    *e;
101    Ecore_Evas                           *ee;
102    Evas_Button_Flags                    flags;
103
104    e = event;
105    ee = _ecore_evas_sdl_match();
106    flags = EVAS_BUTTON_NONE;
107
108    if (!ee) return 1;
109    /* pass on event */
110    _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
111    if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
112    if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
113    evas_event_feed_mouse_down(ee->evas, e->button, flags, e->time, NULL);
114
115    return 0;
116 }
117
118 static int
119 _ecore_evas_sdl_event_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
120 {
121    Ecore_Sdl_Event_Mouse_Button_Up      *e;
122    Ecore_Evas                           *ee;
123    Evas_Button_Flags                    flags;
124
125    e = event;
126    ee = _ecore_evas_sdl_match();
127    flags = EVAS_BUTTON_NONE;
128
129    if (!ee) return 1;
130    /* pass on event */
131    _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
132    if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
133    if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
134    evas_event_feed_mouse_up(ee->evas, e->button, flags, e->time, NULL);
135
136    return 0;
137 }
138
139 static int
140 _ecore_evas_sdl_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
141 {
142    Ecore_Sdl_Event_Mouse_Wheel  *e;
143    Ecore_Evas                   *ee;
144
145    e = event;
146    ee = _ecore_evas_sdl_match();
147
148    if (!ee) return 1; /* pass on event */
149    _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
150    evas_event_feed_mouse_wheel(ee->evas, e->direction, e->wheel, e->time, NULL);
151
152    return 0;
153 }
154
155 static int
156 _ecore_evas_sdl_event_got_focus(void *data __UNUSED__, int type __UNUSED__, void *event)
157 {
158    Ecore_Evas                   *ee;
159
160    ee = _ecore_evas_sdl_match();
161
162    if (!ee) return 1;
163    /* pass on event */
164    ee->prop.focused = 1;
165
166    return 0;
167 }
168
169 static int
170 _ecore_evas_sdl_event_lost_focus(void *data __UNUSED__, int type __UNUSED__, void *event)
171 {
172    Ecore_Evas                   *ee;
173
174    ee = _ecore_evas_sdl_match();
175
176    if (!ee) return 1;
177    /* pass on event */
178    ee->prop.focused = 0;
179
180    return 0;
181 }
182
183 static int
184 _ecore_evas_sdl_event_video_resize(void *data __UNUSED__, int type __UNUSED__, void *event)
185 {
186    Ecore_Sdl_Event_Video_Resize *e;
187    Ecore_Evas                   *ee;
188
189    e = event;
190    ee = _ecore_evas_sdl_match();
191
192    if (!ee) return 1; /* pass on event */
193    evas_output_size_set(ee->evas, e->w, e->h);
194
195    return 0;
196 }
197
198 static int
199 _ecore_evas_sdl_event_video_expose(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
200 {
201    Ecore_Evas                   *ee;
202    int                          w;
203    int                          h;
204
205    ee = _ecore_evas_sdl_match();
206
207    if (!ee) return 1;
208    evas_output_size_get(ee->evas, &w, &h);
209    evas_damage_rectangle_add(ee->evas, 0, 0, w, h);
210
211    return 0;
212 }
213
214 static int
215 _ecore_evas_idle_enter(void *data __UNUSED__)
216 {
217    Ecore_List2  *l;
218    double       t1 = 0.;
219    double       t2 = 0.;
220
221 #ifndef _WIN32
222    if (_ecore_evas_fps_debug)
223      {
224         t1 = ecore_time_get();
225      }
226 #endif /* _WIN32 */
227    for (l = (Ecore_List2 *)ecore_evases; l; l = l->next)
228      {
229         Ecore_Evas *ee;
230
231         ee = (Ecore_Evas *)l;
232         if (ee->visible)
233           {
234              Evas_List *updates;
235              
236              if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
237
238              updates = evas_render_updates(ee->evas);
239              if (updates)
240                {
241                   evas_render_updates_free(updates);
242                   _ecore_evas_idle_timeout_update(ee);
243                }
244              if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
245           }
246         else
247           evas_norender(ee->evas);
248      }
249 #ifndef _WIN32
250    if (_ecore_evas_fps_debug)
251      {
252         t2 = ecore_time_get();
253         _ecore_evas_fps_debug_rendertime_add(t2 - t1);
254      }
255 #endif /* _WIN32 */
256    return 1;
257 }
258
259 static int
260 _ecore_evas_sdl_event(void *data)
261 {
262    ecore_sdl_feed_events();
263
264    return 1;
265 }
266
267 static int
268 _ecore_evas_sdl_init(int w, int h)
269 {
270    _ecore_evas_init_count++;
271    if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
272
273 #ifndef _WIN32
274    if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1;
275 #endif /* _WIN32 */
276    ecore_evas_idle_enterer = ecore_idle_enterer_add(_ecore_evas_idle_enter, NULL);
277    ecore_evas_event = ecore_timer_add(0.008, _ecore_evas_sdl_event, NULL);
278 #ifndef _WIN32
279    if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init();
280 #endif /* _WIN32 */
281
282    ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_SDL_EVENT_KEY_DOWN, _ecore_evas_sdl_event_key_down, NULL);
283    ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_SDL_EVENT_KEY_UP, _ecore_evas_sdl_event_key_up, NULL);
284    ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_SDL_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_sdl_event_button_down, NULL);
285    ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_SDL_EVENT_MOUSE_BUTTON_UP, _ecore_evas_sdl_event_button_up, NULL);
286    ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_SDL_EVENT_MOUSE_MOVE, _ecore_evas_sdl_event_mouse_move, NULL);
287    ecore_evas_event_handlers[5] = ecore_event_handler_add(ECORE_SDL_EVENT_MOUSE_WHEEL, _ecore_evas_sdl_event_mouse_wheel, NULL);
288    ecore_evas_event_handlers[6] = ecore_event_handler_add(ECORE_SDL_EVENT_GOT_FOCUS, _ecore_evas_sdl_event_got_focus, NULL);
289    ecore_evas_event_handlers[7] = ecore_event_handler_add(ECORE_SDL_EVENT_LOST_FOCUS, _ecore_evas_sdl_event_lost_focus, NULL);
290    ecore_evas_event_handlers[8] = ecore_event_handler_add(ECORE_SDL_EVENT_RESIZE, _ecore_evas_sdl_event_video_resize, NULL);
291    ecore_evas_event_handlers[9] = ecore_event_handler_add(ECORE_SDL_EVENT_EXPOSE, _ecore_evas_sdl_event_video_expose, NULL);
292
293    return _ecore_evas_init_count;
294 }
295
296 static int
297 _ecore_evas_sdl_shutdown(void)
298 {
299    _ecore_evas_init_count--;
300    if (_ecore_evas_init_count == 0)
301      {
302         int i;
303
304         while (ecore_evases) _ecore_evas_free(ecore_evases);
305         for (i = 0; i < sizeof (ecore_evas_event_handlers) / sizeof (Ecore_Event_Handler*); i++)
306           ecore_event_handler_del(ecore_evas_event_handlers[i]);
307         ecore_idle_enterer_del(ecore_evas_idle_enterer);
308         ecore_evas_idle_enterer = NULL;
309         ecore_timer_del(ecore_evas_event);
310         ecore_evas_event = NULL;
311 #ifndef _WIN32
312         if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown();
313 #endif /* _WIN32 */
314      }
315    if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
316    return _ecore_evas_init_count;
317 }
318
319 static void
320 _ecore_evas_sdl_free(Ecore_Evas *ee)
321 {
322    ecore_evases = _ecore_list2_remove(ecore_evases, ee);
323    _ecore_evas_sdl_shutdown();
324    ecore_sdl_shutdown();
325 }
326
327 static void
328 _ecore_evas_resize(Ecore_Evas *ee, int w, int h)
329 {
330    if ((w == ee->w) && (h == ee->h)) return;
331    ee->w = w;
332    ee->h = h;
333
334    evas_output_size_set(ee->evas, ee->w, ee->h);
335    evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
336    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
337
338    if (ee->func.fn_resize) ee->func.fn_resize(ee);
339 }
340
341 static void
342 _ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
343 {
344    if ((w == ee->w) && (h == ee->h)) return;
345    ee->w = w;
346    ee->h = h;
347
348    evas_output_size_set(ee->evas, ee->w, ee->h);
349    evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
350    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
351
352    if (ee->func.fn_resize) ee->func.fn_resize(ee);
353 }
354
355 static void
356 _ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
357 {
358    int x, y;
359
360    if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
361
362    if (obj == NULL)
363      {
364         ee->prop.cursor.object = NULL;
365         ee->prop.cursor.layer = 0;
366         ee->prop.cursor.hot.x = 0;
367         ee->prop.cursor.hot.y = 0;
368         return;
369      }
370
371    ee->prop.cursor.object = obj;
372    ee->prop.cursor.layer = layer;
373    ee->prop.cursor.hot.x = hot_x;
374    ee->prop.cursor.hot.y = hot_y;
375    evas_pointer_output_xy_get(ee->evas, &x, &y);
376    evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
377    evas_object_move(ee->prop.cursor.object,
378                     x - ee->prop.cursor.hot.x,
379                     y - ee->prop.cursor.hot.y);
380    evas_object_pass_events_set(ee->prop.cursor.object, 1);
381    if (evas_pointer_inside_get(ee->evas))
382      evas_object_show(ee->prop.cursor.object);
383 }
384
385 static const Ecore_Evas_Engine_Func _ecore_sdl_engine_func =
386 {
387    _ecore_evas_sdl_free,
388    NULL,
389    NULL,
390    NULL,
391    NULL,
392    NULL,
393    NULL,
394    NULL,
395    NULL,
396    NULL,
397    NULL,
398    NULL,
399    NULL,
400    NULL,
401    NULL,
402    NULL,
403    NULL,
404    _ecore_evas_resize,
405    _ecore_evas_move_resize,
406    NULL,
407    NULL,
408    NULL,
409    NULL,
410    NULL,
411    NULL,
412    NULL,
413    NULL,
414    NULL,
415    NULL,
416    NULL,
417    NULL,
418    NULL,
419    _ecore_evas_object_cursor_set,
420    NULL,
421    NULL,
422    NULL,
423    NULL,
424    NULL,
425    NULL,
426    NULL,
427    NULL,
428    NULL,
429    NULL,
430    NULL
431 };
432 #endif
433
434 EAPI Ecore_Evas*
435 ecore_evas_sdl_new(const char* name, int w, int h, int fullscreen, int hwsurface, int noframe, int alpha)
436 {
437 #ifdef BUILD_ECORE_EVAS_SDL
438    Evas_Engine_Info_SDL *einfo;
439    Ecore_Evas           *ee;
440    int                  rmethod;
441
442    if (!name)
443      name = ecore_evas_sdl_default;
444
445    rmethod = evas_render_method_lookup("software_sdl");
446    if (!rmethod) return NULL;
447
448    if (!ecore_sdl_init(name)) return NULL;
449
450    ee = calloc(1, sizeof(Ecore_Evas));
451    if (!ee) return NULL;
452
453    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
454
455    _ecore_evas_sdl_init(w, h);
456
457    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_sdl_engine_func;
458
459    ee->driver = "sdl";
460    if (name) ee->name = strdup(name);
461
462    if (w < 1) w = 1;
463    if (h < 1) h = 1;
464    ee->visible = 1;
465    ee->w = w;
466    ee->h = h;
467
468    ee->prop.max.w = 0;
469    ee->prop.max.h = 0;
470    ee->prop.layer = 0;
471    ee->prop.focused = 1;
472    ee->prop.borderless = 1;
473    ee->prop.override = 1;
474    ee->prop.maximized = 1;
475    ee->prop.fullscreen = fullscreen;
476    ee->prop.withdrawn = 0;
477    ee->prop.sticky = 0;
478
479    /* init evas here */
480    ee->evas = evas_new();
481    evas_data_attach_set(ee->evas, ee);
482    evas_output_method_set(ee->evas, rmethod);
483
484    evas_output_size_set(ee->evas, w, h);
485    evas_output_viewport_set(ee->evas, 0, 0, w, h);
486
487    einfo = (Evas_Engine_Info_SDL*) evas_engine_info_get(ee->evas);
488    if (einfo)
489      {
490         einfo->info.fullscreen = fullscreen;
491         einfo->info.hwsurface = hwsurface;
492         einfo->info.noframe = noframe;
493         einfo->info.alpha = alpha;
494         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
495      }
496    evas_key_modifier_add(ee->evas, "Shift");
497    evas_key_modifier_add(ee->evas, "Control");
498    evas_key_modifier_add(ee->evas, "Alt");
499    evas_key_modifier_add(ee->evas, "Meta");
500    evas_key_modifier_add(ee->evas, "Hyper");
501    evas_key_modifier_add(ee->evas, "Super");
502    evas_key_lock_add(ee->evas, "Caps_Lock");
503    evas_key_lock_add(ee->evas, "Num_Lock");
504    evas_key_lock_add(ee->evas, "Scroll_Lock");
505
506    evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
507
508    ecore_evases = _ecore_list2_prepend(ecore_evases, ee);
509    return ee;
510 #else
511    fprintf(stderr, "OUTCH !\n");
512    return NULL;
513 #endif
514 }