diff --git a/src/lib/edje/edje_entry.c b/src/lib/edje/edje_entry.c index f999d0a76a..b836e9596e 100644 --- a/src/lib/edje/edje_entry.c +++ b/src/lib/edje/edje_entry.c @@ -121,9 +121,6 @@ _edje_entry_focus_in_cb(void *data, Evas_Object *o, const char *emission, const Entry *en; Edje *ed; - seat_name = emission + strlen("focus,part,in,"); - seat = evas_device_get(evas_object_evas_get(o), seat_name); - rp = data; if ((!rp) || (rp->type != EDJE_RP_TYPE_TEXT) || (!rp->typedata.text)) return; @@ -135,6 +132,9 @@ _edje_entry_focus_in_cb(void *data, Evas_Object *o, const char *emission, const en = rp->typedata.text->entry_data; if (!en || !en->imf_context) return; + seat_name = emission + sizeof("focus,part,in,") - 1; + seat = _edje_seat_get(ed, seat_name); + if (evas_object_seat_focus_check(ed->obj, seat)) { ecore_imf_context_focus_in(en->imf_context); @@ -1709,7 +1709,7 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, int old_cur_pos; seat = efl_input_device_seat_get(ev->dev); - rp = _edje_focused_part_get(ed, efl_input_device_name_get(seat)); + rp = _edje_focused_part_get(ed, _edje_seat_name_get(ed, seat)); if (!rp) return; if ((rp->type != EDJE_RP_TYPE_TEXT) || @@ -2373,7 +2373,7 @@ _edje_key_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, v Entry *en; seat = efl_input_device_seat_get(ev->dev); - rp = _edje_focused_part_get(ed, efl_input_device_name_get(seat)); + rp = _edje_focused_part_get(ed, _edje_seat_name_get(ed, seat)); if (!rp) return; if ((rp->type != EDJE_RP_TYPE_TEXT) || (!rp->typedata.text)) return; @@ -4478,6 +4478,21 @@ _edje_entry_imf_cursor_info_set(Entry *en) } #ifdef HAVE_ECORE_IMF + +static Edje_Real_Part * +_edje_entry_imf_default_focused_rp_get(Edje *ed) +{ + Eina_Stringshare *seat_name; + Efl_Input_Device *seat; + Evas *e; + + e = evas_object_evas_get(ed->obj); + seat = evas_canvas_default_device_get(e, EFL_INPUT_DEVICE_CLASS_SEAT); + seat_name = _edje_seat_name_get(ed, seat); + + return _edje_focused_part_get(ed, seat_name); +} + static Eina_Bool _edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, char **text, int *cursor_pos) { @@ -4487,9 +4502,7 @@ _edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx EINA_ const char *str; char *plain_text; - // FIXME - //rp = _edje_focused_part_get(ed, efl_input_device_name_get(seat)); - rp = _edje_focused_part_get(ed, "default"); + rp = _edje_entry_imf_default_focused_rp_get(ed); if (!rp) return EINA_FALSE; if ((rp->type != EDJE_RP_TYPE_TEXT) || (!rp->typedata.text)) return EINA_FALSE; @@ -4567,9 +4580,7 @@ _edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, char *commit_str = event_info; Edje_Entry_Change_Info *info = NULL; - // FIXME - //rp = _edje_focused_part_get(ed, efl_input_device_name_get(seat)); - rp = _edje_focused_part_get(ed, "default"); + rp = _edje_entry_imf_default_focused_rp_get(ed); if ((!rp)) return; if ((rp->type != EDJE_RP_TYPE_TEXT) || (!rp->typedata.text)) return; @@ -4669,9 +4680,7 @@ _edje_entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx EINA Eina_Strbuf *buf; Eina_Strbuf *preedit_attr_str; - // FIXME - //rp = _edje_focused_part_get(ed, efl_input_device_name_get(seat)); - rp = _edje_focused_part_get(ed, "default"); + rp = _edje_entry_imf_default_focused_rp_get(ed); if ((!rp)) return; if ((rp->type != EDJE_RP_TYPE_TEXT) || @@ -4821,9 +4830,7 @@ _edje_entry_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx E int cursor_pos; int start, end; - // FIXME - //rp = _edje_focused_part_get(ed, efl_input_device_name_get(seat)); - rp = _edje_focused_part_get(ed, "default"); + rp = _edje_entry_imf_default_focused_rp_get(ed); if ((!rp)) return; if ((!rp) || (!ev)) return; if ((rp->type != EDJE_RP_TYPE_TEXT) || @@ -4880,9 +4887,7 @@ _edje_entry_imf_event_selection_set_cb(void *data, Ecore_IMF_Context *ctx EINA_U Entry *en = NULL; Ecore_IMF_Event_Selection *ev = event_info; - // FIXME - //rp = _edje_focused_part_get(ed, efl_input_device_name_get(seat)); - rp = _edje_focused_part_get(ed, "default"); + rp = _edje_entry_imf_default_focused_rp_get(ed); if ((!rp) || (!ev)) return; if ((rp->type != EDJE_RP_TYPE_TEXT) || (!rp->typedata.text)) return; @@ -4917,9 +4922,7 @@ _edje_entry_imf_retrieve_selection_cb(void *data, Ecore_IMF_Context *ctx EINA_UN Entry *en = NULL; const char *selection_text = NULL; - // FIXME - //rp = _edje_focused_part_get(ed, efl_input_device_name_get(seat)); - rp = _edje_focused_part_get(ed, "default"); + rp = _edje_entry_imf_default_focused_rp_get(ed); if (!rp) return EINA_FALSE; if ((rp->type != EDJE_RP_TYPE_TEXT) || (!rp->typedata.text)) return EINA_FALSE; diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 214f3e83b2..d3b9f20db3 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -507,6 +507,102 @@ _edje_physics_world_update_cb(void *data, EPhysics_World *world EINA_UNUSED, voi } #endif +static void +_edje_device_add(Edje *ed, Efl_Input_Device *dev) +{ + Edje_Seat *s, *seat = NULL; + Eina_Stringshare *name; + char sig[256]; + Eina_List *l; + + ed->seats_count++; + name = eina_stringshare_printf("seat%i", ed->seats_count); + EINA_SAFETY_ON_NULL_RETURN(name); + + EINA_LIST_FOREACH(ed->seats, l, s) + { + if (s->name != name) + continue; + seat = s; + break; + } + + if (!seat) + { + seat = calloc(1, sizeof(Edje_Seat)); + EINA_SAFETY_ON_NULL_GOTO(seat, seat_err); + ed->seats = eina_list_append(ed->seats, seat); + seat->name = eina_stringshare_ref(name); + } + + seat->device = dev; + snprintf(sig, sizeof(sig), "seat,added,%s,%s", seat->name, + efl_input_device_name_get(dev)); + _edje_emit(ed, sig, ""); + +seat_err: + eina_stringshare_del(name); +} + +static void +_edje_device_added_cb(void *data, const Efl_Event *event) +{ + Efl_Input_Device *dev = event->info; + Edje *ed = data; + + if (efl_input_device_type_get(dev) != EFL_INPUT_DEVICE_CLASS_SEAT) + return; + + _edje_device_add(ed, dev); +} + +static void +_edje_device_removed_cb(void *data, const Efl_Event *event) +{ + Efl_Input_Device *dev = event->info; + Edje_Seat *s, *seat = NULL; + Edje *ed = data; + char sig[256]; + Eina_List *l; + + if (efl_input_device_type_get(dev) != EFL_INPUT_DEVICE_CLASS_SEAT) + return; + + EINA_LIST_FOREACH(ed->seats, l, s) + { + if (s->device != dev) + continue; + seat = s; + break; + } + + /* It shouldn't happen. New seats are always registered. */ + EINA_SAFETY_ON_NULL_RETURN(seat); + + seat->device = NULL; + snprintf(sig, sizeof(sig), "seat,removed,%s", seat->name); + _edje_emit(ed, sig, ""); +} + +static void +_edje_devices_add(Edje *ed, Evas *tev) +{ + const Eina_List *devices, *l; + Efl_Input_Device *dev; + + devices = evas_device_list(tev, NULL); + EINA_LIST_FOREACH(devices, l, dev) + { + if (efl_input_device_type_get(dev) == EFL_INPUT_DEVICE_CLASS_SEAT) + _edje_device_add(ed, dev); + } + + efl_event_callback_add(tev, EFL_CANVAS_EVENT_DEVICE_ADDED, + _edje_device_added_cb, ed); + efl_event_callback_add(tev, EFL_CANVAS_EVENT_DEVICE_REMOVED, + _edje_device_removed_cb, ed); +} + int _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const char *group, const char *parent, Eina_List *group_path, Eina_Array *nested) { @@ -627,6 +723,9 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch ERR("Edje compiled without support to physics."); #endif + /* handle multiseat stuff */ + _edje_devices_add(ed, tev); + /* colorclass stuff */ for (i = 0; i < ed->collection->parts_count; ++i) { @@ -1599,7 +1698,15 @@ _edje_file_del(Edje *ed) ed->groups = eina_list_free(ed->groups); - if (tev) evas_event_freeze(tev); + if (tev) + { + efl_event_callback_del(tev, EFL_CANVAS_EVENT_DEVICE_ADDED, + _edje_device_added_cb, ed); + efl_event_callback_del(tev, EFL_CANVAS_EVENT_DEVICE_REMOVED, + _edje_device_removed_cb, ed); + evas_event_freeze(tev); + } + if (ed->freeze_calc) { _edje_util_freeze_calc_list = eina_list_remove(_edje_util_freeze_calc_list, ed); @@ -1809,14 +1916,14 @@ _edje_file_del(Edje *ed) } } - if (ed->focused_parts) + if (ed->seats) { - Edje_Focused_Part *focused_part; + Edje_Seat *seat; - EINA_LIST_FREE(ed->focused_parts, focused_part) + EINA_LIST_FREE(ed->seats, seat) { - free(focused_part->seat); - free(focused_part); + eina_stringshare_del(seat->name); + free(seat); } } diff --git a/src/lib/edje/edje_object.eo b/src/lib/edje/edje_object.eo index 35ce01ef40..4cfded612d 100644 --- a/src/lib/edje/edje_object.eo +++ b/src/lib/edje/edje_object.eo @@ -2066,6 +2066,40 @@ class Edje.Object (Efl.Canvas.Group.Clipped, Efl.File, Efl.Container, Efl.Part, part: string; [[The part name]] } } + @property seat { + get { + [[Return the seat device given its Edje's name. + + Edje references seats by a name that differs from Evas. + Edje naming follows a incrementional convention: first + registered name is "seat1", second is "seat2", differently + from Evas. + + @since 1.19]] + + return: Efl.Input.Device; [[The seat device or $null if not found.]] + } + keys { + name: stringshare; [[The name's character string.]] + } + } + @property seat_name { + get { + [[Get the name given to a set by Edje. + + Edje references seats by a name that differs from Evas. + Edje naming follows a incrementional convention: first + registered name is "seat1", second is "seat2", differently + from Evas. + + @since 1.19]] + + return: stringshare; [[The name's character string or $null if not found.]] + } + keys { + device: Efl.Input.Device; [[The seat device]] + } + } } implements { Efl.Gfx.visible.set; diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index feafaa98e7..d98f324f23 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -1661,7 +1661,7 @@ struct _Edje Edje_Var_Pool *var_pool; /* for faster lookups to avoid nth list walks */ Edje_Real_Part **table_parts; - Eina_List *focused_parts; + Eina_List *seats; Eina_List *subobjs; Eina_List *text_insert_filter_callbacks; Eina_List *markup_filter_callbacks; @@ -1719,6 +1719,8 @@ struct _Edje unsigned short block; unsigned short state; + unsigned short seats_count; + unsigned char load_error; Eina_Bool is_rtl : 1; @@ -2275,11 +2277,12 @@ struct _Edje_Font char *file; }; -typedef struct _Edje_Focused_Part Edje_Focused_Part; -struct _Edje_Focused_Part +typedef struct _Edje_Seat Edje_Seat; +struct _Edje_Seat { - Edje_Real_Part *part; - char *seat; + Edje_Real_Part *focused_part; + Efl_Input_Device *device; + Eina_Stringshare *name; }; Edje_Patterns *edje_match_collection_dir_init(const Eina_List *lst); @@ -2484,6 +2487,9 @@ void _edje_signals_sources_patterns_clean(Edje_Signals_Sources_Patterns *ssp); void _edje_focused_part_set(Edje *ed, const char *seat_name, Edje_Real_Part *rp); Edje_Real_Part *_edje_focused_part_get(Edje *ed, const char *seat_name); +Eina_Stringshare *_edje_seat_name_get(Edje *ed, Efl_Input_Device *device); +Efl_Input_Device *_edje_seat_get(Edje *ed, Eina_Stringshare *name); + const Edje_Signals_Sources_Patterns *_edje_signal_callback_patterns_ref(const Edje_Signal_Callback_Group *gp); void _edje_signal_callback_patterns_unref(const Edje_Signals_Sources_Patterns *essp); void _edje_signal_callback_reset(Edje_Signal_Callback_Flags *flags, unsigned int length); diff --git a/src/lib/edje/edje_program.c b/src/lib/edje/edje_program.c index f2c4f4cc7e..3cc0d2d873 100644 --- a/src/lib/edje/edje_program.c +++ b/src/lib/edje/edje_program.c @@ -177,6 +177,18 @@ _edje_emit_send(Edje *ed, Eina_Bool broadcast, const char *sig, const char *src, * API * *============================================================================*/ +EOLIAN Eina_Stringshare* +_edje_object_seat_name_get(Eo *obj EINA_UNUSED, Edje *ed, Efl_Input_Device *device) +{ + return _edje_seat_name_get(ed, device); +} + +EOLIAN Efl_Input_Device * +_edje_object_seat_get(Eo *obj EINA_UNUSED, Edje *ed, Eina_Stringshare *name) +{ + return _edje_seat_get(ed, name); +} + EAPI void edje_frametime_set(double t) { @@ -959,19 +971,22 @@ low_mem_current: case EDJE_ACTION_TYPE_FOCUS_SET: { Edje_Real_Part *focused_part; - const char *seat_name; + Eina_Stringshare *seat_name; + Eina_Bool unref_name = EINA_FALSE; - /* TODO : use edje custom seat naming */ if (pr->seat) - seat_name = pr->seat; - else + { + seat_name = eina_stringshare_add(pr->seat); + unref_name = EINA_TRUE; + } + else /* Use default seat name */ { Efl_Input_Device *seat; Evas *e; e = evas_object_evas_get(ed->obj); seat = evas_canvas_default_device_get(e, EFL_INPUT_DEVICE_CLASS_SEAT); - seat_name = evas_device_name_get(seat); + seat_name = _edje_seat_name_get(ed, seat); if (!seat_name) break; } @@ -1010,6 +1025,9 @@ low_mem_current: } } } + + if (unref_name) + eina_stringshare_del(seat_name); } break; @@ -1264,7 +1282,7 @@ _edje_seat_emit(Edje *ed, Efl_Input_Device *dev, const char *sig, const char *sr seat = efl_input_device_seat_get(dev); if (!seat) return; - snprintf(buf, sizeof(buf), "%s,%s", sig, efl_input_device_name_get(seat)); + snprintf(buf, sizeof(buf), "%s,%s", sig, _edje_seat_name_get(ed, seat)); _edje_emit_full(ed, buf, src, NULL, NULL); } @@ -1307,44 +1325,71 @@ _edje_emit_full(Edje *ed, const char *sig, const char *src, void *data, void (*f } void -_edje_focused_part_set(Edje *ed, const char *seat_name, Edje_Real_Part *rp) +_edje_focused_part_set(Edje *ed, Eina_Stringshare *seat_name, Edje_Real_Part *rp) { - Edje_Focused_Part *focused_part; + Edje_Seat *seat; Eina_List *l; - EINA_LIST_FOREACH(ed->focused_parts, l, focused_part) + EINA_LIST_FOREACH(ed->seats, l, seat) { - if (!strcmp(seat_name, focused_part->seat)) + if (seat_name == seat->name) { - focused_part->part = rp; + seat->focused_part = rp; return; } } - focused_part = calloc(1, sizeof(Edje_Focused_Part)); - EINA_SAFETY_ON_NULL_RETURN(focused_part); + /* A part to be set for a seat not yet announced by Evas */ + seat = calloc(1, sizeof(Edje_Seat)); + EINA_SAFETY_ON_NULL_RETURN(seat); - focused_part->seat = strdup(seat_name); - if (!focused_part->seat) - { - free(focused_part); - return; - } + seat->name = eina_stringshare_ref(seat_name); + seat->focused_part = rp; + ed->seats = eina_list_append(ed->seats, seat); - focused_part->part = rp; - ed->focused_parts = eina_list_append(ed->focused_parts, focused_part); + return; } Edje_Real_Part * -_edje_focused_part_get(Edje *ed, const char *seat_name) +_edje_focused_part_get(Edje *ed, Eina_Stringshare *seat_name) { - Edje_Focused_Part *focused_part; + Edje_Seat *seat; Eina_List *l; - EINA_LIST_FOREACH(ed->focused_parts, l, focused_part) + EINA_LIST_FOREACH(ed->seats, l, seat) { - if (!strcmp(seat_name, focused_part->seat)) - return focused_part->part; + if (seat_name == seat->name) + return seat->focused_part; + } + + return NULL; +} + +Eina_Stringshare* +_edje_seat_name_get(Edje *ed, Efl_Input_Device *device) +{ + Edje_Seat *seat; + Eina_List *l; + + EINA_LIST_FOREACH(ed->seats, l, seat) + { + if (seat->device == device) + return seat->name; + } + + return NULL; +} + +Efl_Input_Device * +_edje_seat_get(Edje *ed, Eina_Stringshare *name) +{ + Edje_Seat *seat; + Eina_List *l; + + EINA_LIST_FOREACH(ed->seats, l, seat) + { + if (seat->name == name) + return seat->device; } return NULL;