2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
13 #include "ecore_private.h"
14 #ifdef BUILD_ECORE_EVAS_FB
16 #include <ecore_fb_private.h>
19 #include "ecore_evas_private.h"
20 #include "Ecore_Evas.h"
22 #ifdef BUILD_ECORE_EVAS_FB
23 static int _ecore_evas_init_count = 0;
25 static char *ecore_evas_default_display = "0";
26 static Eina_List *ecore_evas_input_devices = NULL;
27 static Ecore_Event_Handler *ecore_evas_event_handlers[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
30 _ecore_evas_mouse_move_process_fb(Ecore_Evas *ee, int x, int y, unsigned int timestamp)
36 ecore_fb_size_get(&fbw, &fbh);
37 if (ee->prop.cursor.object)
39 evas_object_show(ee->prop.cursor.object);
40 if (ee->rotation == 0)
41 evas_object_move(ee->prop.cursor.object,
42 x - ee->prop.cursor.hot.x,
43 y - ee->prop.cursor.hot.y);
44 else if (ee->rotation == 90)
45 evas_object_move(ee->prop.cursor.object,
46 (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.x,
47 x - ee->prop.cursor.hot.y);
48 else if (ee->rotation == 180)
49 evas_object_move(ee->prop.cursor.object,
50 (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.x,
51 (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.y);
52 else if (ee->rotation == 270)
53 evas_object_move(ee->prop.cursor.object,
54 y - ee->prop.cursor.hot.x,
55 (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.y);
57 if (ee->rotation == 0)
58 evas_event_feed_mouse_move(ee->evas, x, y, timestamp, NULL);
59 else if (ee->rotation == 90)
60 evas_event_feed_mouse_move(ee->evas, (fbh - ee->h) + ee->h - y - 1, x, timestamp, NULL);
61 else if (ee->rotation == 180)
62 evas_event_feed_mouse_move(ee->evas, (fbw - ee->w) + ee->w - x - 1, (fbh - ee->h) + ee->h - y - 1, timestamp, NULL);
63 else if (ee->rotation == 270)
64 evas_event_feed_mouse_move(ee->evas, y, (fbw - ee->w) + ee->w - x - 1, timestamp, NULL);
67 static Ecore_Evas *fb_ee = NULL;
70 _ecore_evas_fb_match(void)
76 _ecore_evas_fb_lose(void *data __UNUSED__)
80 Ecore_Fb_Input_Device *dev;
82 if (fb_ee) fb_ee->visible = 0;
84 EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
85 ecore_fb_input_device_listen(dev, 0);
89 _ecore_evas_fb_gain(void *data __UNUSED__)
93 Ecore_Fb_Input_Device *dev;
100 if ((ee->rotation == 90) || (ee->rotation == 270))
101 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
103 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
106 EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
107 ecore_fb_input_device_listen(dev, 1);
111 _ecore_evas_event_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
114 Ecore_Fb_Event_Key_Down *e;
117 ee = _ecore_evas_fb_match();
118 if (!ee) return 1; /* pass on event */
119 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);
120 return 0; /* dont pass it on */
124 _ecore_evas_event_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
127 Ecore_Fb_Event_Key_Up *e;
130 ee = _ecore_evas_fb_match();
131 if (!ee) return 1; /* pass on event */
132 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);
133 return 0; /* dont pass it on */
137 _ecore_evas_event_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
140 Ecore_Fb_Event_Mouse_Button_Down *e;
141 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
144 ee = _ecore_evas_fb_match();
145 if (!ee) return 1; /* pass on event */
146 _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
147 if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
148 if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
149 evas_event_feed_mouse_down(ee->evas, e->button, flags, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
150 return 0; /* dont pass it on */
154 _ecore_evas_event_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
157 Ecore_Fb_Event_Mouse_Button_Up *e;
160 ee = _ecore_evas_fb_match();
161 if (!ee) return 1; /* pass on event */
162 _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
163 evas_event_feed_mouse_up(ee->evas, e->button, EVAS_BUTTON_NONE, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
164 return 0; /* dont pass it on */
168 _ecore_evas_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
171 Ecore_Fb_Event_Mouse_Move *e;
174 ee = _ecore_evas_fb_match();
175 if (!ee) return 1; /* pass on event */
176 _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
177 return 0; /* dont pass it on */
181 _ecore_evas_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
184 Ecore_Fb_Event_Mouse_Wheel *e;
187 ee = _ecore_evas_fb_match();
188 if (!ee) return 1; /* pass on event */
189 _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
190 return 0; /* dont pass it on */
194 _ecore_evas_fb_render(Ecore_Evas *ee)
202 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
206 if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
207 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
208 EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
210 if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
211 rend |= _ecore_evas_buffer_render(ee2);
212 if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
215 updates = evas_render_updates(ee->evas);
218 evas_render_updates_free(updates);
219 _ecore_evas_idle_timeout_update(ee);
222 if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
225 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;
294 if (ecore_fb_ts_init())
296 ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
297 ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
298 ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
302 return _ecore_evas_init_count;
306 _ecore_evas_fb_free(Ecore_Evas *ee)
308 if (fb_ee == ee) fb_ee = NULL;
309 _ecore_evas_fb_shutdown();
314 _ecore_evas_resize(Ecore_Evas *ee, int w, int h)
316 if ((w == ee->w) && (h == ee->h)) return;
319 if ((ee->rotation == 90) || (ee->rotation == 270))
321 evas_output_size_set(ee->evas, ee->h, ee->w);
322 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
323 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
327 evas_output_size_set(ee->evas, ee->w, ee->h);
328 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
329 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
331 if (ee->func.fn_resize) ee->func.fn_resize(ee);
335 _ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
337 if ((w == ee->w) && (h == ee->h)) return;
340 if ((ee->rotation == 90) || (ee->rotation == 270))
342 evas_output_size_set(ee->evas, ee->h, ee->w);
343 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
344 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
348 evas_output_size_set(ee->evas, ee->w, ee->h);
349 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
350 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
352 if (ee->func.fn_resize) ee->func.fn_resize(ee);
356 _ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize)
358 Evas_Engine_Info_FB *einfo;
361 if (ee->rotation == rotation) return;
362 einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
364 rot_dif = ee->rotation - rotation;
365 if (rot_dif < 0) rot_dif = -rot_dif;
369 einfo->info.rotation = rotation;
370 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
371 if (!ee->prop.fullscreen)
381 if ((rotation == 0) || (rotation == 180))
383 evas_output_size_set(ee->evas, ee->w, ee->h);
384 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
388 evas_output_size_set(ee->evas, ee->h, ee->w);
389 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
392 ee->rotation = rotation;
396 einfo->info.rotation = rotation;
397 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
398 ee->rotation = rotation;
400 if ((ee->rotation == 90) || (ee->rotation == 270))
401 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
403 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
404 _ecore_evas_mouse_move_process_fb(ee, ee->mouse.x, ee->mouse.y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
405 if (ee->func.fn_resize) ee->func.fn_resize(ee);
409 _ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
415 ee->prop.cursor.object = NULL;
419 _ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
423 if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
427 ee->prop.cursor.object = NULL;
428 ee->prop.cursor.layer = 0;
429 ee->prop.cursor.hot.x = 0;
430 ee->prop.cursor.hot.y = 0;
434 ee->prop.cursor.object = obj;
435 ee->prop.cursor.layer = layer;
436 ee->prop.cursor.hot.x = hot_x;
437 ee->prop.cursor.hot.y = hot_y;
438 evas_pointer_output_xy_get(ee->evas, &x, &y);
439 evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
440 evas_object_move(ee->prop.cursor.object,
441 x - ee->prop.cursor.hot.x,
442 y - ee->prop.cursor.hot.y);
443 evas_object_pass_events_set(ee->prop.cursor.object, 1);
444 if (evas_pointer_inside_get(ee->evas))
445 evas_object_show(ee->prop.cursor.object);
447 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
451 _ecore_evas_fullscreen_set(Ecore_Evas *ee, int on)
454 Ecore_Fb_Input_Device *dev;
457 if (((ee->prop.fullscreen) && (on)) ||
458 ((!ee->prop.fullscreen) && (!on))) return;
463 ee->engine.fb.real_w = ee->w;
464 ee->engine.fb.real_h = ee->h;
467 ecore_fb_size_get(&w, &h);
468 if ((w == 0) && (h == 0))
473 if ((w != ee->w) || (h != ee->h)) resized = 1;
476 evas_output_size_set(ee->evas, ee->w, ee->h);
477 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
478 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
482 if ((ee->engine.fb.real_w != ee->w) || (ee->engine.fb.real_h != ee->h)) resized = 1;
483 ee->w = ee->engine.fb.real_w;
484 ee->h = ee->engine.fb.real_h;
485 evas_output_size_set(ee->evas, ee->w, ee->h);
486 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
487 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
489 ee->prop.fullscreen = on;
490 EINA_LIST_FOREACH(ecore_evas_input_devices, l, dev)
491 ecore_fb_input_device_axis_size_set(dev, ee->w, ee->h);
492 /* rescale the input device area */
495 if (ee->func.fn_resize) ee->func.fn_resize(ee);
500 _ecore_evas_fb_shutdown(void)
502 _ecore_evas_init_count--;
503 if (_ecore_evas_init_count == 0)
507 for (i = 0; i < 6; i++)
509 if (ecore_evas_event_handlers[i])
510 ecore_event_handler_del(ecore_evas_event_handlers[i]);
512 ecore_fb_ts_shutdown();
514 if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
515 return _ecore_evas_init_count;
518 static Ecore_Evas_Engine_Func _ecore_fb_engine_func =
538 _ecore_evas_move_resize,
539 _ecore_evas_rotation_set,
552 _ecore_evas_object_cursor_set,
559 _ecore_evas_fullscreen_set,
574 * FIXME: To be fixed.
576 #ifdef BUILD_ECORE_EVAS_FB
578 ecore_evas_fb_new(const char *disp_name, int rotation, int w, int h)
580 Evas_Engine_Info_FB *einfo;
586 disp_name = ecore_evas_default_display;
588 rmethod = evas_render_method_lookup("fb");
589 if (!rmethod) return NULL;
591 if (!ecore_fb_init(disp_name)) return NULL;
592 ecore_fb_callback_gain_set(_ecore_evas_fb_gain, NULL);
593 ecore_fb_callback_lose_set(_ecore_evas_fb_lose, NULL);
594 ee = calloc(1, sizeof(Ecore_Evas));
595 if (!ee) return NULL;
597 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
599 _ecore_evas_fb_init(w, h);
601 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_fb_engine_func;
604 if (disp_name) ee->name = strdup(disp_name);
608 ee->rotation = rotation;
616 ee->prop.focused = 1;
617 ee->prop.borderless = 1;
618 ee->prop.override = 1;
619 ee->prop.maximized = 1;
620 ee->prop.fullscreen = 0;
621 ee->prop.withdrawn = 0;
625 ee->evas = evas_new();
626 evas_data_attach_set(ee->evas, ee);
627 evas_output_method_set(ee->evas, rmethod);
629 if ((rotation == 90) || (rotation == 270))
631 evas_output_size_set(ee->evas, h, w);
632 evas_output_viewport_set(ee->evas, 0, 0, h, w);
636 evas_output_size_set(ee->evas, w, h);
637 evas_output_viewport_set(ee->evas, 0, 0, w, h);
640 einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
643 einfo->info.virtual_terminal = 0;
644 einfo->info.device_number = strtol(disp_name, NULL, 10);
645 einfo->info.refresh = 0;
646 einfo->info.rotation = ee->rotation;
647 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
649 evas_key_modifier_add(ee->evas, "Shift");
650 evas_key_modifier_add(ee->evas, "Control");
651 evas_key_modifier_add(ee->evas, "Alt");
652 evas_key_modifier_add(ee->evas, "Meta");
653 evas_key_modifier_add(ee->evas, "Hyper");
654 evas_key_modifier_add(ee->evas, "Super");
655 evas_key_lock_add(ee->evas, "Caps_Lock");
656 evas_key_lock_add(ee->evas, "Num_Lock");
657 evas_key_lock_add(ee->evas, "Scroll_Lock");
659 ee->engine.func->fn_render = _ecore_evas_buffer_render;
660 _ecore_evas_register(ee);
663 evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
664 evas_focus_in(ee->evas);
670 ecore_evas_fb_new(const char *disp_name __UNUSED__, int rotation __UNUSED__, int w __UNUSED__, int h __UNUSED__)