[ecore] merged svn latest code (svn54830)
[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
181    e = event;
182    ee = _ecore_evas_fb_match();
183    if (!ee) return EINA_TRUE; /* pass on event */
184    _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
185    return EINA_FALSE; /* dont pass it on */
186 }
187
188 /* XXX: unused
189 static int
190 _ecore_evas_fb_render(Ecore_Evas *ee)
191 {
192    int rend = 0;
193
194    if (ee->visible)
195      {
196         Eina_List *updates;
197
198 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
199         Eina_List *ll;
200         Ecore_Evas *ee2;
201 #endif
202         if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
203 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
204         EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
205           {
206              if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
207              rend |= _ecore_evas_buffer_render(ee2);
208              if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
209           }
210 #endif
211         updates = evas_render_updates(ee->evas);
212         if (updates)
213           {
214              evas_render_updates_free(updates);
215              _ecore_evas_idle_timeout_update(ee);
216              rend = 1;
217           }
218         if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
219      }
220    else
221      evas_norender(ee->evas);
222    return rend;
223 }
224 */
225
226 static int
227 _ecore_evas_fb_init(int w, int h)
228 {
229    Ecore_Fb_Input_Device *device;
230    Ecore_Fb_Input_Device_Cap caps;
231    int mouse_handled = 0;
232    int keyboard_handled = 0;
233
234    DIR *input_dir;
235    struct dirent *input_entry;
236
237    _ecore_evas_init_count++;
238    if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
239
240    /* register all input devices */
241    input_dir = opendir("/dev/input/");
242    if (!input_dir) return _ecore_evas_init_count;
243
244    while ((input_entry = readdir(input_dir)))
245      {
246         char device_path[256];
247
248         if (strncmp(input_entry->d_name, "event", 5) != 0)
249           continue;
250
251         snprintf(device_path, 256, "/dev/input/%s", input_entry->d_name);
252         if (!(device = ecore_fb_input_device_open(device_path)))
253           continue;
254
255         caps = ecore_fb_input_device_cap_get(device);
256
257         /* Mouse */
258 #ifdef HAVE_TSLIB
259         if (caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE)
260 #else
261         if ((caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE) || (caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
262 #endif
263           {
264              ecore_fb_input_device_axis_size_set(device, w, h);
265              ecore_fb_input_device_listen(device,1);
266              ecore_evas_input_devices = eina_list_append(ecore_evas_input_devices, device);
267              if (!mouse_handled)
268                {
269                   ecore_evas_event_handlers[2]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
270                   ecore_evas_event_handlers[3]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
271                   ecore_evas_event_handlers[4]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
272                   ecore_evas_event_handlers[5]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_WHEEL, _ecore_evas_event_mouse_wheel, NULL);
273                   mouse_handled = 1;
274                }
275           }
276         /* Keyboard */
277         else if ((caps & ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS) && !(caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
278           {
279              ecore_fb_input_device_listen(device,1);
280              ecore_evas_input_devices = eina_list_append(ecore_evas_input_devices, device);
281              if (!keyboard_handled)
282                {
283                   ecore_evas_event_handlers[0]  = ecore_event_handler_add(ECORE_FB_EVENT_KEY_DOWN, _ecore_evas_event_key_down, NULL);
284                   ecore_evas_event_handlers[1]  = ecore_event_handler_add(ECORE_FB_EVENT_KEY_UP, _ecore_evas_event_key_up, NULL);
285                   keyboard_handled = 1;
286                }
287           }
288      }
289    closedir(input_dir);
290    
291    if (!mouse_handled)
292      {
293         if (ecore_fb_ts_init())
294           {
295              ecore_evas_event_handlers[2]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
296              ecore_evas_event_handlers[3]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
297              ecore_evas_event_handlers[4]  = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
298              mouse_handled = 1;
299           }
300      }
301    return _ecore_evas_init_count;
302 }
303
304 static void
305 _ecore_evas_fb_free(Ecore_Evas *ee)
306 {
307    if (fb_ee == ee) fb_ee = NULL;
308    _ecore_evas_fb_shutdown();
309    ecore_fb_shutdown();
310 }
311
312 static void
313 _ecore_evas_resize(Ecore_Evas *ee, int w, int h)
314 {
315    if ((w == ee->w) && (h == ee->h)) return;
316    ee->w = w;
317    ee->h = h;
318    if ((ee->rotation == 90) || (ee->rotation == 270))
319      {
320        evas_output_size_set(ee->evas, ee->h, ee->w);
321        evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
322        evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
323      }
324    else
325      {
326        evas_output_size_set(ee->evas, ee->w, ee->h);
327        evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
328        evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
329      }
330    if (ee->func.fn_resize) ee->func.fn_resize(ee);
331 }
332
333 static void
334 _ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
335 {
336    if ((w == ee->w) && (h == ee->h)) return;
337    ee->w = w;
338    ee->h = h;
339    if ((ee->rotation == 90) || (ee->rotation == 270))
340      {
341        evas_output_size_set(ee->evas, ee->h, ee->w);
342        evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
343        evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
344      }
345    else
346      {
347        evas_output_size_set(ee->evas, ee->w, ee->h);
348        evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
349        evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
350      }
351    if (ee->func.fn_resize) ee->func.fn_resize(ee);
352 }
353
354 static void
355 _ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize __UNUSED__)
356 {
357    Evas_Engine_Info_FB *einfo;
358    int rot_dif;
359
360    if (ee->rotation == rotation) return;
361    einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
362    if (!einfo) return;
363    rot_dif = ee->rotation - rotation;
364    if (rot_dif < 0) rot_dif = -rot_dif;
365    if (rot_dif != 180)
366      {
367
368         einfo->info.rotation = rotation;
369         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
370           {
371              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
372           }
373         if (!ee->prop.fullscreen)
374           {
375              int tmp;
376
377              tmp = ee->w;
378              ee->w = ee->h;
379              ee->h = tmp;
380           }
381         else
382           {
383              if ((rotation == 0) || (rotation == 180))
384                {
385                   evas_output_size_set(ee->evas, ee->w, ee->h);
386                   evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
387                }
388              else
389                {
390                   evas_output_size_set(ee->evas, ee->h, ee->w);
391                   evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
392                }
393           }
394         ee->rotation = rotation;
395      }
396    else
397      {
398         einfo->info.rotation = rotation;
399         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
400           {
401              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
402           }
403         ee->rotation = rotation;
404      }
405    if ((ee->rotation == 90) || (ee->rotation == 270))
406      evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
407    else
408      evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
409    _ecore_evas_mouse_move_process_fb(ee, ee->mouse.x, ee->mouse.y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
410    if (ee->func.fn_resize) ee->func.fn_resize(ee);
411 }
412
413 static void
414 _ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
415 {
416    Ecore_Evas *ee;
417
418    ee = data;
419    if (ee)
420      ee->prop.cursor.object = NULL;
421 }
422
423 static void
424 _ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
425 {
426    int x, y;
427
428    if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
429
430    if (!obj)
431      {
432         ee->prop.cursor.object = NULL;
433         ee->prop.cursor.layer = 0;
434         ee->prop.cursor.hot.x = 0;
435         ee->prop.cursor.hot.y = 0;
436         return;
437      }
438
439    ee->prop.cursor.object = obj;
440    ee->prop.cursor.layer = layer;
441    ee->prop.cursor.hot.x = hot_x;
442    ee->prop.cursor.hot.y = hot_y;
443    evas_pointer_output_xy_get(ee->evas, &x, &y);
444    evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
445    evas_object_move(ee->prop.cursor.object,
446                     x - ee->prop.cursor.hot.x,
447                     y - ee->prop.cursor.hot.y);
448    evas_object_pass_events_set(ee->prop.cursor.object, 1);
449    if (evas_pointer_inside_get(ee->evas))
450      evas_object_show(ee->prop.cursor.object);
451
452    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
453 }
454
455 static void
456 _ecore_evas_fullscreen_set(Ecore_Evas *ee, int on)
457 {
458    Eina_List *l;
459    Ecore_Fb_Input_Device *dev;
460    int resized = 0;
461
462    if (((ee->prop.fullscreen) && (on)) ||
463        ((!ee->prop.fullscreen) && (!on))) return;
464    if (on)
465      {
466         int w, h;
467
468         ee->engine.fb.real_w = ee->w;
469         ee->engine.fb.real_h = ee->h;
470         w = ee->w;
471         h = ee->h;
472         ecore_fb_size_get(&w, &h);
473         if ((w == 0) && (h == 0))
474           {
475              w = ee->w;
476              h = ee->h;
477           }
478         if ((w != ee->w) || (h != ee->h)) resized = 1;
479         ee->w = w;
480         ee->h = h;
481         evas_output_size_set(ee->evas, ee->w, ee->h);
482         evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
483         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
484      }
485    else
486      {
487         if ((ee->engine.fb.real_w != ee->w) || (ee->engine.fb.real_h != ee->h)) resized = 1;
488         ee->w = ee->engine.fb.real_w;
489         ee->h = ee->engine.fb.real_h;
490         evas_output_size_set(ee->evas, ee->w, ee->h);
491         evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
492         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
493      }
494    ee->prop.fullscreen = on;
495    EINA_LIST_FOREACH(ecore_evas_input_devices, l, dev)
496      ecore_fb_input_device_axis_size_set(dev, ee->w, ee->h);
497    /* rescale the input device area */
498    if (resized)
499      {
500         if (ee->func.fn_resize) ee->func.fn_resize(ee);
501      }
502 }
503
504 int
505 _ecore_evas_fb_shutdown(void)
506 {
507    _ecore_evas_init_count--;
508    if (_ecore_evas_init_count == 0)
509      {
510         int i;
511
512         for (i = 0; i < 6; i++)
513           {
514              if (ecore_evas_event_handlers[i])
515                ecore_event_handler_del(ecore_evas_event_handlers[i]);
516           }
517         ecore_fb_ts_shutdown();
518      }
519    if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
520    return _ecore_evas_init_count;
521 }
522
523 static Ecore_Evas_Engine_Func _ecore_fb_engine_func =
524 {
525    _ecore_evas_fb_free,
526      NULL,
527      NULL,
528      NULL,
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      _ecore_evas_resize,
543      _ecore_evas_move_resize,
544      _ecore_evas_rotation_set,
545      NULL,
546      NULL,
547      NULL,
548      NULL,
549      NULL,
550      NULL,
551      NULL,
552      NULL,
553      NULL,
554      NULL,
555      NULL,
556      NULL,
557      _ecore_evas_object_cursor_set,
558      NULL,
559      NULL,
560      NULL,
561      NULL,
562      NULL,
563      NULL,
564      _ecore_evas_fullscreen_set,
565      NULL,
566      NULL,
567      NULL,
568      NULL,
569      NULL,
570      NULL, //transparent
571      
572      NULL // render
573 };
574 #endif
575
576 /**
577  * To be documented.
578  *
579  * FIXME: To be fixed.
580  */
581 #ifdef BUILD_ECORE_EVAS_FB
582 EAPI Ecore_Evas *
583 ecore_evas_fb_new(const char *disp_name, int rotation, int w, int h)
584 {
585    Evas_Engine_Info_FB *einfo;
586    Ecore_Evas *ee;
587
588    int rmethod;
589
590    if (!disp_name)
591    disp_name = ecore_evas_default_display;
592
593    rmethod = evas_render_method_lookup("fb");
594    if (!rmethod) return NULL;
595
596    if (!ecore_fb_init(disp_name)) return NULL;
597    ecore_fb_callback_gain_set(_ecore_evas_fb_gain, NULL);
598    ecore_fb_callback_lose_set(_ecore_evas_fb_lose, NULL);
599    ee = calloc(1, sizeof(Ecore_Evas));
600    if (!ee) return NULL;
601
602    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
603
604    _ecore_evas_fb_init(w, h);
605
606    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_fb_engine_func;
607
608    ee->driver = "fb";
609    if (disp_name) ee->name = strdup(disp_name);
610
611    if (w < 1) w = 1;
612    if (h < 1) h = 1;
613    ee->rotation = rotation;
614    ee->visible = 1;
615    ee->w = w;
616    ee->h = h;
617
618    ee->prop.max.w = 0;
619    ee->prop.max.h = 0;
620    ee->prop.layer = 0;
621    ee->prop.focused = 1;
622    ee->prop.borderless = 1;
623    ee->prop.override = 1;
624    ee->prop.maximized = 1;
625    ee->prop.fullscreen = 0;
626    ee->prop.withdrawn = 0;
627    ee->prop.sticky = 0;
628
629    /* init evas here */
630    ee->evas = evas_new();
631    evas_data_attach_set(ee->evas, ee);
632    evas_output_method_set(ee->evas, rmethod);
633
634    if ((rotation == 90) || (rotation == 270))
635      {
636        evas_output_size_set(ee->evas, h, w);
637        evas_output_viewport_set(ee->evas, 0, 0, h, w);
638      }
639    else
640      {
641        evas_output_size_set(ee->evas, w, h);
642        evas_output_viewport_set(ee->evas, 0, 0, w, h);
643      }
644
645    einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
646    if (einfo)
647      {
648         einfo->info.virtual_terminal = 0;
649         einfo->info.device_number = strtol(disp_name, NULL, 10);
650         einfo->info.refresh = 0;
651         einfo->info.rotation = ee->rotation;
652         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
653           {
654              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
655           }
656      }
657    evas_key_modifier_add(ee->evas, "Shift");
658    evas_key_modifier_add(ee->evas, "Control");
659    evas_key_modifier_add(ee->evas, "Alt");
660    evas_key_modifier_add(ee->evas, "Meta");
661    evas_key_modifier_add(ee->evas, "Hyper");
662    evas_key_modifier_add(ee->evas, "Super");
663    evas_key_lock_add(ee->evas, "Caps_Lock");
664    evas_key_lock_add(ee->evas, "Num_Lock");
665    evas_key_lock_add(ee->evas, "Scroll_Lock");
666
667    ee->engine.func->fn_render = _ecore_evas_buffer_render;
668    _ecore_evas_register(ee);
669    fb_ee = ee;
670    
671    evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
672    evas_focus_in(ee->evas);
673
674    return ee;
675 }
676 #else
677 EAPI Ecore_Evas *
678 ecore_evas_fb_new(const char *disp_name __UNUSED__, int rotation __UNUSED__, int w __UNUSED__, int h __UNUSED__)
679 {
680    return NULL;
681 }
682 #endif