1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 
5 #include <stdlib.h>
6 #include <sys/types.h>
7 
8 #include <Eina.h>
9 #include <Ecore.h>
10 #include "ecore_private.h"
11 #include <Ecore_Input.h>
12 #include <Ecore_Input_Evas.h>
13 #include <Ecore_Fb.h>
14 #include "ecore_fb_private.h"
15 
16 #include <Ecore_Evas.h>
17 #include "ecore_evas_private.h"
18 #include <Evas_Engine_FB.h>
19 
20 #ifdef EAPI
21 # undef EAPI
22 #endif
23 
24 #ifdef _WIN32
25 # ifdef DLL_EXPORT
26 #  define EAPI __declspec(dllexport)
27 # else
28 #  define EAPI
29 # endif /* ! DLL_EXPORT */
30 #else
31 # ifdef __GNUC__
32 #  if __GNUC__ >= 4
33 #   define EAPI __attribute__ ((visibility("default")))
34 #  else
35 #   define EAPI
36 #  endif
37 # else
38 #  define EAPI
39 # endif
40 #endif /* ! _WIN32 */
41 
42 static int _ecore_evas_init_count = 0;
43 
44 static char *ecore_evas_default_display = "0";
45 static Eina_List *ecore_evas_input_devices = NULL;
46 static Ecore_Event_Handler *ecore_evas_event_handlers[4] = {NULL, NULL, NULL, NULL};
47 
48 typedef struct _Ecore_Evas_Engine_FB_Data Ecore_Evas_Engine_FB_Data;
49 
50 struct _Ecore_Evas_Engine_FB_Data {
51    int real_w;
52    int real_h;
53 };
54 
55 static void
_ecore_evas_mouse_move_process_fb(Ecore_Evas * ee,int x,int y)56 _ecore_evas_mouse_move_process_fb(Ecore_Evas *ee, int x, int y)
57 {
58    const Efl_Input_Device *pointer;
59    Ecore_Evas_Cursor *cursor;
60    int fbw, fbh;
61 
62    ecore_fb_size_get(&fbw, &fbh);
63 
64    pointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_MOUSE);
65    pointer = evas_device_parent_get(pointer);
66    cursor = eina_hash_find(ee->prop.cursors, &pointer);
67    EINA_SAFETY_ON_NULL_RETURN(cursor);
68    cursor->pos_x = x;
69    cursor->pos_y = y;
70    if (cursor->object)
71      {
72         evas_object_show(cursor->object);
73         if (ee->rotation == 0)
74           evas_object_move(cursor->object,
75                            x - cursor->hot.x,
76                            y - cursor->hot.y);
77         else if (ee->rotation == 90)
78           evas_object_move(cursor->object,
79                            (fbh - ee->h) + ee->h - y - 1 - cursor->hot.x,
80                            x - cursor->hot.y);
81         else if (ee->rotation == 180)
82           evas_object_move(cursor->object,
83                            (fbw - ee->w) + ee->w - x - 1 - cursor->hot.x,
84                            (fbh - ee->h) + ee->h - y - 1 - cursor->hot.y);
85         else if (ee->rotation == 270)
86           evas_object_move(cursor->object,
87                            y - cursor->hot.x,
88                            (fbw - ee->w) + ee->w - x - 1 - cursor->hot.y);
89      }
90 }
91 
92 static void
_ecore_evas_fb_lose(void * data)93 _ecore_evas_fb_lose(void *data)
94 {
95    Ecore_Evas *ee = data;
96    Eina_List *ll;
97    Ecore_Fb_Input_Device *dev;
98 
99    if (ee) ee->visible = 0;
100 
101    EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
102      ecore_fb_input_device_listen(dev, 0);
103 }
104 
105 static void
_ecore_evas_fb_gain(void * data)106 _ecore_evas_fb_gain(void *data)
107 {
108    Ecore_Evas *ee = data;
109    Eina_List *ll;
110    Ecore_Fb_Input_Device *dev;
111 
112    if (ee)
113      {
114         ee->visible = 1;
115         if (ECORE_EVAS_PORTRAIT(ee))
116           evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
117         else
118           evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
119      }
120 
121    EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
122      ecore_fb_input_device_listen(dev, 1);
123 }
124 
125 static Eina_Bool
_ecore_evas_event_mouse_button_down(void * data,int type EINA_UNUSED,void * event)126 _ecore_evas_event_mouse_button_down(void *data, int type EINA_UNUSED, void *event)
127 {
128    Ecore_Evas *ee = data;
129    Ecore_Event_Mouse_Button *e;
130 
131    e = event;
132    if (!ee) return ECORE_CALLBACK_PASS_ON;
133    _ecore_evas_mouse_move_process_fb(ee, e->x, e->y);
134    return ECORE_CALLBACK_PASS_ON;
135 }
136 
137 static Eina_Bool
_ecore_evas_event_mouse_button_up(void * data,int type EINA_UNUSED,void * event)138 _ecore_evas_event_mouse_button_up(void *data, int type EINA_UNUSED, void *event)
139 {
140    Ecore_Evas *ee = data;
141    Ecore_Event_Mouse_Button *e;
142 
143    e = event;
144    if (!ee) return ECORE_CALLBACK_PASS_ON;
145    _ecore_evas_mouse_move_process_fb(ee, e->x, e->y);
146    return ECORE_CALLBACK_PASS_ON;
147 }
148 
149 static Eina_Bool
_ecore_evas_event_mouse_move(void * data,int type EINA_UNUSED,void * event)150 _ecore_evas_event_mouse_move(void *data, int type EINA_UNUSED, void *event)
151 {
152    Ecore_Evas *ee = data;
153    Ecore_Event_Mouse_Move *e;
154 
155    e = event;
156    if (!ee) return ECORE_CALLBACK_PASS_ON;
157    _ecore_evas_mouse_move_process_fb(ee, e->x, e->y);
158    return ECORE_CALLBACK_PASS_ON;
159 }
160 
161 static Eina_Bool
_ecore_evas_event_mouse_wheel(void * data,int type EINA_UNUSED,void * event)162 _ecore_evas_event_mouse_wheel(void *data, int type EINA_UNUSED, void *event)
163 {
164    Ecore_Evas *ee = data;
165    Ecore_Event_Mouse_Wheel *e;
166 
167    e = event;
168    if (!ee) return ECORE_CALLBACK_PASS_ON;
169    _ecore_evas_mouse_move_process_fb(ee, e->x, e->y);
170    return ECORE_CALLBACK_PASS_ON;
171 }
172 
173 static int
_ecore_evas_fb_init(Ecore_Evas * ee,int w,int h)174 _ecore_evas_fb_init(Ecore_Evas *ee, int w, int h)
175 {
176    Eina_File_Direct_Info *info;
177    Eina_Iterator *ls;
178    Ecore_Fb_Input_Device *device;
179    Ecore_Fb_Input_Device_Cap caps;
180    int mouse_handled = 0, always_ts;
181    const char *s;
182 
183    _ecore_evas_init_count++;
184    if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
185 
186    ecore_event_evas_init();
187 
188    /* register all input devices */
189    ls = eina_file_direct_ls("/dev/input/");
190 
191    EINA_ITERATOR_FOREACH(ls, info)
192      {
193         if (strncmp(info->path + info->name_start, "event", 5) != 0)
194           continue;
195 
196         if (!(device = ecore_fb_input_device_open(info->path)))
197           continue;
198         ecore_fb_input_device_window_set(device, ee);
199 
200         caps = ecore_fb_input_device_cap_get(device);
201 
202         /* Mouse */
203 #ifdef HAVE_TSLIB
204         if (caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE)
205 #else
206         if ((caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE) || (caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
207 #endif
208           {
209              ecore_fb_input_device_axis_size_set(device, w, h);
210              ecore_fb_input_device_listen(device,1);
211              ecore_evas_input_devices = eina_list_append(ecore_evas_input_devices, device);
212              if (!mouse_handled)
213                {
214                   ecore_evas_event_handlers[0]  = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
215                   ecore_evas_event_handlers[1]  = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
216                   ecore_evas_event_handlers[2]  = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
217                   ecore_evas_event_handlers[3]  = ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _ecore_evas_event_mouse_wheel, NULL);
218                   mouse_handled = 1;
219                }
220           }
221         /* Keyboard */
222         else if ((caps & ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS) && !(caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
223           {
224              ecore_fb_input_device_listen(device,1);
225              ecore_evas_input_devices = eina_list_append(ecore_evas_input_devices, device);
226           }
227      }
228    eina_iterator_free(ls);
229 
230    /* force to check for touchscreen via tslib even if mouse was detected */
231    s = getenv("ECORE_EVAS_FB_TS_ALWAYS");
232    always_ts = s ? atoi(s) : 0;
233 
234    if ((!mouse_handled) || (always_ts))
235      {
236         if (ecore_fb_ts_init())
237           {
238              ecore_fb_ts_event_window_set(ee);
239              ecore_evas_event_handlers[0]  = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
240              ecore_evas_event_handlers[1]  = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
241              ecore_evas_event_handlers[2]  = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
242              mouse_handled = 1;
243           }
244      }
245    return _ecore_evas_init_count;
246 }
247 
248 int
_ecore_evas_fb_shutdown(void)249 _ecore_evas_fb_shutdown(void)
250 {
251    _ecore_evas_init_count--;
252    if (_ecore_evas_init_count == 0)
253      {
254         int i;
255 
256         for (i = 0; i < 4; i++)
257           {
258              if (ecore_evas_event_handlers[i])
259                ecore_event_handler_del(ecore_evas_event_handlers[i]);
260           }
261         ecore_fb_ts_shutdown();
262         ecore_event_evas_shutdown();
263      }
264    if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
265    return _ecore_evas_init_count;
266 }
267 
268 static void
_ecore_evas_fb_free(Ecore_Evas * ee)269 _ecore_evas_fb_free(Ecore_Evas *ee)
270 {
271    Ecore_Evas_Engine_FB_Data *idata = ee->engine.data;
272 
273    ecore_evas_input_event_unregister(ee);
274    free(idata);
275    _ecore_evas_fb_shutdown();
276    ecore_fb_shutdown();
277 }
278 
279 static void
_ecore_evas_resize(Ecore_Evas * ee,int w,int h)280 _ecore_evas_resize(Ecore_Evas *ee, int w, int h)
281 {
282    ee->req.w = w;
283    ee->req.h = h;
284    if ((w == ee->w) && (h == ee->h)) return;
285    ee->w = w;
286    ee->h = h;
287    if (ECORE_EVAS_PORTRAIT(ee))
288      {
289        evas_output_size_set(ee->evas, ee->w, ee->h);
290        evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
291        evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
292      }
293    else
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        evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
298      }
299    if (ee->func.fn_resize) ee->func.fn_resize(ee);
300 }
301 
302 static void
_ecore_evas_move_resize(Ecore_Evas * ee,int x EINA_UNUSED,int y EINA_UNUSED,int w,int h)303 _ecore_evas_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED, int w, int h)
304 {
305    ee->req.w = w;
306    ee->req.h = h;
307    if ((w == ee->w) && (h == ee->h)) return;
308    ee->w = w;
309    ee->h = h;
310    if (ECORE_EVAS_PORTRAIT(ee))
311      {
312        evas_output_size_set(ee->evas, ee->w, ee->h);
313        evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
314        evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
315      }
316    else
317      {
318        evas_output_size_set(ee->evas, ee->h, ee->w);
319        evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
320        evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
321      }
322    if (ee->func.fn_resize) ee->func.fn_resize(ee);
323 }
324 
325 static void
_ecore_evas_rotation_set(Ecore_Evas * ee,int rotation,int resize EINA_UNUSED)326 _ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize EINA_UNUSED)
327 {
328    const Evas_Device *pointer;
329    Ecore_Evas_Cursor *cursor;
330    Evas_Engine_Info_FB *einfo;
331    int rot_dif;
332 
333    pointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_MOUSE);
334    pointer = evas_device_parent_get(pointer);
335    cursor = eina_hash_find(ee->prop.cursors, &pointer);
336    EINA_SAFETY_ON_NULL_RETURN(cursor);
337 
338    if (ee->rotation == rotation) return;
339    einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
340    if (!einfo) return;
341    rot_dif = ee->rotation - rotation;
342    if (rot_dif < 0) rot_dif = -rot_dif;
343    if (rot_dif != 180)
344      {
345 
346         einfo->info.rotation = rotation;
347         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
348           {
349              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
350           }
351         if (!ee->prop.fullscreen)
352           {
353              int tmp;
354 
355              tmp = ee->w;
356              ee->w = ee->h;
357              ee->h = tmp;
358              ee->req.w = ee->w;
359              ee->req.h = ee->h;
360           }
361         else
362           {
363              if (ECORE_EVAS_PORTRAIT(ee))
364                {
365                   evas_output_size_set(ee->evas, ee->w, ee->h);
366                   evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
367                }
368              else
369                {
370                   evas_output_size_set(ee->evas, ee->h, ee->w);
371                   evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
372                }
373           }
374         ee->rotation = rotation;
375      }
376    else
377      {
378         einfo->info.rotation = rotation;
379         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
380           {
381              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
382           }
383         ee->rotation = rotation;
384      }
385    if (ECORE_EVAS_PORTRAIT(ee))
386      evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
387    else
388      evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
389 
390    _ecore_evas_mouse_move_process_fb(ee, cursor->pos_x, cursor->pos_y);
391    if (ee->func.fn_resize) ee->func.fn_resize(ee);
392 }
393 
394 static void
_ecore_evas_show(Ecore_Evas * ee)395 _ecore_evas_show(Ecore_Evas *ee)
396 {
397    if (ecore_evas_focus_device_get(ee, NULL)) return;
398    ee->prop.withdrawn = EINA_FALSE;
399    if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
400    _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE);
401 }
402 
403 static void
_ecore_evas_hide(Ecore_Evas * ee)404 _ecore_evas_hide(Ecore_Evas *ee)
405 {
406    ee->prop.withdrawn = EINA_TRUE;
407    if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
408    _ecore_evas_focus_device_set(ee, NULL, EINA_FALSE);
409 }
410 
411 static void
_ecore_evas_fullscreen_set(Ecore_Evas * ee,Eina_Bool on)412 _ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
413 {
414    Eina_List *l;
415    Ecore_Fb_Input_Device *dev;
416    Ecore_Evas_Engine_FB_Data *idata = ee->engine.data;
417    int resized = 0;
418 
419    if (((ee->prop.fullscreen) && (on)) ||
420        ((!ee->prop.fullscreen) && (!on))) return;
421    if (on)
422      {
423         int w, h;
424 
425         idata->real_w = ee->w;
426         idata->real_h = ee->h;
427         w = ee->w;
428         h = ee->h;
429         ecore_fb_size_get(&w, &h);
430         if ((w == 0) && (h == 0))
431           {
432              w = ee->w;
433              h = ee->h;
434           }
435         if ((w != ee->w) || (h != ee->h)) resized = 1;
436         ee->w = w;
437         ee->h = h;
438         ee->req.w = ee->w;
439         ee->req.h = ee->h;
440         evas_output_size_set(ee->evas, ee->w, ee->h);
441         evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
442         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
443      }
444    else
445      {
446         if ((idata->real_w != ee->w) || (idata->real_h != ee->h)) resized = 1;
447         ee->w = idata->real_w;
448         ee->h = idata->real_h;
449         ee->req.w = ee->w;
450         ee->req.h = ee->h;
451         evas_output_size_set(ee->evas, ee->w, ee->h);
452         evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
453         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
454      }
455    ee->prop.fullscreen = on;
456    EINA_LIST_FOREACH(ecore_evas_input_devices, l, dev)
457      ecore_fb_input_device_axis_size_set(dev, ee->w, ee->h);
458    /* rescale the input device area */
459    if (resized)
460      {
461         if (ee->func.fn_resize) ee->func.fn_resize(ee);
462      }
463 }
464 
465 static void
_ecore_evas_screen_geometry_get(const Ecore_Evas * ee EINA_UNUSED,int * x,int * y,int * w,int * h)466 _ecore_evas_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h)
467 {
468     int fbw, fbh;
469 
470     ecore_fb_size_get(&fbw, &fbh);
471 
472     if (x) *x = 0;
473     if (y) *y = 0;
474     if (w) *w = fbw;
475     if (h) *h = fbh;
476 }
477 
478 static Ecore_Evas_Engine_Func _ecore_fb_engine_func =
479 {
480    _ecore_evas_fb_free,
481      NULL,
482      NULL,
483      NULL,
484      NULL,
485      NULL,
486      NULL,
487      NULL,
488      NULL,
489      NULL,
490      NULL,
491      NULL,
492      NULL,
493      NULL,
494      NULL,
495      NULL,
496      NULL,
497      _ecore_evas_resize,
498      _ecore_evas_move_resize,
499      _ecore_evas_rotation_set,
500      NULL,
501      _ecore_evas_show,
502      _ecore_evas_hide,
503      NULL,
504      NULL,
505      NULL,
506      NULL,
507      NULL,
508      NULL,
509      NULL,
510      NULL,
511      NULL,
512      NULL,
513      NULL,
514      NULL,
515      NULL,
516      NULL,
517      NULL,
518      NULL,
519      NULL,
520      _ecore_evas_fullscreen_set,
521      NULL,
522      NULL,
523      NULL,
524      NULL,
525      NULL,
526      NULL, //transparent
527      NULL, // profiles_set
528      NULL, // profile_set
529 
530      NULL,
531      NULL,
532      NULL,
533      NULL,
534      NULL,
535      NULL,
536 
537      NULL, // render
538      _ecore_evas_screen_geometry_get,
539      NULL, // screen_dpi_get
540      NULL,
541      NULL, // msg_send
542 
543      NULL, // pointer_xy_get
544      NULL, // pointer_warp
545 
546      NULL, // wm_rot_preferred_rotation_set
547      NULL, // wm_rot_available_rotations_set
548      NULL, // wm_rot_manual_rotation_done_set
549      NULL, // wm_rot_manual_rotation_done
550 
551      NULL,  // aux_hints_set
552 
553      NULL, // fn_animator_register
554      NULL, // fn_animator_unregister
555 
556      NULL, // fn_evas_changed
557      NULL, //fn_focus_device_set
558      NULL, //fn_callback_focus_device_in_set
559      NULL, //fn_callback_focus_device_out_set
560      NULL, //fn_callback_device_mouse_in_set
561      NULL, //fn_callback_device_mouse_out_set
562      NULL, //fn_pointer_device_xy_get
563      NULL, //fn_prepare
564      NULL, //fn_last_tick_get
565 };
566 
567 EAPI Ecore_Evas *
ecore_evas_fb_new_internal(const char * disp_name,int rotation,int w,int h)568 ecore_evas_fb_new_internal(const char *disp_name, int rotation, int w, int h)
569 {
570    Evas_Engine_Info_FB *einfo;
571    Ecore_Evas_Engine_FB_Data *idata;
572    Ecore_Evas *ee;
573 
574    int rmethod;
575 
576    if (!disp_name)
577    disp_name = ecore_evas_default_display;
578 
579    rmethod = evas_render_method_lookup("fb");
580    if (!rmethod) return NULL;
581 
582    if (!ecore_fb_init(disp_name)) return NULL;
583    ee = calloc(1, sizeof(Ecore_Evas));
584    if (!ee) return NULL;
585    idata = calloc(1, sizeof(Ecore_Evas_Engine_FB_Data));
586 
587    ee->engine.data = idata;
588 
589    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
590 
591    _ecore_evas_fb_init(ee, w, h);
592 
593    ecore_fb_callback_gain_set(_ecore_evas_fb_gain, ee);
594    ecore_fb_callback_lose_set(_ecore_evas_fb_lose, ee);
595 
596    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_fb_engine_func;
597 
598    ee->driver = "fb";
599    if (disp_name) ee->name = strdup(disp_name);
600 
601    if (w < 1) w = 1;
602    if (h < 1) h = 1;
603    ee->rotation = rotation;
604    ee->visible = 1;
605    ee->w = w;
606    ee->h = h;
607    ee->req.w = ee->w;
608    ee->req.h = ee->h;
609 
610    ee->prop.max.w = 0;
611    ee->prop.max.h = 0;
612    ee->prop.layer = 0;
613    ee->prop.borderless = EINA_TRUE;
614    ee->prop.override = EINA_TRUE;
615    ee->prop.maximized = EINA_TRUE;
616    ee->prop.fullscreen = EINA_FALSE;
617    ee->prop.withdrawn = EINA_TRUE;
618    ee->prop.sticky = EINA_FALSE;
619    ee->prop.window = 1;
620 
621    /* init evas here */
622    if (!ecore_evas_evas_new(ee, w, h))
623      {
624         ERR("Could not create the canvas.");
625         ecore_evas_free(ee);
626         return NULL;
627      }
628    evas_output_method_set(ee->evas, rmethod);
629 
630    einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
631    if (einfo && disp_name)
632      {
633         einfo->info.virtual_terminal = 0;
634         einfo->info.device_number = strtol(disp_name, NULL, 10);
635         einfo->info.refresh = 0;
636         einfo->info.rotation = ee->rotation;
637         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
638           {
639              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
640              ecore_evas_free(ee);
641              return NULL;
642           }
643      }
644    else
645      {
646         ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
647         ecore_evas_free(ee);
648         return NULL;
649      }
650 
651    ecore_evas_done(ee, EINA_TRUE);
652 
653    return ee;
654 }
655