summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <marcel@osg.samsung.com>2021-03-24 16:04:48 +0100
committerMarcel Hollerbach <marcel@osg.samsung.com>2021-03-24 21:00:43 +0100
commitd5c653f4191b9fc529482e8fdb23801de119b011 (patch)
treeb70dcfc03ebdbc9ab8da25cff2d03d95f879c451
parent753ffef8d0c2e5cc8deb5da5cab12281da2ce989 (diff)
gesture_recognition: Rework to use elputdevs/bu5hm4n/swipe_real
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.
-rw-r--r--src/modules/gesture_recognition/e_mod_main.c226
-rw-r--r--src/modules/gesture_recognition/meson.build2
2 files changed, 84 insertions, 144 deletions
diff --git a/src/modules/gesture_recognition/e_mod_main.c b/src/modules/gesture_recognition/e_mod_main.c
index b1ddbf988..aa4b83771 100644
--- a/src/modules/gesture_recognition/e_mod_main.c
+++ b/src/modules/gesture_recognition/e_mod_main.c
@@ -1,9 +1,9 @@
1#include <e.h> 1#include <e.h>
2#include <Eina.h> 2#include <Eina.h>
3#include <libinput.h>
4#include <grp.h> 3#include <grp.h>
5#include <sys/types.h> 4#include <sys/types.h>
6#include <pwd.h> 5#include <pwd.h>
6#include <Elput.h>
7 7
8E_API E_Module_Api e_modapi = 8E_API E_Module_Api e_modapi =
9 { 9 {
@@ -11,9 +11,8 @@ E_API E_Module_Api e_modapi =
11 "Gesture Recognition" 11 "Gesture Recognition"
12 }; 12 };
13 13
14static struct libinput *gesture_recognition_ctx;
15static Ecore_Fd_Handler *fd_listener;
16static Eina_Hash *active_gestures; 14static Eina_Hash *active_gestures;
15static Elput_Manager *manager;
17 16
18typedef struct { 17typedef struct {
19 Eina_Vector2 pos; 18 Eina_Vector2 pos;
@@ -23,45 +22,8 @@ typedef struct {
23 } visuals; 22 } visuals;
24} Swipe_Stats; 23} Swipe_Stats;
25 24
26static int
27open_restricted(const char *path, int flags, void *user_data EINA_UNUSED)
28{
29 int fd = open(path, flags);
30 return fd < 0 ? -errno : fd;
31}
32
33static void
34close_restricted(int fd, void *user_data EINA_UNUSED)
35{
36 close(fd);
37}
38
39static const struct libinput_interface interface = {
40 .open_restricted = open_restricted,
41 .close_restricted = close_restricted,
42};
43
44static void
45_find_all_touch_input_devices(const char *path, struct libinput *li)
46{
47 Eina_File_Direct_Info *info;
48 Eina_Iterator *input_devies = eina_file_direct_ls(path);
49
50 EINA_ITERATOR_FOREACH(input_devies, info)
51 {
52 struct libinput_device *dev = libinput_path_add_device(li, info->path);
53
54 if (!dev) continue;
55
56 if (!libinput_device_has_capability(dev, LIBINPUT_DEVICE_CAP_GESTURE))
57 {
58 libinput_path_remove_device(dev);
59 }
60 }
61}
62
63static Swipe_Stats* 25static Swipe_Stats*
64_find_swipe_gesture_recognizition(struct libinput_device *dev) 26_find_swipe_gesture_recognizition(Elput_Device *dev)
65{ 27{
66 Swipe_Stats *stats = eina_hash_find(active_gestures, dev); 28 Swipe_Stats *stats = eina_hash_find(active_gestures, dev);
67 29
@@ -69,7 +31,7 @@ _find_swipe_gesture_recognizition(struct libinput_device *dev)
69} 31}
70 32
71static Swipe_Stats* 33static Swipe_Stats*
72_start_swipe_gesture_recognizition(struct libinput_device *dev) 34_start_swipe_gesture_recognizition(Elput_Device *dev)
73{ 35{
74 Swipe_Stats *stats = _find_swipe_gesture_recognizition(dev); 36 Swipe_Stats *stats = _find_swipe_gesture_recognizition(dev);
75 37
@@ -103,7 +65,7 @@ _start_swipe_gesture_recognizition(struct libinput_device *dev)
103} 65}
104 66
105static void 67static void
106_end_swipe_gesture_recognizition(struct libinput_device *dev) 68_end_swipe_gesture_recognizition(Elput_Device *dev)
107{ 69{
108 eina_hash_del_by_key(active_gestures, dev); 70 eina_hash_del_by_key(active_gestures, dev);
109} 71}
@@ -119,104 +81,6 @@ _config_angle(Eina_Vector2 pos)
119} 81}
120 82
121static Eina_Bool 83static Eina_Bool
122_cb_input_dispatch(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
123{
124 struct libinput *li = data;
125 struct libinput_event *event;
126
127 if (libinput_dispatch(li) != 0)
128 printf("Failed to dispatch libinput events");
129
130 while((event = libinput_get_event(li)))
131 {
132 E_Bindings_Swipe_Live_Update live_update = e_bindings_swipe_live_update_hook_get();
133
134 enum libinput_event_type type = libinput_event_get_type(event);
135 struct libinput_device *dev = libinput_event_get_device(event);
136 if (type == LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN)
137 {
138 struct libinput_event_gesture *gesture = libinput_event_get_gesture_event(event);
139
140 Swipe_Stats *stats = _start_swipe_gesture_recognizition(dev);
141 stats->fingers = libinput_event_gesture_get_finger_count(gesture);
142 stats->pos.x = stats->pos.y = 0;
143 }
144 else if (type == LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE)
145 {
146 struct libinput_event_gesture *gesture = libinput_event_get_gesture_event(event);
147 Swipe_Stats *stats = _find_swipe_gesture_recognizition(dev);
148
149 stats->pos.x += libinput_event_gesture_get_dx(gesture);
150 stats->pos.y += libinput_event_gesture_get_dy(gesture);
151 if (live_update)
152 {
153 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);
154 }
155 else if (stats->visuals.win)
156 {
157 Eina_Inarray *res = e_bindings_swipe_find_candidates(E_BINDING_CONTEXT_NONE, _config_angle (stats->pos), eina_vector2_length_get(&stats->pos), stats->fingers);
158 E_Binding_Swipe_Candidate *itr;
159 double total = 0.0f;
160 unsigned int len = 0;
161
162 EINA_INARRAY_FOREACH(res, itr)
163 {
164 total += itr->acceptance;
165 len ++;
166 }
167
168 if (len > 0)
169 {
170 char text_buffer[1000];
171
172 snprintf(text_buffer, sizeof(text_buffer), "%d gestures possible", len);
173 elm_progressbar_value_set(stats->visuals.visuals, total/len);
174 elm_object_text_set(stats->visuals.visuals, text_buffer);
175 }
176 else
177 {
178 elm_progressbar_value_set(stats->visuals.visuals, 0.0f);
179 elm_object_text_set(stats->visuals.visuals, "No gesture found");
180 }
181
182 eina_inarray_free(res);
183 }
184 }
185 else if (type == LIBINPUT_EVENT_GESTURE_SWIPE_END)
186 {
187 Swipe_Stats *stats = _find_swipe_gesture_recognizition(dev);
188
189 if (live_update)
190 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);
191 else
192 e_bindings_swipe_handle(E_BINDING_CONTEXT_NONE, NULL, _config_angle(stats->pos), eina_vector2_length_get(&stats->pos), stats->fingers);
193
194 _end_swipe_gesture_recognizition(dev);
195 }
196 libinput_event_destroy(event);
197 }
198 return EINA_TRUE;
199}
200
201static void
202_setup_libinput(void)
203{
204 gesture_recognition_ctx = libinput_path_create_context(&interface, NULL);
205
206 _find_all_touch_input_devices("/dev/input/", gesture_recognition_ctx);
207
208 fd_listener = ecore_main_fd_handler_add(libinput_get_fd(gesture_recognition_ctx), ECORE_FD_READ, _cb_input_dispatch, gesture_recognition_ctx, NULL, NULL);
209}
210
211
212static void
213_tear_down_libinput(void)
214{
215 ecore_main_fd_handler_del(fd_listener);
216 libinput_unref(gesture_recognition_ctx);
217}
218
219static Eina_Bool
220_user_part_of_input(void) 84_user_part_of_input(void)
221{ 85{
222 uid_t user = getuid(); 86 uid_t user = getuid();
@@ -258,9 +122,86 @@ _stats_free(void *ptr)
258 free(stats); 122 free(stats);
259} 123}
260 124
125static void
126_begin(void *data EINA_UNUSED, Elput_Device *device, Elput_Swipe_Gesture *gesture)
127{
128 Swipe_Stats *stats = _start_swipe_gesture_recognizition(device);
129 stats->fingers = elput_swipe_finger_count_get(gesture);
130 stats->pos.x = stats->pos.y = 0;
131}
132
133static void
134_update(void *data EINA_UNUSED, Elput_Device *device, Elput_Swipe_Gesture *gesture)
135{
136 E_Bindings_Swipe_Live_Update live_update = e_bindings_swipe_live_update_hook_get();
137 Swipe_Stats *stats = _find_swipe_gesture_recognizition(device);
138
139 stats->pos.x += elput_swipe_dx_get(gesture);
140 stats->pos.y += elput_swipe_dy_get(gesture);
141
142 if (live_update)
143 {
144 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);
145 }
146 else if (stats->visuals.win)
147 {
148 Eina_Inarray *res = e_bindings_swipe_find_candidates(E_BINDING_CONTEXT_NONE, _config_angle (stats->pos), eina_vector2_length_get(&stats->pos), stats->fingers);
149 E_Binding_Swipe_Candidate *itr;
150 double total = 0.0f;
151 unsigned int len = 0;
152
153 EINA_INARRAY_FOREACH(res, itr)
154 {
155 total += itr->acceptance;
156 len ++;
157 }
158
159 if (len > 0)
160 {
161 char text_buffer[1000];
162
163 snprintf(text_buffer, sizeof(text_buffer), "%d gestures possible", len);
164 elm_progressbar_value_set(stats->visuals.visuals, total/len);
165 elm_object_text_set(stats->visuals.visuals, text_buffer);
166 }
167 else
168 {
169 elm_progressbar_value_set(stats->visuals.visuals, 0.0f);
170 elm_object_text_set(stats->visuals.visuals, "No gesture found");
171 }
172
173 eina_inarray_free(res);
174 }
175}
176
177static void
178_end(void *data EINA_UNUSED, Elput_Device *device, Elput_Swipe_Gesture *gesture EINA_UNUSED)
179{
180 E_Bindings_Swipe_Live_Update live_update = e_bindings_swipe_live_update_hook_get();
181 Swipe_Stats *stats = _find_swipe_gesture_recognizition(device);
182
183 if (live_update)
184 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);
185 else
186 e_bindings_swipe_handle(E_BINDING_CONTEXT_NONE, NULL, _config_angle(stats->pos), eina_vector2_length_get(&stats->pos), stats->fingers);
187
188 _end_swipe_gesture_recognizition(device);
189}
190
261E_API int 191E_API int
262e_modapi_init(E_Module *m EINA_UNUSED) 192e_modapi_init(E_Module *m EINA_UNUSED)
263{ 193{
194 const char *device = NULL;
195
196 elput_init();
197
198 device = getenv("XDG_SEAT");
199 if (!device) device = "seat0";
200 manager = elput_manager_connect_gestures(device, 0);
201 elput_input_init(manager);
202
203 elput_manager_swipe_gesture_listen(manager, _begin, NULL, _update, NULL, _end, NULL);
204
264 if (!_user_part_of_input()) 205 if (!_user_part_of_input())
265 { 206 {
266 e_module_dialog_show(m, "Gesture Recognition", "Your user is not part of the input group, libinput cannot be used."); 207 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)
268 return 0; 209 return 0;
269 } 210 }
270 active_gestures = eina_hash_pointer_new(_stats_free); 211 active_gestures = eina_hash_pointer_new(_stats_free);
271 _setup_libinput();
272 212
273 return 1; 213 return 1;
274} 214}
@@ -276,7 +216,7 @@ e_modapi_init(E_Module *m EINA_UNUSED)
276E_API int 216E_API int
277e_modapi_shutdown(E_Module *m EINA_UNUSED) 217e_modapi_shutdown(E_Module *m EINA_UNUSED)
278{ 218{
279 _tear_down_libinput(); 219 elput_shutdown();
280 return 1; 220 return 1;
281} 221}
282 222
diff --git a/src/modules/gesture_recognition/meson.build b/src/modules/gesture_recognition/meson.build
index 55a7301ea..95785a180 100644
--- a/src/modules/gesture_recognition/meson.build
+++ b/src/modules/gesture_recognition/meson.build
@@ -1,4 +1,4 @@
1src = files( 1src = files(
2 'e_mod_main.c', 2 'e_mod_main.c',
3) 3)
4deps += [dependency('libinput')] 4deps += [dependency('elput'), dependency('libinput')]