aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_evas/ecore_evas_sdl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_evas/ecore_evas_sdl.c')
-rw-r--r--libraries/ecore/src/lib/ecore_evas/ecore_evas_sdl.c542
1 files changed, 542 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_evas/ecore_evas_sdl.c b/libraries/ecore/src/lib/ecore_evas/ecore_evas_sdl.c
new file mode 100644
index 0000000..b333d96
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_evas/ecore_evas_sdl.c
@@ -0,0 +1,542 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Ecore.h>
6#include <Ecore_Input.h>
7#include <Ecore_Input_Evas.h>
8#if defined(BUILD_ECORE_EVAS_SOFTWARE_SDL) || defined(BUILD_ECORE_EVAS_OPENGL_SDL)
9# include <Ecore_Sdl.h>
10# ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
11# include <Evas_Engine_SDL.h>
12# endif
13# ifdef BUILD_ECORE_EVAS_OPENGL_SDL
14# include <Evas_Engine_GL_SDL.h>
15# endif
16#endif
17
18#include "ecore_evas_private.h"
19#include "Ecore_Evas.h"
20
21// fixme: 1 sdl window only at a time? seems wrong
22
23#if defined(BUILD_ECORE_EVAS_SOFTWARE_SDL) || defined(BUILD_ECORE_EVAS_OPENGL_SDL)
24
25/* static char *ecore_evas_default_display = "0"; */
26/* static Ecore_List *ecore_evas_input_devices = NULL; */
27
28static int _ecore_evas_init_count = 0;
29
30static Ecore_Evas *sdl_ee = NULL;
31static Ecore_Event_Handler *ecore_evas_event_handlers[4] = {
32 NULL, NULL, NULL, NULL
33};
34
35static const char *ecore_evas_sdl_default = "EFL SDL";
36static int _ecore_evas_fps_debug = 0;
37static Ecore_Poller *ecore_evas_event;
38
39static Ecore_Evas *
40_ecore_evas_sdl_match(void)
41{
42 return sdl_ee;
43}
44
45static Eina_Bool
46_ecore_evas_sdl_event_got_focus(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
47{
48 Ecore_Evas *ee;
49
50 ee = _ecore_evas_sdl_match();
51
52 if (!ee) return ECORE_CALLBACK_PASS_ON;
53 /* pass on event */
54 ee->prop.focused = 1;
55 evas_focus_in(ee->evas);
56 if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
57 return ECORE_CALLBACK_PASS_ON;
58}
59
60static Eina_Bool
61_ecore_evas_sdl_event_lost_focus(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
62{
63 Ecore_Evas *ee;
64
65 ee = _ecore_evas_sdl_match();
66
67 if (!ee) return ECORE_CALLBACK_PASS_ON;
68 /* pass on event */
69 ee->prop.focused = 0;
70 evas_focus_out(ee->evas);
71 if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
72 return ECORE_CALLBACK_PASS_ON;
73}
74
75static Eina_Bool
76_ecore_evas_sdl_event_video_resize(void *data __UNUSED__, int type __UNUSED__, void *event)
77{
78 Ecore_Sdl_Event_Video_Resize *e;
79 Ecore_Evas *ee;
80
81 e = event;
82 ee = _ecore_evas_sdl_match();
83
84 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
85 evas_output_size_set(ee->evas, e->w, e->h);
86
87 return ECORE_CALLBACK_PASS_ON;
88}
89
90static Eina_Bool
91_ecore_evas_sdl_event_video_expose(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
92{
93 Ecore_Evas *ee;
94 int w;
95 int h;
96
97 ee = _ecore_evas_sdl_match();
98
99 if (!ee) return ECORE_CALLBACK_PASS_ON;
100 evas_output_size_get(ee->evas, &w, &h);
101 evas_damage_rectangle_add(ee->evas, 0, 0, w, h);
102
103 return ECORE_CALLBACK_PASS_ON;
104}
105
106static int
107_ecore_evas_render(Ecore_Evas *ee)
108{
109 Eina_List *updates;
110
111 updates = evas_render_updates(ee->evas);
112 if (updates)
113 {
114 evas_render_updates_free(updates);
115 _ecore_evas_idle_timeout_update(ee);
116 }
117 return updates ? 1 : 0;
118}
119
120static int
121_ecore_evas_sdl_render(Ecore_Evas *ee)
122{
123 int rend = 0;
124 Eina_List *ll;
125 Ecore_Evas *ee2;
126
127 EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
128 {
129 if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
130 if (ee2->engine.func->fn_render)
131 rend |= ee2->engine.func->fn_render(ee2);
132 if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
133 }
134
135 if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
136
137 if (ee->prop.avoid_damage) rend = _ecore_evas_render(ee);
138 else if ((ee->visible) ||
139 ((ee->should_be_visible) && (ee->prop.fullscreen)) ||
140 ((ee->should_be_visible) && (ee->prop.override)))
141 rend |= _ecore_evas_render(ee);
142 else
143 evas_norender(ee->evas);
144
145 if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
146 return rend;
147}
148
149static Eina_Bool
150_ecore_evas_sdl_event(void *data __UNUSED__)
151{
152 ecore_sdl_feed_events();
153 return ECORE_CALLBACK_RENEW;
154}
155
156static int
157_ecore_evas_sdl_init(int w __UNUSED__, int h __UNUSED__)
158{
159 _ecore_evas_init_count++;
160 if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
161
162#ifndef _WIN32
163 if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1;
164#endif /* _WIN32 */
165 // this is pretty bad: poller? and set poll time? pol time is meant to be
166 // adjustable for things like polling battery state, or amoutn of spare
167 // memory etc.
168 //
169 ecore_evas_event = ecore_poller_add(ECORE_POLLER_CORE, 1, _ecore_evas_sdl_event, NULL);
170 ecore_poller_poll_interval_set(ECORE_POLLER_CORE, 0.006);
171#ifndef _WIN32
172 if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init();
173#endif /* _WIN32 */
174
175 ecore_event_evas_init();
176
177 ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_SDL_EVENT_GOT_FOCUS, _ecore_evas_sdl_event_got_focus, NULL);
178 ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_SDL_EVENT_LOST_FOCUS, _ecore_evas_sdl_event_lost_focus, NULL);
179 ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_SDL_EVENT_RESIZE, _ecore_evas_sdl_event_video_resize, NULL);
180 ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_SDL_EVENT_EXPOSE, _ecore_evas_sdl_event_video_expose, NULL);
181
182 return _ecore_evas_init_count;
183}
184
185static int
186_ecore_evas_sdl_shutdown(void)
187{
188 _ecore_evas_init_count--;
189 if (_ecore_evas_init_count == 0)
190 {
191 int i;
192
193 for (i = 0; i < sizeof (ecore_evas_event_handlers) / sizeof (Ecore_Event_Handler*); i++)
194 ecore_event_handler_del(ecore_evas_event_handlers[i]);
195 ecore_event_evas_shutdown();
196 ecore_poller_del(ecore_evas_event);
197 ecore_evas_event = NULL;
198#ifndef _WIN32
199 if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown();
200#endif /* _WIN32 */
201 }
202 if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
203 return _ecore_evas_init_count;
204}
205
206static void
207_ecore_evas_sdl_free(Ecore_Evas *ee)
208{
209 if (sdl_ee == ee) sdl_ee = NULL;
210
211 ecore_event_window_unregister(0);
212 _ecore_evas_sdl_shutdown();
213 ecore_sdl_shutdown();
214}
215
216static void
217_ecore_evas_resize(Ecore_Evas *ee, int w, int h)
218{
219 if ((w == ee->w) && (h == ee->h)) return;
220 ee->w = w;
221 ee->h = h;
222
223 evas_output_size_set(ee->evas, ee->w, ee->h);
224 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
225 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
226
227 if (ee->func.fn_resize) ee->func.fn_resize(ee);
228}
229
230static void
231_ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
232{
233 if ((w == ee->w) && (h == ee->h)) return;
234 ee->w = w;
235 ee->h = h;
236
237 evas_output_size_set(ee->evas, ee->w, ee->h);
238 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
239 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
240
241 if (ee->func.fn_resize) ee->func.fn_resize(ee);
242}
243
244static void
245_ecore_evas_show(Ecore_Evas *ee)
246{
247 if (ee->prop.focused) return;
248 ee->prop.focused = 1;
249 evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
250}
251
252static void
253_ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
254{
255 Ecore_Evas *ee;
256
257 ee = data;
258 if (ee) ee->prop.cursor.object = NULL;
259}
260
261static void
262_ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
263{
264 int x, y;
265
266 if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
267
268 if (!obj)
269 {
270 ee->prop.cursor.object = NULL;
271 ee->prop.cursor.layer = 0;
272 ee->prop.cursor.hot.x = 0;
273 ee->prop.cursor.hot.y = 0;
274 return;
275 }
276
277 ee->prop.cursor.object = obj;
278 ee->prop.cursor.layer = layer;
279 ee->prop.cursor.hot.x = hot_x;
280 ee->prop.cursor.hot.y = hot_y;
281 evas_pointer_output_xy_get(ee->evas, &x, &y);
282 evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
283 evas_object_move(ee->prop.cursor.object,
284 x - ee->prop.cursor.hot.x,
285 y - ee->prop.cursor.hot.y);
286 evas_object_pass_events_set(ee->prop.cursor.object, 1);
287 if (evas_pointer_inside_get(ee->evas))
288 evas_object_show(ee->prop.cursor.object);
289
290 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
291}
292
293static Ecore_Evas_Engine_Func _ecore_sdl_engine_func =
294{
295 _ecore_evas_sdl_free,
296 NULL,
297 NULL,
298 NULL,
299 NULL,
300 NULL,
301 NULL,
302 NULL,
303 NULL,
304 NULL,
305 NULL,
306 NULL,
307 NULL,
308 NULL,
309 NULL,
310 NULL,
311 NULL,
312 _ecore_evas_resize,
313 _ecore_evas_move_resize,
314 NULL,
315 NULL,
316 _ecore_evas_show,
317 NULL,
318 NULL,
319 NULL,
320 NULL,
321 NULL,
322 NULL,
323 NULL,
324 NULL,
325 NULL,
326 NULL,
327 _ecore_evas_object_cursor_set,
328 NULL,
329 NULL,
330 NULL,
331 NULL,
332 NULL,
333 NULL,
334 NULL,
335 NULL,
336 NULL,
337 NULL,
338 NULL,
339 NULL,
340 NULL, //transparent
341
342 NULL, // render
343 NULL // screen_geometry_get
344};
345
346static Ecore_Evas*
347_ecore_evas_internal_sdl_new(int rmethod, const char* name, int w, int h, int fullscreen, int hwsurface, int noframe, int alpha)
348{
349 void *einfo;
350 Ecore_Evas *ee;
351
352 if (!name)
353 name = ecore_evas_sdl_default;
354
355 ee = calloc(1, sizeof(Ecore_Evas));
356 if (!ee) return NULL;
357
358 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
359
360 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_sdl_engine_func;
361
362 ee->driver = "sdl";
363 if (name) ee->name = strdup(name);
364
365 if (w < 1) w = 1;
366 if (h < 1) h = 1;
367 ee->visible = 1;
368 ee->w = w;
369 ee->h = h;
370
371 ee->prop.max.w = 0;
372 ee->prop.max.h = 0;
373 ee->prop.layer = 0;
374 ee->prop.focused = 1;
375 ee->prop.borderless = 1;
376 ee->prop.override = 1;
377 ee->prop.maximized = 1;
378 ee->prop.fullscreen = fullscreen;
379 ee->prop.withdrawn = 0;
380 ee->prop.sticky = 0;
381 ee->prop.window = 0;
382
383 /* init evas here */
384 ee->evas = evas_new();
385 evas_data_attach_set(ee->evas, ee);
386 evas_output_method_set(ee->evas, rmethod);
387
388 evas_output_size_set(ee->evas, w, h);
389 evas_output_viewport_set(ee->evas, 0, 0, w, h);
390
391 if (rmethod == evas_render_method_lookup("software_sdl") ||
392 rmethod == evas_render_method_lookup("software_16_sdl") )
393 {
394#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
395 einfo = evas_engine_info_get(ee->evas);
396 if (einfo)
397 {
398 ((Evas_Engine_Info_SDL *)einfo)->info.rotation = 0;
399 ((Evas_Engine_Info_SDL *)einfo)->info.fullscreen = fullscreen;
400 ((Evas_Engine_Info_SDL *)einfo)->info.hwsurface = hwsurface;
401 ((Evas_Engine_Info_SDL *)einfo)->info.noframe = noframe;
402 ((Evas_Engine_Info_SDL *)einfo)->info.alpha = alpha;
403 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
404 {
405 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
406 ecore_evas_free(ee);
407 return NULL;
408 }
409 }
410 else
411 {
412 ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
413 ecore_evas_free(ee);
414 return NULL;
415 }
416#endif
417 }
418 else if (rmethod == evas_render_method_lookup("gl_sdl"))
419 {
420#ifdef BUILD_ECORE_EVAS_OPENGL_SDL
421 einfo = evas_engine_info_get(ee->evas);
422 if (einfo)
423 {
424 ((Evas_Engine_Info_GL_SDL *)einfo)->flags.fullscreen = fullscreen;
425 ((Evas_Engine_Info_GL_SDL *)einfo)->flags.noframe = noframe;
426 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
427 {
428 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
429 ecore_evas_free(ee);
430 return NULL;
431 }
432 }
433 else
434 {
435 ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
436 ecore_evas_free(ee);
437 return NULL;
438 }
439#endif
440 }
441 else
442 {
443 ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
444 ecore_evas_free(ee);
445 return NULL;
446 }
447
448 if (!ecore_sdl_init(name))
449 {
450 evas_free(ee->evas);
451 if (ee->name) free(ee->name);
452 free(ee);
453 return NULL;
454 }
455
456 _ecore_evas_sdl_init(w, h);
457
458 ecore_event_window_register(0, ee, ee->evas,
459 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
460 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
461 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
462 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
463
464 SDL_ShowCursor(SDL_DISABLE);
465
466 ee->engine.func->fn_render = _ecore_evas_sdl_render;
467 _ecore_evas_register(ee);
468
469 sdl_ee = ee;
470 return ee;
471}
472#endif
473
474#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
475EAPI Ecore_Evas*
476ecore_evas_sdl_new(const char* name, int w, int h, int fullscreen, int hwsurface, int noframe, int alpha)
477{
478 Ecore_Evas *ee;
479 int rmethod;
480
481 rmethod = evas_render_method_lookup("software_sdl");
482 if (!rmethod) return NULL;
483
484 ee = _ecore_evas_internal_sdl_new(rmethod, name, w, h, fullscreen, hwsurface, noframe, alpha);
485 ee->driver = "sdl";
486 return ee;
487}
488#else
489EAPI Ecore_Evas*
490ecore_evas_sdl_new(const char* name __UNUSED__, int w __UNUSED__, int h __UNUSED__, int fullscreen __UNUSED__, int hwsurface __UNUSED__, int noframe __UNUSED__, int alpha __UNUSED__)
491{
492 ERR("OUTCH !");
493 return NULL;
494}
495#endif
496
497#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
498EAPI Ecore_Evas*
499ecore_evas_sdl16_new(const char* name, int w, int h, int fullscreen, int hwsurface, int noframe, int alpha)
500{
501 Ecore_Evas *ee;
502 int rmethod;
503
504 rmethod = evas_render_method_lookup("software_16_sdl");
505 if (!rmethod) return NULL;
506
507 ee = _ecore_evas_internal_sdl_new(rmethod, name, w, h, fullscreen, hwsurface, noframe, alpha);
508 ee->driver = "software_16_sdl";
509 return ee;
510}
511#else
512EAPI Ecore_Evas*
513ecore_evas_sdl16_new(const char* name __UNUSED__, int w __UNUSED__, int h __UNUSED__, int fullscreen __UNUSED__, int hwsurface __UNUSED__, int noframe __UNUSED__, int alpha __UNUSED__)
514{
515 ERR("OUTCH !");
516 return NULL;
517}
518#endif
519
520#ifdef BUILD_ECORE_EVAS_OPENGL_SDL
521EAPI Ecore_Evas*
522ecore_evas_gl_sdl_new(const char* name, int w, int h, int fullscreen, int noframe)
523{
524 Ecore_Evas *ee;
525 int rmethod;
526
527 rmethod = evas_render_method_lookup("gl_sdl");
528 if (!rmethod) return NULL;
529
530 ee = _ecore_evas_internal_sdl_new(rmethod, name, w, h, fullscreen, 0, noframe, 0);
531 ee->driver = "gl_sdl";
532 return ee;
533}
534#else
535EAPI Ecore_Evas*
536ecore_evas_gl_sdl_new(const char* name __UNUSED__, int w __UNUSED__, int h __UNUSED__, int fullscreen __UNUSED__, int noframe __UNUSED__)
537{
538 ERR("OUTCH !");
539 return NULL;
540}
541#endif
542