1 #include "evas_common_private.h"
2 #include "evas_private.h"
4 /* WARNING: This API is not used across EFL, hard to test! */
8 #define SAFETY_CHECK(obj, klass, ...) \
9 do { MAGIC_CHECK(dev, Evas_Device, 1); \
15 #define SAFETY_CHECK(obj, klass, ...) \
16 do { if (!obj) return __VA_ARGS__; } while (0)
19 /* FIXME: Ideally no work besides calling the Efl_Input_Device API
20 * should be done here. But unfortunately, some knowledge of Evas is required
21 * here (callbacks and canvas private data).
25 _is_pointer(Evas_Device_Class clas)
27 if (clas == EVAS_DEVICE_CLASS_MOUSE ||
28 clas == EVAS_DEVICE_CLASS_TOUCH ||
29 clas == EVAS_DEVICE_CLASS_PEN ||
30 clas == EVAS_DEVICE_CLASS_POINTER ||
31 clas == EVAS_DEVICE_CLASS_WAND)
37 _new_default_device_find(Evas_Public_Data *e, Evas_Device *old_dev)
40 Evas_Device *dev, *def, *old_parent;
41 Efl_Input_Device_Type old_class;
43 if (e->cleanup) return NULL;
44 old_class = efl_input_device_type_get(old_dev);
45 old_parent = efl_parent_get(old_dev);
48 EINA_LIST_FOREACH(e->devices, l, dev)
50 if (efl_input_device_type_get(dev) != old_class)
54 //Prefer devices with the same parent.
55 if (efl_parent_get(dev) == old_parent)
61 const char *class_str;
62 if (old_class == EFL_INPUT_DEVICE_TYPE_SEAT)
64 else if (old_class == EFL_INPUT_DEVICE_TYPE_KEYBOARD)
65 class_str = "keyboard";
68 WRN("Could not find a default %s device.", class_str);
74 _del_cb(void *data, const Efl_Event *ev)
76 Efl_Input_Device_Type devtype;
77 Evas_Public_Data *e = data;
79 e->devices_modified = EINA_TRUE;
80 // can not be done in std destructor
81 e->devices = eina_list_remove(e->devices, ev->object);
83 if (e->default_seat == ev->object)
84 e->default_seat = _new_default_device_find(e, ev->object);
85 else if (e->default_mouse == ev->object)
86 e->default_mouse = _new_default_device_find(e, ev->object);
87 else if (e->default_keyboard == ev->object)
88 e->default_keyboard = _new_default_device_find(e, ev->object);
90 //TIZEN_ONLY(20180530): add storing last mouse device.
91 if (e->last_mouse == ev->object)
95 devtype = efl_input_device_type_get(ev->object);
96 if ((devtype == EFL_INPUT_DEVICE_TYPE_SEAT) && (!e->default_seat))
98 Evas_Pointer_Data *pdata = _evas_pointer_data_by_device_get(e, ev->object);
101 Evas_Pointer_Seat *pseat;
103 EINA_INLIST_FOREACH(e->seats, pseat)
105 /* store to dummy seat data for when seat reattaches */
106 if (pseat->seat) continue;
107 pseat->x = pdata->seat->x;
108 pseat->y = pdata->seat->y;
109 pseat->inside = pdata->seat->inside;
115 if (_is_pointer(devtype))
116 _evas_pointer_data_remove(e, ev->object);
117 eina_hash_del_by_key(e->locks.masks, &ev->object);
118 eina_hash_del_by_key(e->modifiers.masks, &ev->object);
119 efl_event_callback_call(e->evas, EFL_CANVAS_SCENE_EVENT_DEVICE_REMOVED,
123 EOLIAN Efl_Input_Device *
124 _evas_canvas_efl_canvas_scene_device_get(Evas *eo_e EINA_UNUSED, Evas_Public_Data *e, const char *name)
126 const char *dev_name;
130 if (!name) return NULL;
132 EINA_LIST_FOREACH(e->devices, l, dev)
134 dev_name = efl_name_get(dev);
136 if (eina_streq(dev_name, name))
144 evas_device_get(Evas *eo_e, const char *name)
146 return efl_canvas_scene_device_get(eo_e, name);
149 EOLIAN Efl_Input_Device *
150 _evas_canvas_efl_canvas_scene_seat_default_get(Evas *eo_e EINA_UNUSED, Evas_Public_Data *e)
152 return e->default_seat;
155 EOLIAN Efl_Input_Device *
156 _evas_canvas_efl_canvas_scene_seat_get(Evas *eo_e EINA_UNUSED, Evas_Public_Data *e, unsigned int id)
161 EINA_LIST_FOREACH(e->devices, l, dev)
163 if (efl_input_device_type_get(dev) != EFL_INPUT_DEVICE_TYPE_SEAT)
166 if (efl_input_device_seat_id_get(dev) == id)
174 evas_device_get_by_seat_id(Evas *eo_e, unsigned int id)
176 return efl_canvas_scene_seat_get(eo_e, id);
180 evas_device_add(Evas *eo_e)
182 return evas_device_add_full(eo_e, NULL, NULL, NULL, NULL,
183 EVAS_DEVICE_CLASS_NONE,
184 EVAS_DEVICE_SUBCLASS_NONE);
188 evas_device_add_full(Evas *eo_e, const char *name, const char *desc,
189 Evas_Device *parent_dev, Evas_Device *emulation_dev,
190 Evas_Device_Class clas, Evas_Device_Subclass sub_clas)
195 SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS, NULL);
197 dev = efl_add_ref(EFL_INPUT_DEVICE_CLASS, parent_dev ?: eo_e,
198 efl_name_set(efl_added, name),
199 efl_comment_set(efl_added, desc),
200 efl_input_device_type_set(efl_added, (Efl_Input_Device_Type)clas),
201 efl_input_device_source_set(efl_added, emulation_dev),
202 efl_input_device_evas_set(efl_added, eo_e),
203 efl_input_device_subclass_set(efl_added, sub_clas));
205 e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
207 /* This is the case when the user is using wayland backend,
208 since evas itself will not create the devices we must set them here. */
209 if (!e->default_seat && clas == EVAS_DEVICE_CLASS_SEAT)
210 e->default_seat = dev;
211 else if (!e->default_keyboard && clas == EVAS_DEVICE_CLASS_KEYBOARD)
212 e->default_keyboard = dev;
213 else if (_is_pointer(clas))
215 Evas_Pointer_Data *pdata = _evas_pointer_data_add(e, dev);
222 if (e->default_mouse)
224 if ((clas == EVAS_DEVICE_CLASS_MOUSE) &&
225 (parent_dev == e->default_seat) &&
226 (evas_device_class_get(e->default_mouse) != EVAS_DEVICE_CLASS_MOUSE))
228 Eina_Bool inside = pdata->seat->inside;
231 evas_event_feed_mouse_out(eo_e, 0, NULL);
232 e->default_mouse = dev;
234 evas_event_feed_mouse_in(eo_e, 0, NULL);
239 Evas_Pointer_Seat *pseat;
241 EINA_INLIST_FOREACH(e->seats, pseat)
242 if (!pseat->pointers) break;
243 e->default_mouse = dev;
247 evas_event_feed_mouse_in(eo_e, 0, NULL);
248 evas_event_feed_mouse_move(eo_e, pseat->x, pseat->y, 0, NULL);
253 e->devices = eina_list_append(e->devices, dev);
254 efl_event_callback_add(dev, EFL_EVENT_DEL, _del_cb, e);
256 efl_event_callback_call(eo_e, EFL_CANVAS_SCENE_EVENT_DEVICE_ADDED, dev);
257 // Keeping this event to do not break things...
258 evas_event_callback_call(eo_e, EVAS_CALLBACK_DEVICE_CHANGED, dev);
259 if (e->pending_default_focus_obj && (e->default_seat == dev))
261 Eo *eo_obj = e->pending_default_focus_obj;
262 e->pending_default_focus_obj = NULL;
263 evas_object_focus_set(eo_obj, 1);
270 evas_device_del(Evas_Device *dev)
272 if (!efl_invalidated_get(dev))
278 evas_device_push(Evas *eo_e, Evas_Device *dev)
280 Evas_Public_Data *e = efl_data_scope_safe_get(eo_e, EVAS_CANVAS_CLASS);
284 e->cur_device = eina_array_new(4);
285 if (!e->cur_device) return;
288 eina_array_push(e->cur_device, dev);
292 evas_device_pop(Evas *eo_e)
296 Evas_Public_Data *e = efl_data_scope_safe_get(eo_e, EVAS_CANVAS_CLASS);
298 dev = eina_array_pop(e->cur_device);
299 if (dev) efl_unref(dev);
302 EAPI const Eina_List *
303 evas_device_list(Evas *eo_e, const Evas_Device *dev)
305 if (dev) return efl_input_device_children_get(dev);
307 Evas_Public_Data *e = efl_data_scope_safe_get(eo_e, EVAS_CANVAS_CLASS);
308 return e ? e->devices : NULL;
312 evas_device_name_set(Evas_Device *dev, const char *name)
314 efl_name_set(dev, name);
315 evas_event_callback_call(efl_input_device_evas_get(dev), EVAS_CALLBACK_DEVICE_CHANGED, dev);
319 evas_device_name_get(const Evas_Device *dev)
321 return efl_name_get(dev);
325 evas_device_description_set(Evas_Device *dev, const char *desc)
327 efl_comment_set(dev, desc);
328 evas_event_callback_call(efl_input_device_evas_get(dev), EVAS_CALLBACK_DEVICE_CHANGED, dev);
332 evas_device_description_get(const Evas_Device *dev)
334 return efl_comment_get(dev);
338 evas_device_parent_set(Evas_Device *dev EINA_UNUSED, Evas_Device *parent EINA_UNUSED)
340 // Note: This function should be deprecated. parent_set doesn't make sense
341 // unless the parent is a seat device. Parent shouldn't be changed after
343 ERR("It is not advised and possible anymore to changed the parent of an Evas_Device.");
346 EAPI const Evas_Device *
347 evas_device_parent_get(const Evas_Device *dev)
349 Eo *parent = efl_parent_get(dev);
351 if (!efl_isa(parent, EFL_INPUT_DEVICE_CLASS))
358 evas_device_class_set(Evas_Device *dev, Evas_Device_Class clas)
360 EINA_SAFETY_ON_TRUE_RETURN(efl_finalized_get(dev));
362 Evas_Public_Data *edata = efl_data_scope_safe_get(efl_input_device_evas_get(dev), EVAS_CANVAS_CLASS);
363 Efl_Input_Device_Type klass = efl_input_device_type_get(dev);
367 if ((Evas_Device_Class)klass == clas)
370 if (_is_pointer((Evas_Device_Class)klass))
371 _evas_pointer_data_remove(edata, dev);
373 efl_input_device_type_set(dev, (Efl_Input_Device_Type)clas);
375 if (_is_pointer(clas))
376 _evas_pointer_data_add(edata, dev);
378 evas_event_callback_call(efl_input_device_evas_get(dev), EVAS_CALLBACK_DEVICE_CHANGED, dev);
381 EAPI Evas_Device_Class
382 evas_device_class_get(const Evas_Device *dev)
384 return (Evas_Device_Class)efl_input_device_type_get(dev);
388 evas_device_subclass_set(Evas_Device *dev, Evas_Device_Subclass clas)
390 efl_input_device_subclass_set(dev, clas);
391 evas_event_callback_call(efl_input_device_evas_get(dev), EVAS_CALLBACK_DEVICE_CHANGED, dev);
394 EAPI Evas_Device_Subclass
395 evas_device_subclass_get(const Evas_Device *dev)
397 return efl_input_device_subclass_get(dev);
401 evas_device_emulation_source_set(Evas_Device *dev, Evas_Device *src)
403 efl_input_device_source_set(dev, src);
404 evas_event_callback_call(efl_input_device_evas_get(dev), EVAS_CALLBACK_DEVICE_CHANGED, dev);
407 EAPI const Evas_Device *
408 evas_device_emulation_source_get(const Evas_Device *dev)
410 return efl_input_device_source_get(dev);
414 evas_device_seat_id_set(Evas_Device *dev, unsigned int id)
416 efl_input_device_seat_id_set(dev, id);
420 evas_device_seat_id_get(const Evas_Device *dev)
422 return efl_input_device_seat_id_get(dev);
426 _evas_device_cleanup(Evas *eo_e)
428 Eina_List *cpy, *deleted = NULL;
430 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
434 while ((dev = eina_array_pop(e->cur_device)))
436 eina_array_free(e->cur_device);
437 e->cur_device = NULL;
440 /* If the device is deleted, _del_cb will remove the device
441 * from the devices list. Ensure we delete them only once, and only if this
442 * Evas is the owner, otherwise we would kill external references (eg.
443 * from efl_duplicate()). */
445 e->devices_modified = EINA_FALSE;
446 cpy = eina_list_clone(e->devices);
447 EINA_LIST_FREE(cpy, dev)
449 if (!eina_list_data_find(deleted, dev))
451 evas_device_del(dev);
452 deleted = eina_list_append(deleted, dev);
453 if (e->devices_modified)
460 eina_list_free(deleted);
462 /* Not all devices were deleted. The user probably will unref them later.
463 Since Evas will be deleted, remove the del callback from them and
464 tell the user that the device was removed.
466 EINA_LIST_FREE(e->devices, dev)
468 efl_event_callback_call(e->evas, EFL_CANVAS_SCENE_EVENT_DEVICE_REMOVED, dev);
469 efl_event_callback_del(dev, EFL_EVENT_DEL, _del_cb, e);
474 _evas_device_top_get(const Evas *eo_e)
478 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
479 if (!e->cur_device) return NULL;
480 num = eina_array_count(e->cur_device);
481 if (num < 1) return NULL;
482 return eina_array_data_get(e->cur_device, num - 1);
486 _evas_canvas_efl_canvas_scene_pointer_position_get(const Eo *eo_e, Evas_Public_Data *e, Efl_Input_Device *seat, Eina_Position2D *pos)
491 if (!pos) return EINA_FALSE;
493 *pos = EINA_POSITION2D(0, 0);
494 if (!e->default_seat) return EINA_FALSE;
497 evas_pointer_canvas_xy_get(eo_e, &pos->x, &pos->y);
500 it = efl_input_device_children_iterate(seat);
501 EINA_SAFETY_ON_NULL_RETURN_VAL(it, EINA_FALSE);
503 EINA_ITERATOR_FOREACH(it, child)
504 if (_is_pointer((Evas_Device_Class)efl_input_device_type_get(child)))
507 *pos = efl_input_pointer_position_get(child);
509 eina_iterator_free(it);
513 //TIZEN_ONLY(20171220): send a hw device for pointer events
515 evas_device_top_get(const Evas *eo_e)
517 return _evas_device_top_get(eo_e);
523 evas_device_default_get(const Evas *eo_e, Evas_Device_Class clas)
527 SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS, NULL);
529 e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
531 if (clas == EVAS_DEVICE_CLASS_SEAT)
533 return e->default_seat;
535 else if (clas == EVAS_DEVICE_CLASS_KEYBOARD)
537 return e->default_keyboard;
539 else if (clas == EVAS_DEVICE_CLASS_MOUSE ||
540 clas == EVAS_DEVICE_CLASS_TOUCH)
542 return e->default_mouse;