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