10 #include "ecore_private.h"
11 #ifdef BUILD_ECORE_EVAS_FB
13 #include <ecore_fb_private.h>
16 #include "ecore_evas_private.h"
17 #include "Ecore_Evas.h"
19 #ifdef BUILD_ECORE_EVAS_FB
20 static int _ecore_evas_init_count = 0;
22 static char *ecore_evas_default_display = "0";
23 static Eina_List *ecore_evas_input_devices = NULL;
24 static Ecore_Event_Handler *ecore_evas_event_handlers[4] = {NULL, NULL, NULL, NULL};
27 _ecore_evas_mouse_move_process_fb(Ecore_Evas *ee, int x, int y)
33 ecore_fb_size_get(&fbw, &fbh);
34 if (ee->prop.cursor.object)
36 evas_object_show(ee->prop.cursor.object);
37 if (ee->rotation == 0)
38 evas_object_move(ee->prop.cursor.object,
39 x - ee->prop.cursor.hot.x,
40 y - ee->prop.cursor.hot.y);
41 else if (ee->rotation == 90)
42 evas_object_move(ee->prop.cursor.object,
43 (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.x,
44 x - ee->prop.cursor.hot.y);
45 else if (ee->rotation == 180)
46 evas_object_move(ee->prop.cursor.object,
47 (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.x,
48 (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.y);
49 else if (ee->rotation == 270)
50 evas_object_move(ee->prop.cursor.object,
51 y - ee->prop.cursor.hot.x,
52 (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.y);
56 static Ecore_Evas *fb_ee = NULL;
59 _ecore_evas_fb_match(void)
65 _ecore_evas_fb_lose(void *data __UNUSED__)
68 Ecore_Fb_Input_Device *dev;
70 if (fb_ee) fb_ee->visible = 0;
72 EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
73 ecore_fb_input_device_listen(dev, 0);
77 _ecore_evas_fb_gain(void *data __UNUSED__)
81 Ecore_Fb_Input_Device *dev;
88 if ((ee->rotation == 90) || (ee->rotation == 270))
89 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
91 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
94 EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
95 ecore_fb_input_device_listen(dev, 1);
99 _ecore_evas_event_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
102 Ecore_Event_Mouse_Button *e;
105 ee = _ecore_evas_fb_match();
106 if (!ee) return ECORE_CALLBACK_PASS_ON;
107 _ecore_evas_mouse_move_process_fb(ee, e->x, e->y);
108 return ECORE_CALLBACK_PASS_ON;
112 _ecore_evas_event_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
115 Ecore_Event_Mouse_Button *e;
118 ee = _ecore_evas_fb_match();
119 if (!ee) return ECORE_CALLBACK_PASS_ON;
120 _ecore_evas_mouse_move_process_fb(ee, e->x, e->y);
121 return ECORE_CALLBACK_PASS_ON;
125 _ecore_evas_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
128 Ecore_Event_Mouse_Move *e;
131 ee = _ecore_evas_fb_match();
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;
138 _ecore_evas_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
141 Ecore_Event_Mouse_Wheel *e;
144 ee = _ecore_evas_fb_match();
145 if (!ee) return ECORE_CALLBACK_PASS_ON;
146 _ecore_evas_mouse_move_process_fb(ee, e->x, e->y);
147 return ECORE_CALLBACK_PASS_ON;
151 _ecore_evas_fb_render(Ecore_Evas *ee)
161 if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
163 EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
165 if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
166 if (ee2->engine.func->fn_render)
167 rend |= ee2->engine.func->fn_render(ee2);
168 if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
171 updates = evas_render_updates(ee->evas);
174 evas_render_updates_free(updates);
175 _ecore_evas_idle_timeout_update(ee);
178 if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
181 evas_norender(ee->evas);
186 _ecore_evas_fb_init(Ecore_Evas *ee, int w, int h)
188 Eina_File_Direct_Info *info;
190 Ecore_Fb_Input_Device *device;
191 Ecore_Fb_Input_Device_Cap caps;
192 int mouse_handled = 0;
194 _ecore_evas_init_count++;
195 if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
197 ecore_event_evas_init();
199 /* register all input devices */
200 ls = eina_file_direct_ls("/dev/input/");
202 EINA_ITERATOR_FOREACH(ls, info)
204 if (strncmp(info->path + info->name_start, "event", 5) != 0)
207 if (!(device = ecore_fb_input_device_open(info->path)))
209 ecore_fb_input_device_window_set(device, ee);
211 caps = ecore_fb_input_device_cap_get(device);
215 if (caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE)
217 if ((caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE) || (caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
220 ecore_fb_input_device_axis_size_set(device, w, h);
221 ecore_fb_input_device_listen(device,1);
222 ecore_evas_input_devices = eina_list_append(ecore_evas_input_devices, device);
225 ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
226 ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
227 ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
228 ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _ecore_evas_event_mouse_wheel, NULL);
233 else if ((caps & ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS) && !(caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
235 ecore_fb_input_device_listen(device,1);
236 ecore_evas_input_devices = eina_list_append(ecore_evas_input_devices, device);
239 eina_iterator_free(ls);
243 if (ecore_fb_ts_init())
245 ecore_fb_ts_event_window_set(ee);
246 ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
247 ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
248 ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
252 return _ecore_evas_init_count;
256 _ecore_evas_fb_free(Ecore_Evas *ee)
258 ecore_evas_input_event_unregister(ee);
259 if (fb_ee == ee) fb_ee = NULL;
260 _ecore_evas_fb_shutdown();
265 _ecore_evas_resize(Ecore_Evas *ee, int w, int h)
269 if ((w == ee->w) && (h == ee->h)) return;
272 if ((ee->rotation == 90) || (ee->rotation == 270))
274 evas_output_size_set(ee->evas, ee->h, ee->w);
275 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
276 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
280 evas_output_size_set(ee->evas, ee->w, ee->h);
281 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
282 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
284 if (ee->func.fn_resize) ee->func.fn_resize(ee);
288 _ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
292 if ((w == ee->w) && (h == ee->h)) return;
295 if ((ee->rotation == 90) || (ee->rotation == 270))
297 evas_output_size_set(ee->evas, ee->h, ee->w);
298 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
299 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
303 evas_output_size_set(ee->evas, ee->w, ee->h);
304 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
305 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
307 if (ee->func.fn_resize) ee->func.fn_resize(ee);
311 _ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize __UNUSED__)
313 Evas_Engine_Info_FB *einfo;
316 if (ee->rotation == rotation) return;
317 einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
319 rot_dif = ee->rotation - rotation;
320 if (rot_dif < 0) rot_dif = -rot_dif;
324 einfo->info.rotation = rotation;
325 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
327 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
329 if (!ee->prop.fullscreen)
341 if ((rotation == 0) || (rotation == 180))
343 evas_output_size_set(ee->evas, ee->w, ee->h);
344 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
348 evas_output_size_set(ee->evas, ee->h, ee->w);
349 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
352 ee->rotation = rotation;
356 einfo->info.rotation = rotation;
357 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
359 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
361 ee->rotation = rotation;
363 if ((ee->rotation == 90) || (ee->rotation == 270))
364 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
366 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
367 _ecore_evas_mouse_move_process_fb(ee, ee->mouse.x, ee->mouse.y);
368 if (ee->func.fn_resize) ee->func.fn_resize(ee);
372 _ecore_evas_show(Ecore_Evas *ee)
374 if (ee->prop.focused) return;
375 ee->prop.focused = 1;
376 evas_focus_in(ee->evas);
377 if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
381 _ecore_evas_hide(Ecore_Evas *ee)
383 if (ee->prop.focused)
385 ee->prop.focused = 0;
386 evas_focus_out(ee->evas);
387 if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
392 _ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
398 ee->prop.cursor.object = NULL;
402 _ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
406 if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
410 ee->prop.cursor.object = NULL;
411 ee->prop.cursor.layer = 0;
412 ee->prop.cursor.hot.x = 0;
413 ee->prop.cursor.hot.y = 0;
417 ee->prop.cursor.object = obj;
418 ee->prop.cursor.layer = layer;
419 ee->prop.cursor.hot.x = hot_x;
420 ee->prop.cursor.hot.y = hot_y;
421 evas_pointer_output_xy_get(ee->evas, &x, &y);
422 evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
423 evas_object_move(ee->prop.cursor.object,
424 x - ee->prop.cursor.hot.x,
425 y - ee->prop.cursor.hot.y);
426 evas_object_pass_events_set(ee->prop.cursor.object, 1);
427 if (evas_pointer_inside_get(ee->evas))
428 evas_object_show(ee->prop.cursor.object);
430 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
434 _ecore_evas_fullscreen_set(Ecore_Evas *ee, int on)
437 Ecore_Fb_Input_Device *dev;
440 if (((ee->prop.fullscreen) && (on)) ||
441 ((!ee->prop.fullscreen) && (!on))) return;
446 ee->engine.fb.real_w = ee->w;
447 ee->engine.fb.real_h = ee->h;
450 ecore_fb_size_get(&w, &h);
451 if ((w == 0) && (h == 0))
456 if ((w != ee->w) || (h != ee->h)) resized = 1;
461 evas_output_size_set(ee->evas, ee->w, ee->h);
462 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
463 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
467 if ((ee->engine.fb.real_w != ee->w) || (ee->engine.fb.real_h != ee->h)) resized = 1;
468 ee->w = ee->engine.fb.real_w;
469 ee->h = ee->engine.fb.real_h;
472 evas_output_size_set(ee->evas, ee->w, ee->h);
473 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
474 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
476 ee->prop.fullscreen = on;
477 EINA_LIST_FOREACH(ecore_evas_input_devices, l, dev)
478 ecore_fb_input_device_axis_size_set(dev, ee->w, ee->h);
479 /* rescale the input device area */
482 if (ee->func.fn_resize) ee->func.fn_resize(ee);
487 _ecore_evas_fb_shutdown(void)
489 _ecore_evas_init_count--;
490 if (_ecore_evas_init_count == 0)
494 for (i = 0; i < 4; i++)
496 if (ecore_evas_event_handlers[i])
497 ecore_event_handler_del(ecore_evas_event_handlers[i]);
499 ecore_fb_ts_shutdown();
500 ecore_event_evas_shutdown();
502 if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
503 return _ecore_evas_init_count;
506 static Ecore_Evas_Engine_Func _ecore_fb_engine_func =
526 _ecore_evas_move_resize,
527 _ecore_evas_rotation_set,
540 _ecore_evas_object_cursor_set,
547 _ecore_evas_fullscreen_set,
554 NULL, // profiles_set
564 NULL, // screen_geometry_get
565 NULL // screen_dpi_get
570 * @brief Create Ecore_Evas using fb backend.
571 * @param disp_name The name of the display to be used.
572 * @param rotation The rotation to be used.
573 * @param w The width of the Ecore_Evas to be created.
574 * @param h The height of the Ecore_Evas to be created.
575 * @return The new Ecore_Evas.
577 #ifdef BUILD_ECORE_EVAS_FB
579 ecore_evas_fb_new(const char *disp_name, int rotation, int w, int h)
581 Evas_Engine_Info_FB *einfo;
587 disp_name = ecore_evas_default_display;
589 rmethod = evas_render_method_lookup("fb");
590 if (!rmethod) return NULL;
592 if (!ecore_fb_init(disp_name)) return NULL;
593 ecore_fb_callback_gain_set(_ecore_evas_fb_gain, NULL);
594 ecore_fb_callback_lose_set(_ecore_evas_fb_lose, NULL);
595 ee = calloc(1, sizeof(Ecore_Evas));
596 if (!ee) return NULL;
598 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
600 _ecore_evas_fb_init(ee, w, h);
602 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_fb_engine_func;
605 if (disp_name) ee->name = strdup(disp_name);
609 ee->rotation = rotation;
619 ee->prop.focused = 0;
620 ee->prop.borderless = 1;
621 ee->prop.override = 1;
622 ee->prop.maximized = 1;
623 ee->prop.fullscreen = 0;
624 ee->prop.withdrawn = 0;
628 ee->evas = evas_new();
629 evas_data_attach_set(ee->evas, ee);
630 evas_output_method_set(ee->evas, rmethod);
632 if ((rotation == 90) || (rotation == 270))
634 evas_output_size_set(ee->evas, h, w);
635 evas_output_viewport_set(ee->evas, 0, 0, h, w);
639 evas_output_size_set(ee->evas, w, h);
640 evas_output_viewport_set(ee->evas, 0, 0, w, h);
643 einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
644 if (einfo && disp_name)
646 einfo->info.virtual_terminal = 0;
647 einfo->info.device_number = strtol(disp_name, NULL, 10);
648 einfo->info.refresh = 0;
649 einfo->info.rotation = ee->rotation;
650 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
652 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
659 ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
664 ecore_evas_input_event_register(ee);
666 ee->engine.func->fn_render = _ecore_evas_fb_render;
667 _ecore_evas_register(ee);
668 ecore_event_window_register(1, ee, ee->evas,
669 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
670 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
671 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
672 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
674 evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
679 ecore_evas_fb_new(const char *disp_name __UNUSED__, int rotation __UNUSED__, int w __UNUSED__, int h __UNUSED__)