gesture_recognition: Rework to use elput
With this: - Support for gestures in X *and* wayland. Wayland does not require the libinput group hack - Hotplugging support thanks to udev support This requires a new rebuild of efl.
This commit is contained in:
parent
753ffef8d0
commit
d5c653f419
|
@ -1,9 +1,9 @@
|
|||
#include <e.h>
|
||||
#include <Eina.h>
|
||||
#include <libinput.h>
|
||||
#include <grp.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <Elput.h>
|
||||
|
||||
E_API E_Module_Api e_modapi =
|
||||
{
|
||||
|
@ -11,9 +11,8 @@ E_API E_Module_Api e_modapi =
|
|||
"Gesture Recognition"
|
||||
};
|
||||
|
||||
static struct libinput *gesture_recognition_ctx;
|
||||
static Ecore_Fd_Handler *fd_listener;
|
||||
static Eina_Hash *active_gestures;
|
||||
static Elput_Manager *manager;
|
||||
|
||||
typedef struct {
|
||||
Eina_Vector2 pos;
|
||||
|
@ -23,45 +22,8 @@ typedef struct {
|
|||
} visuals;
|
||||
} Swipe_Stats;
|
||||
|
||||
static int
|
||||
open_restricted(const char *path, int flags, void *user_data EINA_UNUSED)
|
||||
{
|
||||
int fd = open(path, flags);
|
||||
return fd < 0 ? -errno : fd;
|
||||
}
|
||||
|
||||
static void
|
||||
close_restricted(int fd, void *user_data EINA_UNUSED)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static const struct libinput_interface interface = {
|
||||
.open_restricted = open_restricted,
|
||||
.close_restricted = close_restricted,
|
||||
};
|
||||
|
||||
static void
|
||||
_find_all_touch_input_devices(const char *path, struct libinput *li)
|
||||
{
|
||||
Eina_File_Direct_Info *info;
|
||||
Eina_Iterator *input_devies = eina_file_direct_ls(path);
|
||||
|
||||
EINA_ITERATOR_FOREACH(input_devies, info)
|
||||
{
|
||||
struct libinput_device *dev = libinput_path_add_device(li, info->path);
|
||||
|
||||
if (!dev) continue;
|
||||
|
||||
if (!libinput_device_has_capability(dev, LIBINPUT_DEVICE_CAP_GESTURE))
|
||||
{
|
||||
libinput_path_remove_device(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Swipe_Stats*
|
||||
_find_swipe_gesture_recognizition(struct libinput_device *dev)
|
||||
_find_swipe_gesture_recognizition(Elput_Device *dev)
|
||||
{
|
||||
Swipe_Stats *stats = eina_hash_find(active_gestures, dev);
|
||||
|
||||
|
@ -69,7 +31,7 @@ _find_swipe_gesture_recognizition(struct libinput_device *dev)
|
|||
}
|
||||
|
||||
static Swipe_Stats*
|
||||
_start_swipe_gesture_recognizition(struct libinput_device *dev)
|
||||
_start_swipe_gesture_recognizition(Elput_Device *dev)
|
||||
{
|
||||
Swipe_Stats *stats = _find_swipe_gesture_recognizition(dev);
|
||||
|
||||
|
@ -103,7 +65,7 @@ _start_swipe_gesture_recognizition(struct libinput_device *dev)
|
|||
}
|
||||
|
||||
static void
|
||||
_end_swipe_gesture_recognizition(struct libinput_device *dev)
|
||||
_end_swipe_gesture_recognizition(Elput_Device *dev)
|
||||
{
|
||||
eina_hash_del_by_key(active_gestures, dev);
|
||||
}
|
||||
|
@ -118,104 +80,6 @@ _config_angle(Eina_Vector2 pos)
|
|||
return res;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_cb_input_dispatch(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
|
||||
{
|
||||
struct libinput *li = data;
|
||||
struct libinput_event *event;
|
||||
|
||||
if (libinput_dispatch(li) != 0)
|
||||
printf("Failed to dispatch libinput events");
|
||||
|
||||
while((event = libinput_get_event(li)))
|
||||
{
|
||||
E_Bindings_Swipe_Live_Update live_update = e_bindings_swipe_live_update_hook_get();
|
||||
|
||||
enum libinput_event_type type = libinput_event_get_type(event);
|
||||
struct libinput_device *dev = libinput_event_get_device(event);
|
||||
if (type == LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN)
|
||||
{
|
||||
struct libinput_event_gesture *gesture = libinput_event_get_gesture_event(event);
|
||||
|
||||
Swipe_Stats *stats = _start_swipe_gesture_recognizition(dev);
|
||||
stats->fingers = libinput_event_gesture_get_finger_count(gesture);
|
||||
stats->pos.x = stats->pos.y = 0;
|
||||
}
|
||||
else if (type == LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE)
|
||||
{
|
||||
struct libinput_event_gesture *gesture = libinput_event_get_gesture_event(event);
|
||||
Swipe_Stats *stats = _find_swipe_gesture_recognizition(dev);
|
||||
|
||||
stats->pos.x += libinput_event_gesture_get_dx(gesture);
|
||||
stats->pos.y += libinput_event_gesture_get_dy(gesture);
|
||||
if (live_update)
|
||||
{
|
||||
live_update(e_bindings_swipe_live_update_hook_data_get(), EINA_FALSE, _config_angle(stats->pos), eina_vector2_length_get(&stats->pos), 0.8, stats->fingers);
|
||||
}
|
||||
else if (stats->visuals.win)
|
||||
{
|
||||
Eina_Inarray *res = e_bindings_swipe_find_candidates(E_BINDING_CONTEXT_NONE, _config_angle (stats->pos), eina_vector2_length_get(&stats->pos), stats->fingers);
|
||||
E_Binding_Swipe_Candidate *itr;
|
||||
double total = 0.0f;
|
||||
unsigned int len = 0;
|
||||
|
||||
EINA_INARRAY_FOREACH(res, itr)
|
||||
{
|
||||
total += itr->acceptance;
|
||||
len ++;
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
char text_buffer[1000];
|
||||
|
||||
snprintf(text_buffer, sizeof(text_buffer), "%d gestures possible", len);
|
||||
elm_progressbar_value_set(stats->visuals.visuals, total/len);
|
||||
elm_object_text_set(stats->visuals.visuals, text_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
elm_progressbar_value_set(stats->visuals.visuals, 0.0f);
|
||||
elm_object_text_set(stats->visuals.visuals, "No gesture found");
|
||||
}
|
||||
|
||||
eina_inarray_free(res);
|
||||
}
|
||||
}
|
||||
else if (type == LIBINPUT_EVENT_GESTURE_SWIPE_END)
|
||||
{
|
||||
Swipe_Stats *stats = _find_swipe_gesture_recognizition(dev);
|
||||
|
||||
if (live_update)
|
||||
live_update(e_bindings_swipe_live_update_hook_data_get(), EINA_TRUE, _config_angle(stats->pos), eina_vector2_length_get(&stats->pos), 0.8, stats->fingers);
|
||||
else
|
||||
e_bindings_swipe_handle(E_BINDING_CONTEXT_NONE, NULL, _config_angle(stats->pos), eina_vector2_length_get(&stats->pos), stats->fingers);
|
||||
|
||||
_end_swipe_gesture_recognizition(dev);
|
||||
}
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_setup_libinput(void)
|
||||
{
|
||||
gesture_recognition_ctx = libinput_path_create_context(&interface, NULL);
|
||||
|
||||
_find_all_touch_input_devices("/dev/input/", gesture_recognition_ctx);
|
||||
|
||||
fd_listener = ecore_main_fd_handler_add(libinput_get_fd(gesture_recognition_ctx), ECORE_FD_READ, _cb_input_dispatch, gesture_recognition_ctx, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_tear_down_libinput(void)
|
||||
{
|
||||
ecore_main_fd_handler_del(fd_listener);
|
||||
libinput_unref(gesture_recognition_ctx);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_user_part_of_input(void)
|
||||
{
|
||||
|
@ -258,9 +122,86 @@ _stats_free(void *ptr)
|
|||
free(stats);
|
||||
}
|
||||
|
||||
static void
|
||||
_begin(void *data EINA_UNUSED, Elput_Device *device, Elput_Swipe_Gesture *gesture)
|
||||
{
|
||||
Swipe_Stats *stats = _start_swipe_gesture_recognizition(device);
|
||||
stats->fingers = elput_swipe_finger_count_get(gesture);
|
||||
stats->pos.x = stats->pos.y = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_update(void *data EINA_UNUSED, Elput_Device *device, Elput_Swipe_Gesture *gesture)
|
||||
{
|
||||
E_Bindings_Swipe_Live_Update live_update = e_bindings_swipe_live_update_hook_get();
|
||||
Swipe_Stats *stats = _find_swipe_gesture_recognizition(device);
|
||||
|
||||
stats->pos.x += elput_swipe_dx_get(gesture);
|
||||
stats->pos.y += elput_swipe_dy_get(gesture);
|
||||
|
||||
if (live_update)
|
||||
{
|
||||
live_update(e_bindings_swipe_live_update_hook_data_get(), EINA_FALSE, _config_angle(stats->pos), eina_vector2_length_get(&stats->pos), 0.8, stats->fingers);
|
||||
}
|
||||
else if (stats->visuals.win)
|
||||
{
|
||||
Eina_Inarray *res = e_bindings_swipe_find_candidates(E_BINDING_CONTEXT_NONE, _config_angle (stats->pos), eina_vector2_length_get(&stats->pos), stats->fingers);
|
||||
E_Binding_Swipe_Candidate *itr;
|
||||
double total = 0.0f;
|
||||
unsigned int len = 0;
|
||||
|
||||
EINA_INARRAY_FOREACH(res, itr)
|
||||
{
|
||||
total += itr->acceptance;
|
||||
len ++;
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
char text_buffer[1000];
|
||||
|
||||
snprintf(text_buffer, sizeof(text_buffer), "%d gestures possible", len);
|
||||
elm_progressbar_value_set(stats->visuals.visuals, total/len);
|
||||
elm_object_text_set(stats->visuals.visuals, text_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
elm_progressbar_value_set(stats->visuals.visuals, 0.0f);
|
||||
elm_object_text_set(stats->visuals.visuals, "No gesture found");
|
||||
}
|
||||
|
||||
eina_inarray_free(res);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_end(void *data EINA_UNUSED, Elput_Device *device, Elput_Swipe_Gesture *gesture EINA_UNUSED)
|
||||
{
|
||||
E_Bindings_Swipe_Live_Update live_update = e_bindings_swipe_live_update_hook_get();
|
||||
Swipe_Stats *stats = _find_swipe_gesture_recognizition(device);
|
||||
|
||||
if (live_update)
|
||||
live_update(e_bindings_swipe_live_update_hook_data_get(), EINA_TRUE, _config_angle(stats->pos), eina_vector2_length_get(&stats->pos), 0.8, stats->fingers);
|
||||
else
|
||||
e_bindings_swipe_handle(E_BINDING_CONTEXT_NONE, NULL, _config_angle(stats->pos), eina_vector2_length_get(&stats->pos), stats->fingers);
|
||||
|
||||
_end_swipe_gesture_recognizition(device);
|
||||
}
|
||||
|
||||
E_API int
|
||||
e_modapi_init(E_Module *m EINA_UNUSED)
|
||||
{
|
||||
const char *device = NULL;
|
||||
|
||||
elput_init();
|
||||
|
||||
device = getenv("XDG_SEAT");
|
||||
if (!device) device = "seat0";
|
||||
manager = elput_manager_connect_gestures(device, 0);
|
||||
elput_input_init(manager);
|
||||
|
||||
elput_manager_swipe_gesture_listen(manager, _begin, NULL, _update, NULL, _end, NULL);
|
||||
|
||||
if (!_user_part_of_input())
|
||||
{
|
||||
e_module_dialog_show(m, "Gesture Recognition", "Your user is not part of the input group, libinput cannot be used.");
|
||||
|
@ -268,7 +209,6 @@ e_modapi_init(E_Module *m EINA_UNUSED)
|
|||
return 0;
|
||||
}
|
||||
active_gestures = eina_hash_pointer_new(_stats_free);
|
||||
_setup_libinput();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -276,7 +216,7 @@ e_modapi_init(E_Module *m EINA_UNUSED)
|
|||
E_API int
|
||||
e_modapi_shutdown(E_Module *m EINA_UNUSED)
|
||||
{
|
||||
_tear_down_libinput();
|
||||
elput_shutdown();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
src = files(
|
||||
'e_mod_main.c',
|
||||
)
|
||||
deps += [dependency('libinput')]
|
||||
deps += [dependency('elput'), dependency('libinput')]
|
||||
|
|
Loading…
Reference in New Issue