[ecore] merged svn latest code (svn54830)
[profile/ivi/ecore.git] / src / lib / ecore_evas / ecore_evas_directfb.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <string.h>
6
7 #include <Ecore.h>
8 #include "ecore_private.h"
9 #ifdef BUILD_ECORE_EVAS_DIRECTFB
10 #include <Ecore_DirectFB.h>
11 #endif
12
13 #include "ecore_evas_private.h"
14 #include "Ecore_Evas.h"
15
16 #ifdef BUILD_ECORE_EVAS_DIRECTFB
17 static int _ecore_evas_init_count = 0;
18 static Ecore_Event_Handler *ecore_evas_event_handlers[13];
19
20 static Eina_Hash *ecore_evases_hash = NULL;
21
22 static int
23 _ecore_evas_directfb_render(Ecore_Evas *ee)
24 {
25    Eina_List *updates, *ll;
26    Ecore_Evas *ee2;
27    int rend = 0;
28
29 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
30    EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
31      {
32         if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
33         rend |= _ecore_evas_buffer_render(ee2);
34         if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
35      }
36 #endif
37    if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
38    updates = evas_render_updates(ee->evas);
39    if (updates)
40      {
41         evas_render_updates_free(updates);
42         _ecore_evas_idle_timeout_update(ee);
43      }
44    if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
45
46    return updates ? 1 : rend;
47 }
48
49 static char *
50 _ecore_evas_directfb_winid_str_get(Ecore_X_Window win)
51 {
52    const char *vals = "qWeRtYuIoP5$&<~";
53    static char id[9];
54    unsigned int val;
55    val = (unsigned int)win;
56    id[0] = vals[(val >> 28) & 0xf];
57    id[1] = vals[(val >> 24) & 0xf];
58    id[2] = vals[(val >> 20) & 0xf];
59    id[3] = vals[(val >> 16) & 0xf];
60    id[4] = vals[(val >> 12) & 0xf];
61    id[5] = vals[(val >>  8) & 0xf];
62    id[6] = vals[(val >>  4) & 0xf];
63    id[7] = vals[(val      ) & 0xf];
64    id[8] = 0;
65    return id;
66 }
67
68 static Ecore_Evas *
69 _ecore_evas_directfb_match(DFBWindowID win)
70 {
71    Ecore_Evas *ee;
72    
73    ee = eina_hash_find(ecore_evases_hash, _ecore_evas_directfb_winid_str_get(win));
74    return ee;
75 }
76
77 static Eina_Bool
78 _ecore_evas_directfb_event_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
79 {
80    Ecore_Evas *ee;
81    Ecore_DirectFB_Event_Key_Down *e;
82
83    e = event;
84    ee = _ecore_evas_directfb_match(e->win);
85
86    if (!ee) return EINA_TRUE; /* pass on event */
87    evas_event_feed_key_down(ee->evas, e->name, e->name, e->string,
88                             e->key_compose, e->time, NULL);
89    return EINA_TRUE;
90 }
91
92 static Eina_Bool
93 _ecore_evas_directfb_event_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
94 {
95    Ecore_Evas *ee;
96    Ecore_DirectFB_Event_Key_Up *e;
97
98    e = event;
99    ee = _ecore_evas_directfb_match(e->win);
100
101    if (!ee) return EINA_TRUE; /* pass on event */
102    evas_event_feed_key_up(ee->evas, e->name, e->name, e->string,
103                           e->key_compose, e->time, NULL);
104    return EINA_TRUE;
105 }
106
107 static Eina_Bool
108 _ecore_evas_directfb_event_motion(void *data __UNUSED__, int type __UNUSED__, void *event)
109 {
110    Ecore_Evas *ee;
111    Ecore_DirectFB_Event_Motion *e;
112
113    e = event;
114    ee = _ecore_evas_directfb_match(e->win);
115
116    if (!ee) return EINA_TRUE; /* pass on event */
117    _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
118    return EINA_TRUE;
119 }
120
121 static Eina_Bool
122 _ecore_evas_directfb_event_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
123 {
124    Ecore_Evas *ee;
125    Ecore_DirectFB_Event_Button_Down *e;
126
127    e = event;
128    ee = _ecore_evas_directfb_match(e->win);
129
130    if (!ee) return EINA_TRUE; /* pass on event */
131    // _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
132    evas_event_feed_mouse_down(ee->evas, e->button, EVAS_BUTTON_NONE, e->time, NULL);
133    return EINA_TRUE;
134 }
135
136 static Eina_Bool
137 _ecore_evas_directfb_event_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
138 {
139    Ecore_Evas *ee;
140    Ecore_DirectFB_Event_Button_Up *e;
141    Evas_Button_Flags flags = EVAS_BUTTON_NONE;
142
143    e = event;
144    ee = _ecore_evas_directfb_match(e->win);
145
146    if (!ee) return EINA_TRUE; /* pass on event */
147    //_ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
148    evas_event_feed_mouse_up(ee->evas, e->button, flags, e->time, NULL);
149    return EINA_TRUE;
150 }
151
152 static Eina_Bool
153 _ecore_evas_directfb_event_enter(void *data __UNUSED__, int type __UNUSED__, void *event)
154 {
155    Ecore_Evas *ee;
156    Ecore_DirectFB_Event_Enter *e;
157
158    e = event;
159    ee = _ecore_evas_directfb_match(e->win);
160
161    if (!ee) return EINA_TRUE; /* pass on event */
162    evas_event_feed_mouse_in(ee->evas, e->time, NULL);
163    //_ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
164    return EINA_TRUE;
165 }
166
167 static Eina_Bool
168 _ecore_evas_directfb_event_leave(void *data __UNUSED__, int type __UNUSED__, void *event)
169 {
170    Ecore_Evas *ee;
171    Ecore_DirectFB_Event_Leave *e;
172
173    e = event;
174    ee = _ecore_evas_directfb_match(e->win);
175
176    if (!ee) return EINA_TRUE; /* pass on event */
177    evas_event_feed_mouse_out(ee->evas, e->time, NULL);
178    //_ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
179    if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
180    if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
181    return EINA_TRUE;
182 }
183
184 static Eina_Bool
185 _ecore_evas_directfb_event_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
186 {
187    Ecore_Evas *ee;
188    Ecore_DirectFB_Event_Wheel *e;
189
190    e = event;
191    ee = _ecore_evas_directfb_match(e->win);
192
193    if (!ee) return EINA_TRUE; /* pass on event */
194    evas_event_feed_mouse_wheel(ee->evas, e->direction, e->z, e->time, NULL);
195    return EINA_TRUE;
196 }
197
198 static Eina_Bool
199 _ecore_evas_directfb_event_got_focus(void *data __UNUSED__, int type __UNUSED__, void *event)
200 {
201    Ecore_Evas *ee;
202    Ecore_DirectFB_Event_Got_Focus *e;
203
204    e = event;
205    ee = _ecore_evas_directfb_match(e->win);
206
207    if (!ee) return EINA_TRUE; /* pass on event */
208    ee->prop.focused = 1;
209    return EINA_TRUE;
210 }
211
212 static Eina_Bool
213 _ecore_evas_directfb_event_lost_focus(void *data __UNUSED__, int type __UNUSED__, void *event)
214 {
215    Ecore_Evas *ee;
216    Ecore_DirectFB_Event_Lost_Focus *e;
217
218    e = event;
219    ee = _ecore_evas_directfb_match(e->win);
220
221    if (!ee) return EINA_TRUE; /* pass on event */
222    ee->prop.focused = 0;
223    return EINA_TRUE;
224 }
225
226 int
227 _ecore_evas_directfb_shutdown(void)
228 {
229    _ecore_evas_init_count--;
230    if (_ecore_evas_init_count == 0)
231      {
232         int i;
233
234         for (i = 0; i < 8; i++)
235           ecore_event_handler_del(ecore_evas_event_handlers[i]);
236      }
237    if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
238    return _ecore_evas_init_count;
239 }
240
241
242
243
244
245 int
246 _ecore_evas_directfb_init(void)
247 {
248    _ecore_evas_init_count++;
249    if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
250
251    ecore_evas_event_handlers[0]  = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_KEY_DOWN, _ecore_evas_directfb_event_key_down, NULL);
252    ecore_evas_event_handlers[1]  = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_KEY_UP, _ecore_evas_directfb_event_key_up, NULL);
253    ecore_evas_event_handlers[2]  = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_BUTTON_DOWN, _ecore_evas_directfb_event_button_down, NULL);
254    ecore_evas_event_handlers[3]  = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_BUTTON_UP, _ecore_evas_directfb_event_button_up, NULL);
255    ecore_evas_event_handlers[4]  = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_MOTION, _ecore_evas_directfb_event_motion, NULL);
256    ecore_evas_event_handlers[5]  = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_ENTER, _ecore_evas_directfb_event_enter, NULL);
257    ecore_evas_event_handlers[6]  = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_LEAVE, _ecore_evas_directfb_event_leave, NULL);
258    ecore_evas_event_handlers[7]  = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_WHEEL, _ecore_evas_directfb_event_wheel, NULL);
259    ecore_evas_event_handlers[8]  = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_GOT_FOCUS, _ecore_evas_directfb_event_got_focus, NULL);
260    ecore_evas_event_handlers[9]  = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_LOST_FOCUS, _ecore_evas_directfb_event_lost_focus, NULL);
261    ecore_evas_event_handlers[10]  = NULL;
262    ecore_evas_event_handlers[11]  = NULL;
263    ecore_evas_event_handlers[12]  = NULL;
264
265    return _ecore_evas_init_count;
266 }
267
268 /* engine functions */
269 /********************/
270
271 static void
272 _ecore_evas_directfb_free(Ecore_Evas *ee)
273 {
274    eina_hash_del(ecore_evases_hash, _ecore_evas_directfb_winid_str_get(ee->engine.directfb.window->id), ee);
275    ecore_directfb_window_free(ee->engine.directfb.window);
276    _ecore_evas_directfb_shutdown();
277    ecore_directfb_shutdown();
278 }
279
280 static void
281 _ecore_evas_directfb_move(Ecore_Evas *ee, int x, int y)
282 {
283    ecore_directfb_window_move(ee->engine.directfb.window, x, y);
284 }
285
286 static void
287 _ecore_evas_directfb_resize(Ecore_Evas *ee, int w, int h)
288 {
289    if ((w == ee->w) && (h == ee->h)) return;
290    ecore_directfb_window_resize(ee->engine.directfb.window, w, h);
291    ee->w = w;
292    ee->h = h;
293    if ((ee->rotation == 90) || (ee->rotation == 270))
294      {
295         evas_output_size_set(ee->evas, ee->h, ee->w);
296         evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
297      }
298    else
299      {
300         evas_output_size_set(ee->evas, ee->w, ee->h);
301         evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
302      }
303 }
304
305 static void
306 _ecore_evas_directfb_focus_set(Ecore_Evas *ee, int on __UNUSED__)
307 {
308    ecore_directfb_window_focus(ee->engine.directfb.window);
309 }
310
311 static void
312 _ecore_evas_directfb_hide(Ecore_Evas *ee)
313 {
314    ecore_directfb_window_hide(ee->engine.directfb.window);
315    ee->should_be_visible = 0;
316 }
317
318 static void
319 _ecore_evas_directfb_show(Ecore_Evas *ee)
320 {
321    ecore_directfb_window_show(ee->engine.directfb.window);
322    ee->should_be_visible = 1;
323 }
324
325 static void
326 _ecore_evas_directfb_shaped_set(Ecore_Evas *ee, int shaped)
327 {
328    if (((ee->shaped) && (shaped)) || ((!ee->shaped) && (!shaped)))
329      return;
330    ee->shaped = shaped;
331    if(ee->shaped)
332      ecore_directfb_window_shaped_set(ee->engine.directfb.window, 1);
333    else
334      ecore_directfb_window_shaped_set(ee->engine.directfb.window, 0);
335
336 }
337
338 static void
339 _ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
340 {
341    Ecore_Evas *ee;
342
343    ee = data;
344    if (ee)
345      ee->prop.cursor.object = NULL;
346 }
347
348 static void
349 _ecore_evas_directfb_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
350 {
351    int x, y;
352
353    if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
354
355    if (!obj)
356      {
357         ee->prop.cursor.object = NULL;
358         ee->prop.cursor.layer = 0;
359         ee->prop.cursor.hot.x = 0;
360         ee->prop.cursor.hot.y = 0;
361         ecore_directfb_window_cursor_show(ee->engine.directfb.window, 1);
362         return;
363
364      }
365
366    ee->prop.cursor.object = obj;
367    ee->prop.cursor.layer = layer;
368    ee->prop.cursor.hot.x = hot_x;
369    ee->prop.cursor.hot.y = hot_y;
370
371    ecore_directfb_window_cursor_show(ee->engine.directfb.window, 0);
372
373    evas_pointer_output_xy_get(ee->evas, &x, &y);
374    evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
375    evas_object_move(ee->prop.cursor.object,x - ee->prop.cursor.hot.x,y - ee->prop.cursor.hot.y);
376    evas_object_pass_events_set(ee->prop.cursor.object, 1);
377    if (evas_pointer_inside_get(ee->evas))
378      evas_object_show(ee->prop.cursor.object);
379
380    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
381 }
382
383 static void
384 _ecore_evas_directfb_fullscreen_set(Ecore_Evas *ee, int on)
385 {
386    Evas_Engine_Info_DirectFB *einfo;
387    int w;
388    int h;
389    int resized = 0;
390
391    if (((ee->prop.fullscreen) && (on)) || ((!ee->prop.fullscreen) && (!on)))
392      return;
393
394    if (on)
395      ecore_directfb_window_fullscreen_set(ee->engine.directfb.window, 1);
396    else
397      ecore_directfb_window_fullscreen_set(ee->engine.directfb.window, 0);
398    /* set the new size of the evas */
399    ecore_directfb_window_size_get(ee->engine.directfb.window, &w, &h);
400    if( (ee->w != w) || (ee->h != h))
401      {
402         resized = 1;
403         ee->w = w;
404         ee->h = h;
405         if ((ee->rotation == 90) || (ee->rotation == 270))
406           {
407              evas_output_size_set(ee->evas, ee->h, ee->w);
408              evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
409           }
410         else
411           {
412              evas_output_size_set(ee->evas, ee->w, ee->h);
413              evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
414           }
415      }
416    einfo = (Evas_Engine_Info_DirectFB *)evas_engine_info_get(ee->evas);
417    if (einfo)
418      {
419         einfo->info.surface = ee->engine.directfb.window->surface;
420         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
421           {
422              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
423           }
424      }
425    ee->prop.fullscreen = on;
426    if (resized)
427      {
428         if(ee->func.fn_resize) ee->func.fn_resize(ee);
429      }
430 }
431
432 static void *
433 _ecore_evas_directfb_window_get(const Ecore_Evas *ee)
434 {
435    return ee->engine.directfb.window;
436 }
437 #endif
438
439 #ifdef BUILD_ECORE_EVAS_DIRECTFB
440 static Ecore_Evas_Engine_Func _ecore_directfb_engine_func =
441 {
442    _ecore_evas_directfb_free,        /* free an ecore_evas */
443      NULL,                                /* cb resize */
444      NULL,                                /* cb move */
445      NULL,                                /* cb show */
446      NULL,                                /* cb hide */
447      NULL,                                /* cb delete request */
448      NULL,                                /* cb destroy */
449      NULL,                                /* cb focus in */
450      NULL,                                /* cb focus out */
451      NULL,                              /* cb sticky */
452      NULL,                              /* cb unsticky */
453      NULL,                                /* cb mouse in */
454      NULL,                                /* cb mouse out */
455      NULL,                                /* cb pre render */
456      NULL,                                /* cb post render */
457      _ecore_evas_directfb_move,                /* move */
458      NULL,                              /* managed move */
459      _ecore_evas_directfb_resize,        /* resize */
460      NULL,                                /* move resize */
461      NULL,//_ecore_evas_directfb_rotation_set,/* rotation */
462      _ecore_evas_directfb_shaped_set,   /* shaped */
463      _ecore_evas_directfb_show,                /* show */
464      _ecore_evas_directfb_hide,                /* hide */
465      NULL,                                /* raise */
466      NULL,                                /* lower */
467      NULL,                                /* activate */
468      NULL,                                /* title set */
469      NULL,                                /* name class set */
470      NULL,                                /* size min */
471      NULL,                                /* size max */
472      NULL,                                /* size base */
473      NULL,                                /* size step */
474      _ecore_evas_directfb_object_cursor_set, /* set cursor to an evas object */
475      NULL,                                /* layer set */
476      _ecore_evas_directfb_focus_set,        /* focus */
477      NULL,                                /* iconified */
478      NULL,                                /* borderless */
479      NULL,                                /* override */
480      NULL,                                /* maximized */
481      _ecore_evas_directfb_fullscreen_set,/* fullscreen */
482      NULL,                                /* avoid damage */
483      NULL,                                /* withdrawn */
484      NULL,                                /* sticky */
485      NULL,                              /* ignore events */
486      NULL,                              /* alpha */
487      NULL, //transparent
488      
489      NULL // render
490 };
491 #endif
492
493 /* api */
494 /*******/
495
496 #ifdef BUILD_ECORE_EVAS_DIRECTFB
497 EAPI Ecore_Evas *
498 ecore_evas_directfb_new(const char *disp_name, int windowed, int x, int y, int w, int h)
499 {
500    Evas_Engine_Info_DirectFB *einfo;
501    Ecore_Evas *ee;
502    Ecore_DirectFB_Window *window;
503    int rmethod;
504
505    rmethod = evas_render_method_lookup("directfb");
506    if (!rmethod) return NULL;
507    if (!ecore_directfb_init(disp_name)) return NULL;
508    ee = calloc(1, sizeof(Ecore_Evas));
509    if (!ee) return NULL;
510
511    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
512    _ecore_evas_directfb_init();
513    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_directfb_engine_func;
514
515    ee->driver = "directfb";
516    if (disp_name) ee->name = strdup(disp_name);
517
518    if (w < 1) w = 1;
519    if (h < 1) h = 1;
520
521    ee->rotation = 0;
522    ee->visible = 1;
523    ee->x = x;
524    ee->y = y;
525    ee->w = w;
526    ee->h = h;
527    ee->prop.layer = 1;
528    ee->prop.fullscreen = 0;
529
530    /* init evas here */
531    ee->evas = evas_new();
532    evas_data_attach_set(ee->evas, ee);
533    evas_output_method_set(ee->evas, rmethod);
534    evas_output_size_set(ee->evas, w, h);
535    evas_output_viewport_set(ee->evas, 0, 0, w, h);
536    einfo = (Evas_Engine_Info_DirectFB *)evas_engine_info_get(ee->evas);
537
538    window = ecore_directfb_window_new(x,y,w,h);
539    ee->engine.directfb.window = window;
540    if (einfo)
541      {
542         einfo->info.dfb = ecore_directfb_interface_get();
543         einfo->info.surface = window->surface;
544         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
545           {
546              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
547           }
548      }
549    
550    ee->engine.func->fn_render = _ecore_evas_directfb_render;
551    _ecore_evas_register(ee);
552    
553    if (!ecore_evases_hash)
554      ecore_evases_hash = eina_hash_string_superfast_new(NULL);
555    eina_hash_add(ecore_evases_hash, _ecore_evas_directfb_winid_str_get(ee->engine.directfb.window->id), ee);
556
557    return ee;
558 }
559 #else
560 EAPI Ecore_Evas *
561 ecore_evas_directfb_new(const char *disp_name __UNUSED__, int windowed __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
562 {
563    return NULL;
564 }
565 #endif
566
567 #ifdef BUILD_ECORE_EVAS_DIRECTFB
568 EAPI Ecore_DirectFB_Window *
569 ecore_evas_directfb_window_get(const Ecore_Evas *ee)
570 {
571    return (Ecore_DirectFB_Window *) _ecore_evas_directfb_window_get(ee);
572 }
573 #else
574 EAPI Ecore_DirectFB_Window *
575 ecore_evas_directfb_window_get(const Ecore_Evas *ee __UNUSED__)
576 {
577   return NULL;
578 }
579 #endif