9 #include "ecore_private.h"
10 #ifdef BUILD_ECORE_EVAS_FB
12 #include <ecore_fb_private.h>
15 #include "ecore_evas_private.h"
16 #include "Ecore_Evas.h"
18 #ifdef BUILD_ECORE_EVAS_FB
19 static int _ecore_evas_init_count = 0;
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};
26 _ecore_evas_mouse_move_process_fb(Ecore_Evas *ee, int x, int y, unsigned int timestamp)
32 ecore_fb_size_get(&fbw, &fbh);
33 if (ee->prop.cursor.object)
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);
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);
63 static Ecore_Evas *fb_ee = NULL;
66 _ecore_evas_fb_match(void)
72 _ecore_evas_fb_lose(void *data __UNUSED__)
75 Ecore_Fb_Input_Device *dev;
77 if (fb_ee) fb_ee->visible = 0;
79 EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
80 ecore_fb_input_device_listen(dev, 0);
84 _ecore_evas_fb_gain(void *data __UNUSED__)
88 Ecore_Fb_Input_Device *dev;
95 if ((ee->rotation == 90) || (ee->rotation == 270))
96 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
98 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
101 EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
102 ecore_fb_input_device_listen(dev, 1);
106 _ecore_evas_event_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
109 Ecore_Fb_Event_Key_Down *e;
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 */
119 _ecore_evas_event_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
122 Ecore_Fb_Event_Key_Up *e;
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 */
132 _ecore_evas_event_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
135 Ecore_Fb_Event_Mouse_Button_Down *e;
136 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
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 */
149 _ecore_evas_event_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
152 Ecore_Fb_Event_Mouse_Button_Up *e;
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 */
163 _ecore_evas_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
166 Ecore_Fb_Event_Mouse_Move *e;
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 */
176 _ecore_evas_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
179 Ecore_Fb_Event_Mouse_Wheel *e;
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 */
190 _ecore_evas_fb_render(Ecore_Evas *ee)
198 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
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)
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);
211 updates = evas_render_updates(ee->evas);
214 evas_render_updates_free(updates);
215 _ecore_evas_idle_timeout_update(ee);
218 if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
221 evas_norender(ee->evas);
227 _ecore_evas_fb_init(int w, int h)
229 Ecore_Fb_Input_Device *device;
230 Ecore_Fb_Input_Device_Cap caps;
231 int mouse_handled = 0;
232 int keyboard_handled = 0;
235 struct dirent *input_entry;
237 _ecore_evas_init_count++;
238 if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
240 /* register all input devices */
241 input_dir = opendir("/dev/input/");
242 if (!input_dir) return _ecore_evas_init_count;
244 while ((input_entry = readdir(input_dir)))
246 char device_path[256];
248 if (strncmp(input_entry->d_name, "event", 5) != 0)
251 snprintf(device_path, 256, "/dev/input/%s", input_entry->d_name);
252 if (!(device = ecore_fb_input_device_open(device_path)))
255 caps = ecore_fb_input_device_cap_get(device);
259 if (caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE)
261 if ((caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE) || (caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
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);
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);
277 else if ((caps & ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS) && !(caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
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)
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;
293 if (ecore_fb_ts_init())
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);
301 return _ecore_evas_init_count;
305 _ecore_evas_fb_free(Ecore_Evas *ee)
307 if (fb_ee == ee) fb_ee = NULL;
308 _ecore_evas_fb_shutdown();
313 _ecore_evas_resize(Ecore_Evas *ee, int w, int h)
315 if ((w == ee->w) && (h == ee->h)) return;
318 if ((ee->rotation == 90) || (ee->rotation == 270))
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);
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);
330 if (ee->func.fn_resize) ee->func.fn_resize(ee);
334 _ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
336 if ((w == ee->w) && (h == ee->h)) return;
339 if ((ee->rotation == 90) || (ee->rotation == 270))
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);
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);
351 if (ee->func.fn_resize) ee->func.fn_resize(ee);
355 _ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize __UNUSED__)
357 Evas_Engine_Info_FB *einfo;
360 if (ee->rotation == rotation) return;
361 einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
363 rot_dif = ee->rotation - rotation;
364 if (rot_dif < 0) rot_dif = -rot_dif;
368 einfo->info.rotation = rotation;
369 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
371 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
373 if (!ee->prop.fullscreen)
383 if ((rotation == 0) || (rotation == 180))
385 evas_output_size_set(ee->evas, ee->w, ee->h);
386 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
390 evas_output_size_set(ee->evas, ee->h, ee->w);
391 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
394 ee->rotation = rotation;
398 einfo->info.rotation = rotation;
399 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
401 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
403 ee->rotation = rotation;
405 if ((ee->rotation == 90) || (ee->rotation == 270))
406 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
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);
414 _ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
420 ee->prop.cursor.object = NULL;
424 _ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
428 if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
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;
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);
452 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
456 _ecore_evas_fullscreen_set(Ecore_Evas *ee, int on)
459 Ecore_Fb_Input_Device *dev;
462 if (((ee->prop.fullscreen) && (on)) ||
463 ((!ee->prop.fullscreen) && (!on))) return;
468 ee->engine.fb.real_w = ee->w;
469 ee->engine.fb.real_h = ee->h;
472 ecore_fb_size_get(&w, &h);
473 if ((w == 0) && (h == 0))
478 if ((w != ee->w) || (h != ee->h)) resized = 1;
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);
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);
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 */
500 if (ee->func.fn_resize) ee->func.fn_resize(ee);
505 _ecore_evas_fb_shutdown(void)
507 _ecore_evas_init_count--;
508 if (_ecore_evas_init_count == 0)
512 for (i = 0; i < 6; i++)
514 if (ecore_evas_event_handlers[i])
515 ecore_event_handler_del(ecore_evas_event_handlers[i]);
517 ecore_fb_ts_shutdown();
519 if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
520 return _ecore_evas_init_count;
523 static Ecore_Evas_Engine_Func _ecore_fb_engine_func =
543 _ecore_evas_move_resize,
544 _ecore_evas_rotation_set,
557 _ecore_evas_object_cursor_set,
564 _ecore_evas_fullscreen_set,
579 * FIXME: To be fixed.
581 #ifdef BUILD_ECORE_EVAS_FB
583 ecore_evas_fb_new(const char *disp_name, int rotation, int w, int h)
585 Evas_Engine_Info_FB *einfo;
591 disp_name = ecore_evas_default_display;
593 rmethod = evas_render_method_lookup("fb");
594 if (!rmethod) return NULL;
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;
602 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
604 _ecore_evas_fb_init(w, h);
606 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_fb_engine_func;
609 if (disp_name) ee->name = strdup(disp_name);
613 ee->rotation = rotation;
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;
630 ee->evas = evas_new();
631 evas_data_attach_set(ee->evas, ee);
632 evas_output_method_set(ee->evas, rmethod);
634 if ((rotation == 90) || (rotation == 270))
636 evas_output_size_set(ee->evas, h, w);
637 evas_output_viewport_set(ee->evas, 0, 0, h, w);
641 evas_output_size_set(ee->evas, w, h);
642 evas_output_viewport_set(ee->evas, 0, 0, w, h);
645 einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
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))
654 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
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");
667 ee->engine.func->fn_render = _ecore_evas_buffer_render;
668 _ecore_evas_register(ee);
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);
678 ecore_evas_fb_new(const char *disp_name __UNUSED__, int rotation __UNUSED__, int w __UNUSED__, int h __UNUSED__)