#ifdef HAVE_CONFIG_H # include "elementary_config.h" #endif #include #include #define EFL_INTERNAL_UNSTABLE #include "Evas_Internal.h" #define DEFAULT_TEXT "Click the white rectangle to get started" typedef struct { int down; Eo *evdown, *evup, *evmove, *evkeydown, *evkeyup; Eo *win, *button, *text; int id; Eina_Future *f; } testdata; static void _pointer_down(void *data, const Efl_Event *ev) { testdata *td = data; td->down = 1; efl_unref(td->evdown); td->evdown = efl_duplicate(ev->info); } static void _pointer_move(void *data, const Efl_Event *ev) { testdata *td = data; efl_unref(td->evmove); td->evmove = efl_duplicate(ev->info); } static void _pointer_up(void *data, const Efl_Event *ev) { testdata *td = data; td->down = 0; efl_unref(td->evup); td->evup = efl_duplicate(ev->info); } static void _key_down(void *data, const Efl_Event *ev) { testdata *td = data; char str[1024]; // FIXME: By default the elm_win object is the focused object // this means that evas callbacks will transfer the KEY_UP/KEY_DOWN events // to the elm_win. So, we get two key_down & two key_up events: // 1. ecore_evas -> evas -> elm_win forward -> here // 2. ecore_evas -> evas -> focused obj (elm_win) -> here sprintf(str, "key=%s keyname=%s string=%s compose=%s", efl_input_key_sym_get(ev->info), efl_input_key_name_get(ev->info), efl_input_key_string_get(ev->info), efl_input_key_compose_string_get(ev->info)); elm_object_text_set(td->text, str); if (!efl_input_fake_get(ev->info)) { efl_unref(td->evkeydown); td->evkeydown = efl_duplicate(ev->info); } } static Eina_Value _ecore_timeout_cb(void *data, const Eina_Value t, const Eina_Future *dead EINA_UNUSED) { testdata *td = data; elm_object_text_set(td->text, DEFAULT_TEXT); td->f = NULL; return t; } static void _key_up(void *data, const Efl_Event *ev) { testdata *td = data; if (!efl_input_fake_get(ev->info)) { efl_unref(td->evkeyup); td->evkeyup = efl_duplicate(ev->info); } if (td->f) eina_future_cancel(td->f); td->f = efl_loop_timeout(efl_provider_find(ev->object, EFL_LOOP_CLASS), 0.5); eina_future_then(td->f, _ecore_timeout_cb, td, NULL); } static void _clicked_button1(void *data, const Efl_Event *ev EINA_UNUSED) { testdata *td = data; Eo *txt = td->text; char buf[256]; // Note: can't do efl_input_fake_get(ev->info) because this is a click evt td->id++; sprintf(buf, "Button was clicked %d time%s", td->id, td->id > 1 ? "s" : ""); elm_object_text_set(txt, buf); } static void _clicked_button2(void *data, const Efl_Event *ev EINA_UNUSED) { testdata *td = data; Eo *bt = td->button; Eina_Rect r; if (!td->evkeyup) { r = efl_gfx_entity_geometry_get(bt); r.x = r.x + r.w / 2; r.y = r.y + r.h / 2; efl_input_pointer_position_set(td->evmove, r.pos); efl_input_pointer_position_set(td->evdown, r.pos); efl_input_pointer_position_set(td->evup, r.pos); efl_event_callback_call(td->win, EFL_EVENT_POINTER_MOVE, td->evmove); efl_event_callback_call(td->win, EFL_EVENT_POINTER_DOWN, td->evdown); efl_event_callback_call(td->win, EFL_EVENT_POINTER_UP, td->evup); } else { efl_event_callback_call(td->win, EFL_EVENT_KEY_DOWN, td->evkeydown); efl_event_callback_call(td->win, EFL_EVENT_KEY_UP, td->evkeyup); efl_unref(td->evkeydown); efl_unref(td->evkeyup); td->evkeydown = NULL; td->evkeyup = NULL; } } static void _win_del(void *data, const Efl_Event *ev EINA_UNUSED) { testdata *td = data; efl_unref(td->evdown); efl_unref(td->evup); efl_unref(td->evmove); efl_unref(td->evkeydown); efl_unref(td->evkeyup); free(td); } static void _button_pointer_down(void *data, const Efl_Event *ev) { if (((intptr_t) data) != 0x1) abort(); printf("Button raw event: DOWN. Fake = %d\n", efl_input_fake_get(ev->info)); fflush(stdout); } static void _button_pointer_up(void *data, const Efl_Event *ev) { if (((intptr_t) data) != 0x1) abort(); printf("Button raw event: UP. Fake = %d\n", efl_input_fake_get(ev->info)); fflush(stdout); } EFL_CALLBACKS_ARRAY_DEFINE(rect_pointer_callbacks, { EFL_EVENT_POINTER_DOWN, _pointer_down }, { EFL_EVENT_POINTER_MOVE, _pointer_move }, { EFL_EVENT_POINTER_UP, _pointer_up }) EFL_CALLBACKS_ARRAY_DEFINE(win_key_callbacks, { EFL_EVENT_KEY_DOWN, _key_down }, { EFL_EVENT_KEY_UP, _key_up }) EFL_CALLBACKS_ARRAY_DEFINE(button_pointer_callbacks, { EFL_EVENT_POINTER_DOWN, _button_pointer_down }, { EFL_EVENT_POINTER_UP, _button_pointer_up }) void test_events(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { /* test fake POINTER and KEY events */ Evas_Object *bx, *bt, *txt, *o, *win; testdata *td = calloc(1, sizeof(*td)); win = elm_win_util_standard_add("buttons", "Buttons"); elm_win_autodel_set(win, EINA_TRUE); bx = efl_add(EFL_UI_BOX_CLASS, win, efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_VERTICAL)); efl_content_set(win, bx); td->win = win; txt = elm_label_add(win); evas_object_size_hint_weight_set(txt, EVAS_HINT_EXPAND, 0); evas_object_size_hint_align_set(txt, -1, -1); efl_pack(bx, txt); elm_object_text_set(txt, DEFAULT_TEXT); evas_object_show(txt); td->text = txt; bt = elm_button_add(win); evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0); evas_object_size_hint_align_set(bt, -1, -1); elm_object_text_set(bt, "Click me!"); efl_pack(bx, bt); evas_object_show(bt); td->button = bt; bt = elm_button_add(win); evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0); evas_object_size_hint_align_set(bt, -1, -1); elm_object_text_set(bt, "Send fake event"); efl_pack(bx, bt); evas_object_show(bt); o = efl_add(EFL_CANVAS_RECTANGLE_CLASS, win); efl_pack(bx, o); efl_event_callback_add(td->button, EFL_INPUT_EVENT_CLICKED, _clicked_button1, td); efl_event_callback_array_add(td->button, button_pointer_callbacks(), (void*)(intptr_t)0x1); efl_event_callback_add(bt, EFL_INPUT_EVENT_CLICKED, _clicked_button2, td); efl_event_callback_add(win, EFL_EVENT_DEL, _win_del, td); efl_event_callback_array_add(o, rect_pointer_callbacks(), td); efl_event_callback_array_add(win, win_key_callbacks(), td); evas_object_resize(td->win, 200, 100); evas_object_show(td->win); }