df9f70f1a316fdde49ee594cb496765d0f318735
[profile/ivi/ecore.git] / src / lib / ecore_evas / ecore_evas_fb.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <sys/types.h>
6 #include <dirent.h>
7
8 #include <Ecore.h>
9 #include "ecore_private.h"
10 #ifdef BUILD_ECORE_EVAS_FB
11 #include <Ecore_Fb.h>
12 #include <ecore_fb_private.h>
13 #endif
14
15 #include "ecore_evas_private.h"
16 #include "Ecore_Evas.h"
17
18 #ifdef BUILD_ECORE_EVAS_FB
19 static int _ecore_evas_init_count = 0;
20
21 static char *ecore_evas_default_display = "0";
22 static Eina_List *ecore_evas_input_devices = NULL;
23 static Ecore_Event_Handler *ecore_evas_event_handlers[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
24
25 static void
26 _ecore_evas_mouse_move_process_fb(Ecore_Evas *ee, int x, int y, unsigned int timestamp)
27 {
28    int fbw, fbh;
29
30    ee->mouse.x = x;
31    ee->mouse.y = y;
32    ecore_fb_size_get(&fbw, &fbh);
33    if (ee->prop.cursor.object)
34      {
35         evas_object_show(ee->prop.cursor.object);
36         if (ee->rotation == 0)
37           evas_object_move(ee->prop.cursor.object,
38                            x - ee->prop.cursor.hot.x,
39                            y - ee->prop.cursor.hot.y);
40         else if (ee->rotation == 90)
41           evas_object_move(ee->prop.cursor.object,
42                            (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.x,
43                            x - ee->prop.cursor.hot.y);
44         else if (ee->rotation == 180)
45           evas_object_move(ee->prop.cursor.object,
46                            (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.x,
47                            (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.y);
48         else if (ee->rotation == 270)
49           evas_object_move(ee->prop.cursor.object,
50                            y - ee->prop.cursor.hot.x,
51                            (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.y);
52      }
53    if (ee->rotation == 0)
54      evas_event_feed_mouse_move(ee->evas, x, y, timestamp, NULL);
55    else if (ee->rotation == 90)
56      evas_event_feed_mouse_move(ee->evas, (fbh - ee->h) + ee->h - y - 1, x, timestamp, NULL);
57    else if (ee->rotation == 180)
58      evas_event_feed_mouse_move(ee->evas, (fbw - ee->w) + ee->w - x - 1, (fbh - ee->h) + ee->h - y - 1, timestamp, NULL);
59    else if (ee->rotation == 270)
60      evas_event_feed_mouse_move(ee->evas, y, (fbw - ee->w) + ee->w - x - 1, timestamp, NULL);
61 }
62
63 static Ecore_Evas *fb_ee = NULL;
64
65 static Ecore_Evas *
66 _ecore_evas_fb_match(void)
67 {
68    return fb_ee;
69 }
70
71 static void
72 _ecore_evas_fb_lose(void *data __UNUSED__)
73 {
74    Eina_List *ll;
75    Ecore_Fb_Input_Device *dev;
76
77    if (fb_ee) fb_ee->visible = 0;
78
79    EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
80      ecore_fb_input_device_listen(dev, 0);
81 }
82
83 static void
84 _ecore_evas_fb_gain(void *data __UNUSED__)
85 {
86    Ecore_Evas *ee;
87    Eina_List *ll;
88    Ecore_Fb_Input_Device *dev;
89
90    if (fb_ee) 
91      {
92         ee = fb_ee;
93         
94         ee->visible = 1;
95         if ((ee->rotation == 90) || (ee->rotation == 270))
96           evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
97         else
98           evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
99      }
100
101    EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
102      ecore_fb_input_device_listen(dev, 1);
103 }
104
105 static Eina_Bool
106 _ecore_evas_event_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
107 {
108    Ecore_Evas *ee;
109    Ecore_Fb_Event_Key_Down *e;
110
111    e = event;
112    ee = _ecore_evas_fb_match();
113    if (!ee) return EINA_TRUE; /* pass on event */
114    evas_event_feed_key_down(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
115    return EINA_FALSE; /* dont pass it on */
116 }
117
118 static Eina_Bool
119 _ecore_evas_event_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
120 {
121    Ecore_Evas *ee;
122    Ecore_Fb_Event_Key_Up *e;
123
124    e = event;
125    ee = _ecore_evas_fb_match();
126    if (!ee) return EINA_TRUE; /* pass on event */
127    evas_event_feed_key_up(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
128    return EINA_FALSE; /* dont pass it on */
129 }
130
131 static Eina_Bool
132 _ecore_evas_event_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
133 {
134    Ecore_Evas *ee;
135    Ecore_Fb_Event_Mouse_Button_Down *e;
136    Evas_Button_Flags flags = EVAS_BUTTON_NONE;
137
138    e = event;
139    ee = _ecore_evas_fb_match();
140    if (!ee) return EINA_TRUE; /* pass on event */
141    _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
142    if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
143    if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
144    evas_event_feed_mouse_down(ee->evas, e->button, flags, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
145    return EINA_FALSE; /* dont pass it on */
146 }
147
148 static Eina_Bool
149 _ecore_evas_event_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
150 {
151    Ecore_Evas *ee;
152    Ecore_Fb_Event_Mouse_Button_Up *e;
153
154    e = event;
155    ee = _ecore_evas_fb_match();
156    if (!ee) return EINA_TRUE; /* pass on event */
157    _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
158    evas_event_feed_mouse_up(ee->evas, e->button, EVAS_BUTTON_NONE, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
159    return EINA_FALSE; /* dont pass it on */
160 }
161
162 static Eina_Bool
163 _ecore_evas_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
164 {
165    Ecore_Evas *ee;
166    Ecore_Fb_Event_Mouse_Move *e;
167
168    e = event;
169    ee = _ecore_evas_fb_match();
170    if (!ee) return EINA_TRUE; /* pass on event */
171    _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
172    return EINA_FALSE; /* dont pass it on */
173 }
174
175 static Eina_Bool
176 _ecore_evas_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
177 {
178    Ecore_Evas *ee;
179    Ecore_Fb_Event_Mouse_Wheel *e;
180    unsigned long long event_time;
181
182    e = event;
183    ee = _ecore_evas_fb_match();
184    if (!ee) return EINA_TRUE; /* pass on event */
185    event_time = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff);
186    _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, event_time);
187    evas_event_feed_mouse_wheel(ee->evas, e->direction, e->wheel, event_time, NULL);
188    return EINA_FALSE; /* dont pass it on */
189 }
190
191 /* XXX: unused
192 static int
193 _ecore_evas_fb_render(Ecore_Evas *ee)
194 {
195    int rend = 0;
196
197    if (ee->visible)
198      {
199         Eina_List *updates;
200
201 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
202         Eina_List *ll;
203         Ecore_Evas *ee2;
204 #endif
205         if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
206 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
207         EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
208           {
209              if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
210              rend |= _ecore_evas_buffer_render(ee2);
211              if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
212           }
213 #endif
214         updates = evas_render_updates(ee->evas);
215         if (updates)
216           {
217              evas_render_updates_free(updates);
218              _ecore_evas_idle_timeout_update(ee);
219              rend = 1;
220           }
221         if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
222      }
223    else
224      evas_norender(ee->evas);
225    return rend;
226 }
227 */
228
229 static int
230 _ecore_evas_fb_init(int w, int h)
231 {
232    Ecore_Fb_Input_Device *device;
233    Ecore_Fb_Input_Device_Cap caps;
234    int mouse_handled = 0;
235    int keyboard_handled = 0;
236
237    DIR *input_dir;
238    struct dirent *input_entry;
239
240    _ecore_evas_init_count++;
241    if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
242
243    /* register all input devices */
244    input_dir = opendir("/dev/input/");
245    if (!input_dir) return _ecore_evas_init_count;
246
247    while ((input_entry = readdir(input_dir)))
248      {
249         char device_path[256];
250
251         if (strncmp(input_entry->d_name, "event", 5) != 0)
252           continue;
253
254         snprintf(device_path, 256, "/dev/input/%s", input_entry->d_name);
255         if (!(device = ecore_fb_input_device_open(device_path)))
256           continue;
257
258         caps = ecore_fb_input_device_cap_get(device);
259
260         /* Mouse */
261 #ifdef HAVE_TSLIB
262         if (caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE)
263 #else
264         if ((caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE) || (caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
265 #endif
266           {
267              ecore_fb_input_device_axis_size_set(device, w, h);
268              ecore_fb_input_device_listen(device,1);
269              ecore_evas_input_devices = eina_list_append(ecore_evas_input_devices, device);
270              if (!mouse_handled)
271                {
272                   ecore_evas_event_handlers[2]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
273                   ecore_evas_event_handlers[3]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
274                   ecore_evas_event_handlers[4]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
275                   ecore_evas_event_handlers[5]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_WHEEL, _ecore_evas_event_mouse_wheel, NULL);
276                   mouse_handled = 1;
277                }
278           }
279         /* Keyboard */
280         else if ((caps & ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS) && !(caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
281           {
282              ecore_fb_input_device_listen(device,1);
283              ecore_evas_input_devices = eina_list_append(ecore_evas_input_devices, device);
284              if (!keyboard_handled)
285                {
286                   ecore_evas_event_handlers[0]  = ecore_event_handler_add(ECORE_FB_EVENT_KEY_DOWN, _ecore_evas_event_key_down, NULL);
287                   ecore_evas_event_handlers[1]  = ecore_event_handler_add(ECORE_FB_EVENT_KEY_UP, _ecore_evas_event_key_up, NULL);
288                   keyboard_handled = 1;
289                }
290           }
291      }
292    closedir(input_dir);
293    
294    if (!mouse_handled)
295      {
296         if (ecore_fb_ts_init())
297           {
298              ecore_evas_event_handlers[2]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
299              ecore_evas_event_handlers[3]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
300              ecore_evas_event_handlers[4]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
301              mouse_handled = 1;
302           }
303      }
304    return _ecore_evas_init_count;
305 }
306
307 static void
308 _ecore_evas_fb_free(Ecore_Evas *ee)
309 {
310    if (fb_ee == ee) fb_ee = NULL;
311    _ecore_evas_fb_shutdown();
312    ecore_fb_shutdown();
313 }
314
315 static void
316 _ecore_evas_resize(Ecore_Evas *ee, int w, int h)
317 {
318    if ((w == ee->w) && (h == ee->h)) return;
319    ee->w = w;
320    ee->h = h;
321    if ((ee->rotation == 90) || (ee->rotation == 270))
322      {
323        evas_output_size_set(ee->evas, ee->h, ee->w);
324        evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
325        evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
326      }
327    else
328      {
329        evas_output_size_set(ee->evas, ee->w, ee->h);
330        evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
331        evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
332      }
333    if (ee->func.fn_resize) ee->func.fn_resize(ee);
334 }
335
336 static void
337 _ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
338 {
339    if ((w == ee->w) && (h == ee->h)) return;
340    ee->w = w;
341    ee->h = h;
342    if ((ee->rotation == 90) || (ee->rotation == 270))
343      {
344        evas_output_size_set(ee->evas, ee->h, ee->w);
345        evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
346        evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
347      }
348    else
349      {
350        evas_output_size_set(ee->evas, ee->w, ee->h);
351        evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
352        evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
353      }
354    if (ee->func.fn_resize) ee->func.fn_resize(ee);
355 }
356
357 static void
358 _ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize __UNUSED__)
359 {
360    Evas_Engine_Info_FB *einfo;
361    int rot_dif;
362
363    if (ee->rotation == rotation) return;
364    einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
365    if (!einfo) return;
366    rot_dif = ee->rotation - rotation;
367    if (rot_dif < 0) rot_dif = -rot_dif;
368    if (rot_dif != 180)
369      {
370
371         einfo->info.rotation = rotation;
372         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
373           {
374              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
375           }
376         if (!ee->prop.fullscreen)
377           {
378              int tmp;
379
380              tmp = ee->w;
381              ee->w = ee->h;
382              ee->h = tmp;
383           }
384         else
385           {
386              if ((rotation == 0) || (rotation == 180))
387                {
388                   evas_output_size_set(ee->evas, ee->w, ee->h);
389                   evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
390                }
391              else
392                {
393                   evas_output_size_set(ee->evas, ee->h, ee->w);
394                   evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
395                }
396           }
397         ee->rotation = rotation;
398      }
399    else
400      {
401         einfo->info.rotation = rotation;
402         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
403           {
404              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
405           }
406         ee->rotation = rotation;
407      }
408    if ((ee->rotation == 90) || (ee->rotation == 270))
409      evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
410    else
411      evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
412    _ecore_evas_mouse_move_process_fb(ee, ee->mouse.x, ee->mouse.y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
413    if (ee->func.fn_resize) ee->func.fn_resize(ee);
414 }
415
416 static void
417 _ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
418 {
419    Ecore_Evas *ee;
420
421    ee = data;
422    if (ee)
423      ee->prop.cursor.object = NULL;
424 }
425
426 static void
427 _ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
428 {
429    int x, y;
430
431    if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
432
433    if (!obj)
434      {
435         ee->prop.cursor.object = NULL;
436         ee->prop.cursor.layer = 0;
437         ee->prop.cursor.hot.x = 0;
438         ee->prop.cursor.hot.y = 0;
439         return;
440      }
441
442    ee->prop.cursor.object = obj;
443    ee->prop.cursor.layer = layer;
444    ee->prop.cursor.hot.x = hot_x;
445    ee->prop.cursor.hot.y = hot_y;
446    evas_pointer_output_xy_get(ee->evas, &x, &y);
447    evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
448    evas_object_move(ee->prop.cursor.object,
449                     x - ee->prop.cursor.hot.x,
450                     y - ee->prop.cursor.hot.y);
451    evas_object_pass_events_set(ee->prop.cursor.object, 1);
452    if (evas_pointer_inside_get(ee->evas))
453      evas_object_show(ee->prop.cursor.object);
454
455    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
456 }
457
458 static void
459 _ecore_evas_fullscreen_set(Ecore_Evas *ee, int on)
460 {
461    Eina_List *l;
462    Ecore_Fb_Input_Device *dev;
463    int resized = 0;
464
465    if (((ee->prop.fullscreen) && (on)) ||
466        ((!ee->prop.fullscreen) && (!on))) return;
467    if (on)
468      {
469         int w, h;
470
471         ee->engine.fb.real_w = ee->w;
472         ee->engine.fb.real_h = ee->h;
473         w = ee->w;
474         h = ee->h;
475         ecore_fb_size_get(&w, &h);
476         if ((w == 0) && (h == 0))
477           {
478              w = ee->w;
479              h = ee->h;
480           }
481         if ((w != ee->w) || (h != ee->h)) resized = 1;
482         ee->w = w;
483         ee->h = h;
484         evas_output_size_set(ee->evas, ee->w, ee->h);
485         evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
486         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
487      }
488    else
489      {
490         if ((ee->engine.fb.real_w != ee->w) || (ee->engine.fb.real_h != ee->h)) resized = 1;
491         ee->w = ee->engine.fb.real_w;
492         ee->h = ee->engine.fb.real_h;
493         evas_output_size_set(ee->evas, ee->w, ee->h);
494         evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
495         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
496      }
497    ee->prop.fullscreen = on;
498    EINA_LIST_FOREACH(ecore_evas_input_devices, l, dev)
499      ecore_fb_input_device_axis_size_set(dev, ee->w, ee->h);
500    /* rescale the input device area */
501    if (resized)
502      {
503         if (ee->func.fn_resize) ee->func.fn_resize(ee);
504      }
505 }
506
507 int
508 _ecore_evas_fb_shutdown(void)
509 {
510    _ecore_evas_init_count--;
511    if (_ecore_evas_init_count == 0)
512      {
513         int i;
514
515         for (i = 0; i < 6; i++)
516           {
517              if (ecore_evas_event_handlers[i])
518                ecore_event_handler_del(ecore_evas_event_handlers[i]);
519           }
520         ecore_fb_ts_shutdown();
521      }
522    if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
523    return _ecore_evas_init_count;
524 }
525
526 static Ecore_Evas_Engine_Func _ecore_fb_engine_func =
527 {
528    _ecore_evas_fb_free,
529      NULL,
530      NULL,
531      NULL,
532      NULL,
533      NULL,
534      NULL,
535      NULL,
536      NULL,
537      NULL,
538      NULL,
539      NULL,
540      NULL,
541      NULL,
542      NULL,
543      NULL,
544      NULL,
545      _ecore_evas_resize,
546      _ecore_evas_move_resize,
547      _ecore_evas_rotation_set,
548      NULL,
549      NULL,
550      NULL,
551      NULL,
552      NULL,
553      NULL,
554      NULL,
555      NULL,
556      NULL,
557      NULL,
558      NULL,
559      NULL,
560      _ecore_evas_object_cursor_set,
561      NULL,
562      NULL,
563      NULL,
564      NULL,
565      NULL,
566      NULL,
567      _ecore_evas_fullscreen_set,
568      NULL,
569      NULL,
570      NULL,
571      NULL,
572      NULL,
573      NULL, //transparent
574      
575      NULL // render
576 };
577 #endif
578
579 /**
580  * To be documented.
581  *
582  * FIXME: To be fixed.
583  */
584 #ifdef BUILD_ECORE_EVAS_FB
585 EAPI Ecore_Evas *
586 ecore_evas_fb_new(const char *disp_name, int rotation, int w, int h)
587 {
588    Evas_Engine_Info_FB *einfo;
589    Ecore_Evas *ee;
590
591    int rmethod;
592
593    if (!disp_name)
594    disp_name = ecore_evas_default_display;
595
596    rmethod = evas_render_method_lookup("fb");
597    if (!rmethod) return NULL;
598
599    if (!ecore_fb_init(disp_name)) return NULL;
600    ecore_fb_callback_gain_set(_ecore_evas_fb_gain, NULL);
601    ecore_fb_callback_lose_set(_ecore_evas_fb_lose, NULL);
602    ee = calloc(1, sizeof(Ecore_Evas));
603    if (!ee) return NULL;
604
605    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
606
607    _ecore_evas_fb_init(w, h);
608
609    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_fb_engine_func;
610
611    ee->driver = "fb";
612    if (disp_name) ee->name = strdup(disp_name);
613
614    if (w < 1) w = 1;
615    if (h < 1) h = 1;
616    ee->rotation = rotation;
617    ee->visible = 1;
618    ee->w = w;
619    ee->h = h;
620
621    ee->prop.max.w = 0;
622    ee->prop.max.h = 0;
623    ee->prop.layer = 0;
624    ee->prop.focused = 1;
625    ee->prop.borderless = 1;
626    ee->prop.override = 1;
627    ee->prop.maximized = 1;
628    ee->prop.fullscreen = 0;
629    ee->prop.withdrawn = 0;
630    ee->prop.sticky = 0;
631
632    /* init evas here */
633    ee->evas = evas_new();
634    evas_data_attach_set(ee->evas, ee);
635    evas_output_method_set(ee->evas, rmethod);
636
637    if ((rotation == 90) || (rotation == 270))
638      {
639        evas_output_size_set(ee->evas, h, w);
640        evas_output_viewport_set(ee->evas, 0, 0, h, w);
641      }
642    else
643      {
644        evas_output_size_set(ee->evas, w, h);
645        evas_output_viewport_set(ee->evas, 0, 0, w, h);
646      }
647
648    einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
649    if (einfo)
650      {
651         einfo->info.virtual_terminal = 0;
652         einfo->info.device_number = strtol(disp_name, NULL, 10);
653         einfo->info.refresh = 0;
654         einfo->info.rotation = ee->rotation;
655         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
656           {
657              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
658           }
659      }
660    evas_key_modifier_add(ee->evas, "Shift");
661    evas_key_modifier_add(ee->evas, "Control");
662    evas_key_modifier_add(ee->evas, "Alt");
663    evas_key_modifier_add(ee->evas, "Meta");
664    evas_key_modifier_add(ee->evas, "Hyper");
665    evas_key_modifier_add(ee->evas, "Super");
666    evas_key_lock_add(ee->evas, "Caps_Lock");
667    evas_key_lock_add(ee->evas, "Num_Lock");
668    evas_key_lock_add(ee->evas, "Scroll_Lock");
669
670    ee->engine.func->fn_render = _ecore_evas_buffer_render;
671    _ecore_evas_register(ee);
672    fb_ee = ee;
673    
674    evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
675    evas_focus_in(ee->evas);
676
677    return ee;
678 }
679 #else
680 EAPI Ecore_Evas *
681 ecore_evas_fb_new(const char *disp_name __UNUSED__, int rotation __UNUSED__, int w __UNUSED__, int h __UNUSED__)
682 {
683    return NULL;
684 }
685 #endif