From 7ef5f6c3a0a6893552a7f13aa2777e3b9480e343 Mon Sep 17 00:00:00 2001 From: Bruno Dilly Date: Thu, 3 Nov 2016 19:10:51 -0200 Subject: [PATCH] examples/edje: add multiseat example --- src/examples/edje/.gitignore | 1 + src/examples/edje/Makefile.am | 3 + src/examples/edje/edje-multiseat.c | 211 +++++++++++ src/examples/edje/multiseat.edc | 740 +++++++++++++++++++++++++++++++++++++ 4 files changed, 955 insertions(+) create mode 100644 src/examples/edje/edje-multiseat.c create mode 100644 src/examples/edje/multiseat.edc diff --git a/src/examples/edje/.gitignore b/src/examples/edje/.gitignore index 5b5f5f0..a10bdf9 100644 --- a/src/examples/edje/.gitignore +++ b/src/examples/edje/.gitignore @@ -11,6 +11,7 @@ /edje-drag /edje-edit-part-box /edje-entry +/edje-multiseat /edje-multisense /edje-perspective /edje-signals-messages diff --git a/src/examples/edje/Makefile.am b/src/examples/edje/Makefile.am index 7dff1e3..6198ccf 100644 --- a/src/examples/edje/Makefile.am +++ b/src/examples/edje/Makefile.am @@ -43,6 +43,7 @@ external_elm_panes.edc \ external_emotion_elm.edc \ lua_script.edc \ messages_echo.edc \ +multiseat.edc \ perspective.edc \ signals-messages.edc \ signalsBubble.edc \ @@ -140,6 +141,7 @@ edje-color-class.c \ edje-drag.c \ edje-edit-part-box.c \ edje-entry.c \ +edje-multiseat.c \ edje-multisense.c \ edje-perspective.c \ edje-signals-messages.c \ @@ -213,6 +215,7 @@ edje-color-class \ edje-drag\ edje-edit-part-box \ edje-entry \ +edje-multiseat \ edje-perspective \ edje-signals-messages \ edje-swallow \ diff --git a/src/examples/edje/edje-multiseat.c b/src/examples/edje/edje-multiseat.c new file mode 100644 index 0000000..4fbc77c --- /dev/null +++ b/src/examples/edje/edje-multiseat.c @@ -0,0 +1,211 @@ +/** + * Edje example demonstrating how to use multiseat features. + * + * You'll need at least one Evas engine built for it (excluding the + * buffer one) that supports multiseat. It may be wayland or + * X11 with VNC support. Using other engines will lead you to a + * situation where all seats are reported as the same one ("default"). + * + * @verbatim + * edje_cc multiseat.edc && gcc -o edje-multiseat edje-multiseat.c `pkg-config --libs --cflags evas ecore ecore-evas edje` + * @endverbatim + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#else +# define EINA_UNUSED +#endif + +#ifndef PACKAGE_DATA_DIR +#define PACKAGE_DATA_DIR "." +#endif + +#include +#include +#include + +#define WIDTH 400 +#define HEIGHT 400 + +static const char *GROUPNAME = "example/main"; +static const char *PARTNAME_KNOB1 = "example/knob1"; +static const char *PARTNAME_KNOB2 = "example/knob2"; + +static void +_on_destroy(Ecore_Evas *ee EINA_UNUSED) +{ + ecore_main_loop_quit(); +} + +static void +_on_canvas_resize(Ecore_Evas *ee) +{ + Evas_Object *bg; + Evas_Object *edje_obj; + int w, h; + + bg = ecore_evas_data_get(ee, "background"); + edje_obj = ecore_evas_data_get(ee, "edje_obj"); + + ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); + evas_object_resize(bg, w, h); + evas_object_resize(edje_obj, w, h); +} + +static void +_on_key_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o, void *event_info) +{ + Evas_Event_Key_Down *ev = event_info; + Efl_Input_Device *seat; + + seat = efl_input_device_seat_get(ev->dev); + printf("Seat %s (%s) pressed key %s\n", efl_input_device_name_get(seat), + edje_obj_seat_name_get(o, seat), ev->key); +} + +static void +_on_drag_started(void *data EINA_UNUSED, Evas_Object *o, const char *emission, const char *source) +{ + Eina_Stringshare *seat_name; + const char *seat_name_str; + Efl_Input_Device *seat; + + seat_name_str = emission + strlen("drag,start,"); + seat_name = eina_stringshare_add(seat_name_str); + seat = edje_obj_seat_get(o, seat_name); + printf("Seat %s (%s) started drag %s\n", efl_input_device_name_get(seat), + seat_name, source); + eina_stringshare_del(seat_name); +} + +static void +_setup_drag(Evas_Object *edje_obj, const char *partname) +{ + if (!edje_object_part_drag_size_set(edje_obj, partname, 1.0, 0.4)) + printf("error when setting drag size.\n"); + + if (!edje_object_part_drag_step_set(edje_obj, partname, 0.0, 0.1)) + printf("error when setting drag step size.\n"); + + if (!edje_object_part_drag_page_set(edje_obj, partname, 0.0, 0.3)) + printf("error when setting drag page step size.\n"); + + edje_object_signal_callback_add(edje_obj, "drag,start,*", partname, + _on_drag_started, NULL); +} + +static void +_edje_load_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED) +{ + printf("Edje loaded\n"); +} + +static void +_edje_seat_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, const char *emission, const char *source EINA_UNUSED) +{ + const char *sig; + + sig = emission + strlen("seat,"); + printf("Device %s\n", sig); +} + +static void +_device_added(void *data, const Efl_Event *event) +{ + Efl_Input_Device *dev = event->info; + Evas_Object *edje_obj = data; + + if (efl_input_device_type_get(dev) != EFL_INPUT_DEVICE_CLASS_SEAT) + return; + + efl_canvas_object_seat_focus_add(edje_obj, dev); +} + +int +main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED) +{ + const char *edje_file = PACKAGE_DATA_DIR"/multiseat.edj"; + const Eina_List *devices, *l; + Evas_Object *edje_obj, *bg; + Efl_Input_Device *dev; + Ecore_Evas *ee; + Evas *evas; + + if (!ecore_evas_init()) + return EXIT_FAILURE; + + if (!edje_init()) + goto shutdown_ecore_evas; + + ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL); + if (!ee) goto shutdown_edje; + + ecore_evas_callback_destroy_set(ee, _on_destroy); + ecore_evas_callback_resize_set(ee, _on_canvas_resize); + ecore_evas_title_set(ee, "Edje Multiseat Example"); + + evas = ecore_evas_get(ee); + + bg = evas_object_rectangle_add(evas); + evas_object_color_set(bg, 255, 255, 255, 255); + evas_object_resize(bg, WIDTH, HEIGHT); + evas_object_show(bg); + ecore_evas_data_set(ee, "background", bg); + + edje_obj = edje_object_add(evas); + + if (!edje_object_file_set(edje_obj, edje_file, GROUPNAME)) + printf("failed to set file %s.\n", edje_file); + + evas_object_move(edje_obj, 0, 0); + evas_object_resize(edje_obj, WIDTH, HEIGHT); + evas_object_show(edje_obj); + ecore_evas_data_set(ee, "edje_obj", edje_obj); + + _setup_drag(edje_obj, PARTNAME_KNOB1); + _setup_drag(edje_obj, PARTNAME_KNOB2); + + edje_object_part_text_set(edje_obj, "example/text1", "Type here : "); + edje_object_part_text_cursor_end_set(edje_obj, "example/text1", + EDJE_CURSOR_MAIN); + + edje_object_part_text_set(edje_obj, "example/text2", "Or maybe here : "); + edje_object_part_text_cursor_end_set(edje_obj, "example/text2", + EDJE_CURSOR_MAIN); + + devices = evas_device_list(evas, NULL); + EINA_LIST_FOREACH(devices, l, dev) + { + if (efl_input_device_type_get(dev) == EFL_INPUT_DEVICE_CLASS_SEAT) + efl_canvas_object_seat_focus_add(edje_obj, dev); + + } + efl_event_callback_add(evas, EFL_CANVAS_EVENT_DEVICE_ADDED, + _device_added, edje_obj); + evas_object_event_callback_add(edje_obj, EVAS_CALLBACK_KEY_DOWN, + _on_key_down, NULL); + edje_object_signal_callback_add(edje_obj, "seat,*", "", + _edje_seat_cb, NULL); + edje_object_signal_callback_add(edje_obj, "load", "", + _edje_load_cb, NULL); + + printf("Running example on evas engine %s\n", + ecore_evas_engine_name_get(ee)); + ecore_evas_show(ee); + + ecore_main_loop_begin(); + + ecore_evas_free(ee); + ecore_evas_shutdown(); + edje_shutdown(); + + return EXIT_SUCCESS; + +shutdown_edje: + edje_shutdown(); +shutdown_ecore_evas: + ecore_evas_shutdown(); + + return EXIT_FAILURE; +} diff --git a/src/examples/edje/multiseat.edc b/src/examples/edje/multiseat.edc new file mode 100644 index 0000000..aa16309 --- /dev/null +++ b/src/examples/edje/multiseat.edc @@ -0,0 +1,740 @@ +collections { + + styles { + style { + name: "entry_style"; + base: "font="sans" font_size=10 color=#000 wrap="word" left_margin=2 right_margin=2"; + } + } + + group { + name: "example/main"; + min: 400 400; + + parts { + part { + name: "bg"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + } + } + + part { + name: "title"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1 { + relative: 0.0 0.0; + offset: 0 0; + to: "bg"; + } + rel2 { + relative: 1.0 0.2; + offset: -1 -1; + to: "bg"; + } + text { + text: "Multiseat Example"; + size: 16; + font: "sans"; + min: 1 1; + } + } + } + + part { + name: "drag_area1"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1 { + relative: 0.1 0.25; + offset: -5 0; + } + rel2 { + relative: 0.1 0.9; + offset: 4 0; + } + } + } + + part { + name: "example/knob1"; + type: RECT; + mouse_events: 1; + dragable { + confine: "drag_area1"; + x: 0 0 0; + y: 1 1 0; + } + description { + state: "default" 0.0; + min: 10 10; + color: 200 200 200 255; + } + description { + state: "focused,s1" 0.0; + inherit: "default" 0.0; + color: 200 0 0 255; + } + description { + state: "focused,s2" 0.0; + inherit: "default" 0.0; + color: 0 200 0 255; + } + } + + part { + name: "drag_area2"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1 { + relative: 0.2 0.25; + offset: -5 0; + } + rel2 { + relative: 0.2 0.9; + offset: 4 0; + } + } + } + + part { + name: "example/knob2"; + type: RECT; + mouse_events: 1; + dragable { + confine: "drag_area2"; + x: 0 0 0; + y: 1 1 0; + } + description { + state: "default" 0.0; + min: 10 10; + color: 200 200 200 255; + } + description { + state: "focused,s1" 0.0; + inherit: "default" 0.0; + color: 200 0 0 255; + } + description { + state: "focused,s2" 0.0; + inherit: "default" 0.0; + color: 0 200 0 255; + } + } + + part { + name: "bg_text1"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + min: 10 50; + rel1.relative: 0.3 0.25; + rel2.relative: 0.9 0.4; + color: 200 200 200 255; + } + description { + state: "focused,s1" 0.0; + inherit: "default" 0.0; + color: 200 0 0 255; + } + description { + state: "focused,s2" 0.0; + inherit: "default" 0.0; + color: 0 200 0 255; + } + } + + part { + name: "example/text1"; + type: TEXTBLOCK; + scale: 1; + entry_mode: EDITABLE; + select_mode: DEFAULT; + cursor_mode: UNDER; + mouse_events: 1; + multiline: 1; + source: "example/selection"; + source4: "example/cursor"; + description { + state: "default" 0.0; + min: 12 50; + rel1 { + to: "bg_text1"; + offset: 2 2; + } + rel2 { + to: "bg_text1"; + offset: -3 -3; + } + text { + style: "entry_style"; + min: 0 1; + align: 0.0 0.0; + } + } + } + + part { + name: "bg_text2"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + min: 10 50; + rel1.relative: 0.3 0.45; + rel2.relative: 0.9 0.6; + color: 200 200 200 255; + } + description { + state: "focused,s1" 0.0; + inherit: "default" 0.0; + color: 200 0 0 255; + } + description { + state: "focused,s2" 0.0; + inherit: "default" 0.0; + color: 0 200 0 255; + } + } + + part { + name: "example/text2"; + type: TEXTBLOCK; + scale: 1; + entry_mode: EDITABLE; + select_mode: DEFAULT; + cursor_mode: UNDER; + mouse_events: 1; + multiline: 1; + source: "example/selection"; + source4: "example/cursor"; + description { + state: "default" 0.0; + min: 12 50; + rel1 { + to: "bg_text2"; + offset: 2 2; + } + rel2 { + to: "bg_text2"; + offset: -3 -3; + } + text { + style: "entry_style"; + min: 0 1; + align: 0.0 0.0; + } + } + } + + part { + name: "button_bg"; + type: RECT; + mouse_events: 1; + description { + state: "default" 0.0; + rel1.relative: 0.3 0.65; + rel2.relative: 0.9 0.9; + color: 200 200 200 255; + } + } + + part { + name: "button_area"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + rel1 { + to: "button_bg"; + offset: 10 10; + } + rel2 { + to: "button_bg"; + offset: -11 -11; + } + color: 0 0 0 0; + } + } + + part { + name: "button_left_over"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + rel1 { + to: "button_area"; + relative: 0.0 0.0; + } + rel2 { + to: "button_area"; + relative: 0.5 0.5; + } + color: 255 0 0 100; + } + description { + state: "on" 0.0; + inherit: "default" 0.0; + color: 255 0 0 255; + } + } + + part { + name: "button_left_over_label"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1.to: "button_left_over"; + rel2.to: "button_left_over"; + text { + text: "Seat 1 over"; + size: 12; + font: "sans"; + min: 1 1; + } + } + } + + part { + name: "button_left_focus"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + rel1 { + to: "button_area"; + relative: 0.0 0.5; + } + rel2 { + to: "button_area"; + relative: 0.5 1.0; + } + color: 255 0 0 100; + } + description { + state: "on" 0.0; + inherit: "default" 0.0; + color: 255 0 0 255; + } + } + + part { + name: "button_left_focus_label"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1.to: "button_left_focus"; + rel2.to: "button_left_focus"; + text { + text: "Seat 1 focus"; + size: 12; + font: "sans"; + min: 1 1; + } + } + } + + part { + name: "button_right_over"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + rel1 { + to: "button_area"; + relative: 0.5 0.0; + } + rel2 { + to: "button_area"; + relative: 1.0 0.5; + } + color: 0 255 0 100; + } + description { + state: "on" 0.0; + inherit: "default" 0.0; + color: 0 255 0 255; + } + } + + part { + name: "button_right_over_label"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1.to: "button_right_over"; + rel2.to: "button_right_over"; + text { + text: "Seat 2 over"; + size: 12; + font: "sans"; + min: 1 1; + } + } + } + + part { + name: "button_right_focus"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + rel1 { + to: "button_area"; + relative: 0.5 0.5; + } + rel2 { + to: "button_area"; + relative: 1.0 1.0; + } + color: 0 255 0 100; + } + description { + state: "on" 0.0; + inherit: "default" 0.0; + color: 0 255 0 255; + } + } + + part { + name: "button_right_focus_label"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1.to: "button_right_focus"; + rel2.to: "button_right_focus"; + text { + text: "Seat 2 focus"; + size: 12; + font: "sans"; + min: 1 1; + } + } + } + } + + programs { + program { + name: "focus"; + signal: "load"; + source: ""; + action: FOCUS_SET "seat1"; + target: "example/text1"; + } + + program { + name: "focus,t1,s1"; + signal: "mouse,clicked,1,seat1"; + source: "example/text1"; + action: FOCUS_SET "seat1"; + target: "example/text1"; + } + + program { + name: "focus,color,t1,s1"; + signal: "focus,part,in,seat1"; + source: "example/text1"; + action: STATE_SET "focused,s1" 0.0; + target: "bg_text1"; + } + + program { + name: "unfocus,color,t1,s1"; + signal: "focus,part,out,seat1"; + source: "example/text1"; + action: STATE_SET "default" 0.0; + target: "bg_text1"; + } + + program { + name: "focus,t2,s1"; + signal: "mouse,clicked,1,seat1"; + source: "example/text2"; + action: FOCUS_SET "seat1"; + target: "example/text2"; + } + + program { + name: "focus,color,t2,s1"; + signal: "focus,part,in,seat1"; + source: "example/text2"; + action: STATE_SET "focused,s1" 0.0; + target: "bg_text2"; + } + + program { + name: "unfocus,color,t2,s1"; + signal: "focus,part,out,seat1"; + source: "example/text2"; + action: STATE_SET "default" 0.0; + target: "bg_text2"; + } + + program { + name: "focus,t1,s2"; + signal: "mouse,clicked,1,seat2"; + source: "example/text1"; + action: FOCUS_SET "seat2"; + target: "example/text1"; + } + + program { + name: "focus,color,t1,s2"; + signal: "focus,part,in,seat2"; + source: "example/text1"; + action: STATE_SET "focused,s2" 0.0; + target: "bg_text1"; + } + + program { + name: "unfocus,color,t1,s2"; + signal: "focus,part,out,seat2"; + source: "example/text1"; + action: STATE_SET "default" 0.0; + target: "bg_text1"; + } + + program { + name: "focus,t2,s2"; + signal: "mouse,clicked,1,seat2"; + source: "example/text2"; + action: FOCUS_SET "seat2"; + target: "example/text2"; + } + + program { + name: "focus,color,t2,s2"; + signal: "focus,part,in,seat2"; + source: "example/text2"; + action: STATE_SET "focused,s2" 0.0; + target: "bg_text2"; + } + + program { + name: "unfocus,color,t2,s2"; + signal: "focus,part,out,seat2"; + source: "example/text2"; + action: STATE_SET "default" 0.0; + target: "bg_text2"; + } + + program { + name: "button,left,in"; + signal: "mouse,in,seat1"; + source: "button_bg"; + action: STATE_SET "on" 0.0; + target: "button_left_over"; + } + + program { + name: "button,left,out"; + signal: "mouse,out,seat1"; + source: "button_bg"; + action: STATE_SET "default" 0.0; + target: "button_left_over"; + } + + program { + name: "button,left,focus"; + signal: "mouse,clicked,1,seat1"; + source: "button_bg"; + action: FOCUS_SET "seat1"; + target: "button_bg"; + } + + program { + name: "button,left,focused"; + signal: "focus,part,in,seat1"; + source: "button_bg"; + action: STATE_SET "on" 0.0; + target: "button_left_focus"; + } + + program { + name: "button,left,unfocused"; + signal: "focus,part,out,seat1"; + source: "button_bg"; + action: STATE_SET "default" 0.0; + target: "button_left_focus"; + } + + program { + name: "button,right,in"; + signal: "mouse,in,seat2"; + source: "button_bg"; + action: STATE_SET "on" 0.0; + target: "button_right_over"; + } + + program { + name: "button,right,out"; + signal: "mouse,out,seat2"; + source: "button_bg"; + action: STATE_SET "default" 0.0; + target: "button_right_over"; + } + + program { + name: "button,right,focus"; + signal: "mouse,clicked,1,seat2"; + source: "button_bg"; + action: FOCUS_SET "seat2"; + target: "button_bg"; + } + + program { + name: "button,right,focused"; + signal: "focus,part,in,seat2"; + source: "button_bg"; + action: STATE_SET "on" 0.0; + target: "button_right_focus"; + } + + program { + name: "button,right,unfocused"; + signal: "focus,part,out,seat2"; + source: "button_bg"; + action: STATE_SET "default" 0.0; + target: "button_right_focus"; + } + + program { + name: "knob1,s1"; + signal: "drag,start,seat1"; + source: "example/knob1"; + action: STATE_SET "focused,s1" 0.0; + target: "example/knob1"; + } + + program { + name: "knob1,s2"; + signal: "drag,start,seat2"; + source: "example/knob1"; + action: STATE_SET "focused,s2" 0.0; + target: "example/knob1"; + } + + program { + name: "knob1,seat1"; + signal: "drag,stop,*"; + source: "example/knob1"; + action: STATE_SET "default" 0.0; + target: "example/knob1"; + } + + program { + name: "knob2,s1"; + signal: "drag,start,seat1"; + source: "example/knob2"; + action: STATE_SET "focused,s1" 0.0; + target: "example/knob2"; + } + + program { + name: "knob2,s2"; + signal: "drag,start,seat2"; + source: "example/knob2"; + action: STATE_SET "focused,s2" 0.0; + target: "example/knob2"; + } + + program { + name: "knob2,seat1"; + signal: "drag,stop,*"; + source: "example/knob2"; + action: STATE_SET "default" 0.0; + target: "example/knob2"; + } + } + } + + group { + name: "example/selection"; + + parts { + part { + name: "selection"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 180 180 180 255; + } + } + } + } + + group { + name: "example/cursor"; + min: 1 0; + + parts { + part { + name: "cursor"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + min: 2 12; + color: 0 0 0 255; + } + description { + state: "hidden" 0.0; + inherit: "default" 0.0; + color: 0 0 0 0; + } + } + } + + programs { + program { + name: "cursor_hide"; + signal: "load"; + source: ""; + action: STATE_SET "hidden" 0.0; + target: "cursor"; + transition: SINUSOIDAL 0.2; + after: "cursor_hide_timer"; + } + program { + name: "cursor_hide_timer"; + in: 0.2 0.0; + after: "cursor_show"; + } + program { + name: "cursor_show"; + action: STATE_SET "default" 0.0; + target: "cursor"; + after: "cursor_show_timer"; + } + program { + name: "cursor_show_timer"; + in: 0.5 0.0; + after: "cursor_hide"; + } + } + } +} -- 2.7.4