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;
180 unsigned long long event_time;
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 */
193 _ecore_evas_fb_render(Ecore_Evas *ee)
201 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
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)
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);
214 updates = evas_render_updates(ee->evas);
217 evas_render_updates_free(updates);
218 _ecore_evas_idle_timeout_update(ee);
221 if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
224 evas_norender(ee->evas);
230 _ecore_evas_fb_init(int w, int h)
232 Ecore_Fb_Input_Device *device;
233 Ecore_Fb_Input_Device_Cap caps;
234 int mouse_handled = 0;
235 int keyboard_handled = 0;
238 struct dirent *input_entry;
240 _ecore_evas_init_count++;
241 if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
243 /* register all input devices */
244 input_dir = opendir("/dev/input/");
245 if (!input_dir) return _ecore_evas_init_count;
247 while ((input_entry = readdir(input_dir)))
249 char device_path[256];
251 if (strncmp(input_entry->d_name, "event", 5) != 0)
254 snprintf(device_path, 256, "/dev/input/%s", input_entry->d_name);
255 if (!(device = ecore_fb_input_device_open(device_path)))
258 caps = ecore_fb_input_device_cap_get(device);
262 if (caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE)
264 if ((caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE) || (caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
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);
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);
280 else if ((caps & ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS) && !(caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
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)
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;
296 if (ecore_fb_ts_init())
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);
304 return _ecore_evas_init_count;
308 _ecore_evas_fb_free(Ecore_Evas *ee)
310 if (fb_ee == ee) fb_ee = NULL;
311 _ecore_evas_fb_shutdown();
316 _ecore_evas_resize(Ecore_Evas *ee, int w, int h)
318 if ((w == ee->w) && (h == ee->h)) return;
321 if ((ee->rotation == 90) || (ee->rotation == 270))
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);
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);
333 if (ee->func.fn_resize) ee->func.fn_resize(ee);
337 _ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
339 if ((w == ee->w) && (h == ee->h)) return;
342 if ((ee->rotation == 90) || (ee->rotation == 270))
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);
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);
354 if (ee->func.fn_resize) ee->func.fn_resize(ee);
358 _ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize __UNUSED__)
360 Evas_Engine_Info_FB *einfo;
363 if (ee->rotation == rotation) return;
364 einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
366 rot_dif = ee->rotation - rotation;
367 if (rot_dif < 0) rot_dif = -rot_dif;
371 einfo->info.rotation = rotation;
372 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
374 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
376 if (!ee->prop.fullscreen)
386 if ((rotation == 0) || (rotation == 180))
388 evas_output_size_set(ee->evas, ee->w, ee->h);
389 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
393 evas_output_size_set(ee->evas, ee->h, ee->w);
394 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
397 ee->rotation = rotation;
401 einfo->info.rotation = rotation;
402 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
404 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
406 ee->rotation = rotation;
408 if ((ee->rotation == 90) || (ee->rotation == 270))
409 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
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);
417 _ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
423 ee->prop.cursor.object = NULL;
427 _ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
431 if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
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;
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);
455 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
459 _ecore_evas_fullscreen_set(Ecore_Evas *ee, int on)
462 Ecore_Fb_Input_Device *dev;
465 if (((ee->prop.fullscreen) && (on)) ||
466 ((!ee->prop.fullscreen) && (!on))) return;
471 ee->engine.fb.real_w = ee->w;
472 ee->engine.fb.real_h = ee->h;
475 ecore_fb_size_get(&w, &h);
476 if ((w == 0) && (h == 0))
481 if ((w != ee->w) || (h != ee->h)) resized = 1;
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);
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);
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 */
503 if (ee->func.fn_resize) ee->func.fn_resize(ee);
508 _ecore_evas_fb_shutdown(void)
510 _ecore_evas_init_count--;
511 if (_ecore_evas_init_count == 0)
515 for (i = 0; i < 6; i++)
517 if (ecore_evas_event_handlers[i])
518 ecore_event_handler_del(ecore_evas_event_handlers[i]);
520 ecore_fb_ts_shutdown();
522 if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
523 return _ecore_evas_init_count;
526 static Ecore_Evas_Engine_Func _ecore_fb_engine_func =
546 _ecore_evas_move_resize,
547 _ecore_evas_rotation_set,
560 _ecore_evas_object_cursor_set,
567 _ecore_evas_fullscreen_set,
582 * FIXME: To be fixed.
584 #ifdef BUILD_ECORE_EVAS_FB
586 ecore_evas_fb_new(const char *disp_name, int rotation, int w, int h)
588 Evas_Engine_Info_FB *einfo;
594 disp_name = ecore_evas_default_display;
596 rmethod = evas_render_method_lookup("fb");
597 if (!rmethod) return NULL;
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;
605 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
607 _ecore_evas_fb_init(w, h);
609 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_fb_engine_func;
612 if (disp_name) ee->name = strdup(disp_name);
616 ee->rotation = rotation;
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;
633 ee->evas = evas_new();
634 evas_data_attach_set(ee->evas, ee);
635 evas_output_method_set(ee->evas, rmethod);
637 if ((rotation == 90) || (rotation == 270))
639 evas_output_size_set(ee->evas, h, w);
640 evas_output_viewport_set(ee->evas, 0, 0, h, w);
644 evas_output_size_set(ee->evas, w, h);
645 evas_output_viewport_set(ee->evas, 0, 0, w, h);
648 einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
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))
657 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
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");
670 ee->engine.func->fn_render = _ecore_evas_buffer_render;
671 _ecore_evas_register(ee);
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);
681 ecore_evas_fb_new(const char *disp_name __UNUSED__, int rotation __UNUSED__, int w __UNUSED__, int h __UNUSED__)