From 2f1fb38e386c0a74ad5d395571995ffb0ee4ef2d Mon Sep 17 00:00:00 2001 From: Guilherme Iscaro Date: Tue, 6 Dec 2016 16:38:47 -0200 Subject: Evas: Add event filter example. This example exercises the new seat event filter API. --- src/examples/evas/.gitignore | 1 + src/examples/evas/Makefile.am | 6 + src/examples/evas/evas-event-filter.c | 277 ++++++++++++++++++++++++++++++++++ 3 files changed, 284 insertions(+) create mode 100644 src/examples/evas/evas-event-filter.c diff --git a/src/examples/evas/.gitignore b/src/examples/evas/.gitignore index ae8e78e9c5..df145d0821 100644 --- a/src/examples/evas/.gitignore +++ b/src/examples/evas/.gitignore @@ -19,6 +19,7 @@ /evas_aspect_hints /evas_box /evas_buffer_simple +/evas_event_filter /evas_canvas3d_aabb /evas_canvas3d_blending /evas_canvas3d_colorpick diff --git a/src/examples/evas/Makefile.am b/src/examples/evas/Makefile.am index c4d155d356..c4ed9dea01 100644 --- a/src/examples/evas/Makefile.am +++ b/src/examples/evas/Makefile.am @@ -119,6 +119,11 @@ evas_events_SOURCES = evas-events.c evas_events_LDADD = $(ECORE_EVAS_COMMON_LDADD) evas_events_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS) +EXTRA_PROGRAMS += evas_event_filter +evas_event_filter_SOURCES = evas-event-filter.c +evas_event_filter_LDADD = $(ECORE_EVAS_COMMON_LDADD) +evas_event_filter_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS) + EXTRA_PROGRAMS += evas_multiseat_events evas_multiseat_events_SOURCES = evas-multiseat-events.c evas_multiseat_events_LDADD = $(ECORE_EVAS_COMMON_LDADD) @@ -369,6 +374,7 @@ evas-aspect-hints.c \ evas-box.c \ evas-buffer-simple.c \ evas-events.c \ +evas-event-filter.c \ evas-hints.c \ evas-images.c \ evas-images2.c \ diff --git a/src/examples/evas/evas-event-filter.c b/src/examples/evas/evas-event-filter.c new file mode 100644 index 0000000000..aa41d8ec71 --- /dev/null +++ b/src/examples/evas/evas-event-filter.c @@ -0,0 +1,277 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#define W (300) +#define H (300) +#define RECT_W (50) +#define RECT_H (50) + +typedef struct _Context { + Evas_Object *filtered_obj; + Efl_Input_Device *allowed_seat; +} Context; + +static void +_ee_del_request_cb(Ecore_Evas *ee EINA_UNUSED) +{ + ecore_main_loop_quit(); +} + +static void +_ee_resize_cb(Ecore_Evas *ee) +{ + Evas_Object *bg; + int w, h; + + ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); + bg = ecore_evas_data_get(ee, "bg"); + evas_object_resize(bg, w, h); +} + +static Eina_Bool +_allowed_seat_get(Evas_Object *filtered_obj, + Efl_Input_Device **allowed_seat) +{ + const Eina_List *devs, *l; + Efl_Input_Device *seat; + Eina_Bool allowed_seat_changed = EINA_FALSE; + + if (!filtered_obj) return EINA_TRUE; + + devs = evas_device_list(evas_object_evas_get(filtered_obj), NULL); + EINA_LIST_FOREACH(devs, l, seat) + { + if ((efl_input_device_type_get(seat) != EFL_INPUT_DEVICE_CLASS_SEAT) || + (*allowed_seat == seat)) + continue; + if (!allowed_seat_changed) + { + printf("The '%s' shall only receive events from seat '%s'\n", + evas_object_name_get(filtered_obj), + efl_input_device_name_get(seat)); + allowed_seat_changed = EINA_TRUE; + *allowed_seat = seat; + efl_input_seat_event_filter_set(filtered_obj, seat, EINA_TRUE); + if (!efl_canvas_object_seat_focus_add(filtered_obj, seat)) + { + fprintf(stderr, "ERROR: The '%s' could not be focused by the seat '%s'\n", + evas_object_name_get(filtered_obj), + efl_input_device_name_get(seat)); + return EINA_FALSE; + } + } + else + { + if (efl_canvas_object_seat_focus_add(filtered_obj, seat)) + { + fprintf(stderr, "ERROR: The '%s' should not be focused by the seat '%s'\n", + evas_object_name_get(filtered_obj), + efl_input_device_name_get(seat)); + return EINA_FALSE; + } + } + } + if (!allowed_seat_changed) + *allowed_seat = NULL; + return EINA_TRUE; +} + +static const char * +_event_as_string(const void *desc) +{ + if (desc == EFL_EVENT_FOCUS_IN) + return "FOCUS_IN"; + else if (desc == EFL_EVENT_FOCUS_OUT) + return "FOCUS_OUT"; + else if (desc == EFL_EVENT_KEY_DOWN) + return "KEY_DOWN"; + else if (desc == EFL_EVENT_KEY_UP) + return "KEY_UP"; + else if (desc == EFL_EVENT_HOLD) + return "HOLD"; + else if (desc == EFL_EVENT_POINTER_IN) + return "POINTER_IN"; + else if (desc == EFL_EVENT_POINTER_OUT) + return "POINTER_OUT"; + else if (desc == EFL_EVENT_POINTER_DOWN) + return "POINTER_DOWN"; + else if (desc == EFL_EVENT_POINTER_UP) + return "POINTER_UP"; + else if (desc == EFL_EVENT_POINTER_MOVE) + return "POINTER_MOVE"; + else + return "MOUSE_WHEEL"; +} + +static void +_obj_events_cb(void *data, const Efl_Event *event) +{ + Efl_Input_Device *seat = efl_input_device_seat_get(efl_input_device_get(event->info)); + Context *ctx = data; + const char *event_name; + + event_name = _event_as_string(event->desc); + if (seat != ctx->allowed_seat && event->object == ctx->filtered_obj) + { + fprintf(stderr, "ERROR: The object '%s' should not receive the event" + "'%s' from the seat '%s'\n", + evas_object_name_get(event->object), event_name, + efl_input_device_name_get(seat)); + ecore_main_loop_quit(); + } + else + printf("The object '%s' recevied a '%s' event from seat '%s'\n", + evas_object_name_get(event->object), event_name, + efl_input_device_name_get(seat)); +} + +static void +_obj_del_event_cb(void *data, const Efl_Event *event) +{ + Context *ctx = data; + + if (event->object == ctx->filtered_obj) + ctx->filtered_obj = NULL; +} + +static void +_device_added_removed_cb(void *data, const Efl_Event *event) +{ + Efl_Input_Device *dev = event->info; + Context *ctx = data; + + if (efl_input_device_type_get(dev) != EFL_INPUT_DEVICE_CLASS_SEAT) + return; + + if (event->desc == EFL_CANVAS_EVENT_DEVICE_ADDED) + { + if (ctx->allowed_seat) + efl_input_seat_event_filter_set(ctx->filtered_obj, + ctx->allowed_seat, EINA_FALSE); + ctx->allowed_seat = dev; + } + else + { + if (!_allowed_seat_get(ctx->filtered_obj, &ctx->allowed_seat)) + ecore_main_loop_quit(); + } +} + +EFL_CALLBACKS_ARRAY_DEFINE(_device_callbacks, + { EFL_CANVAS_EVENT_DEVICE_ADDED, _device_added_removed_cb }, + { EFL_CANVAS_EVENT_DEVICE_REMOVED, _device_added_removed_cb }); + +EFL_CALLBACKS_ARRAY_DEFINE(_obj_callbacks, + { EFL_EVENT_FOCUS_IN, _obj_events_cb }, + { EFL_EVENT_FOCUS_OUT, _obj_events_cb }, + { EFL_EVENT_KEY_DOWN, _obj_events_cb }, + { EFL_EVENT_KEY_UP, _obj_events_cb }, + { EFL_EVENT_HOLD, _obj_events_cb }, + { EFL_EVENT_POINTER_IN, _obj_events_cb }, + { EFL_EVENT_POINTER_OUT,_obj_events_cb }, + { EFL_EVENT_POINTER_DOWN, _obj_events_cb }, + { EFL_EVENT_POINTER_UP, _obj_events_cb }, + { EFL_EVENT_POINTER_MOVE, _obj_events_cb }, + { EFL_EVENT_POINTER_WHEEL, _obj_events_cb }, + { EFL_EVENT_DEL, _obj_del_event_cb }); + +static Evas_Object * +_rect_add(Evas *e, Context *ctx, const char *name, + int w, int h, int x, int y, int r, int g, int b, + Eina_Bool add_callbacks) +{ + Evas_Object *obj; + + obj = evas_object_rectangle_add(e); + if (!obj) + { + fprintf(stderr, "Could not create the BG\n"); + return NULL; + } + + evas_object_color_set(obj, r, g, b, 255); + evas_object_resize(obj, w, h); + evas_object_move(obj, x, y); + evas_object_show(obj); + evas_object_name_set(obj, name); + if (add_callbacks) + efl_event_callback_array_add(obj, _obj_callbacks(), ctx); + return obj; +} + +int +main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED) +{ + Context ctx = { 0 }; + Ecore_Evas *ee; + Evas_Object *obj; + Evas *e; + + if (!ecore_evas_init()) + { + fprintf(stderr, "Could not init Ecore_Evas\n"); + return EXIT_FAILURE; + } + + ee = ecore_evas_new(NULL, 0, 0, W, H, NULL); + if (!ee) + { + fprintf(stderr, "Coult not create the Ecore_Evas\n"); + goto err_ee; + } + + e = ecore_evas_get(ee); + + obj = _rect_add(e, &ctx, "bg", W, H, 0, 0, 255, 255, 255, EINA_FALSE); + if (!obj) + { + fprintf(stderr, "Could not create the BG\n"); + goto err_obj; + } + ecore_evas_data_set(ee, "bg", obj); + + obj = _rect_add(e, &ctx, "Red Rectangle", RECT_W, RECT_H, W/2 - RECT_W/2, + H/2 - RECT_H/2, 255, 0, 0, EINA_TRUE); + if (!obj) + { + fprintf(stderr, "Could not create the red rectangle\n"); + goto err_obj; + } + ctx.filtered_obj = obj; + + obj = _rect_add(e, &ctx, "Blue Rectangle", RECT_W, RECT_H, + 100, 100, 0, 0, 255, EINA_TRUE); + if (!obj) + { + fprintf(stderr, "Could not create the blue rectangle\n"); + goto err_obj; + } + + printf("The '%s' shall receive events from any seat\n", + evas_object_name_get(obj)); + + if (!_allowed_seat_get(ctx.filtered_obj, &ctx.allowed_seat)) + goto err_obj; + efl_event_callback_array_add(e, _device_callbacks(), &ctx); + ecore_evas_callback_resize_set(ee, _ee_resize_cb); + ecore_evas_callback_delete_request_set(ee, _ee_del_request_cb); + ecore_evas_show(ee); + ecore_main_loop_begin(); + ecore_evas_free(ee); + ecore_evas_shutdown(); + return EXIT_SUCCESS; + + err_obj: + ecore_evas_free(ee); + err_ee: + ecore_evas_shutdown(); + return EXIT_FAILURE; +} + -- cgit v1.2.1