summaryrefslogtreecommitdiff
path: root/src/lib/ecore_input
diff options
context:
space:
mode:
authorShinwoo Kim <kimcinoo.efl@gmail.com>2016-06-13 19:41:38 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2016-06-13 20:33:29 +0900
commitf70be6eb28a2ed6c6bfc23a14d6ad2cebfe1b95b (patch)
treea4147d38cf9d4a5447a8550edd87ac9136ec484f /src/lib/ecore_input
parent59f3841803238a21972d17336a68616406bec8b3 (diff)
Ecore_Input: define data type for joysticks
Summary: This adds support for joysticks for ecore_input Reviewers: cedric, devilhorns, Sergeant_Whitespace, raster, thiepha, zmike, jpeg Reviewed By: thiepha, zmike, jpeg Subscribers: thiepha, stefan_schmidt, zmike, singh.amitesh, Sergeant_Whitespace, jgerecke, cedric, seoz Tags: #efl Differential Revision: https://phab.enlightenment.org/D1538
Diffstat (limited to 'src/lib/ecore_input')
-rw-r--r--src/lib/ecore_input/Ecore_Input.h81
-rw-r--r--src/lib/ecore_input/ecore_input.c6
-rw-r--r--src/lib/ecore_input/ecore_input_joystick.c386
-rw-r--r--src/lib/ecore_input/ecore_input_private.h2
4 files changed, 475 insertions, 0 deletions
diff --git a/src/lib/ecore_input/Ecore_Input.h b/src/lib/ecore_input/Ecore_Input.h
index c7a74a9d4c..45f6c387bd 100644
--- a/src/lib/ecore_input/Ecore_Input.h
+++ b/src/lib/ecore_input/Ecore_Input.h
@@ -55,6 +55,7 @@ extern "C" {
55 EAPI extern int ECORE_EVENT_MOUSE_OUT; 55 EAPI extern int ECORE_EVENT_MOUSE_OUT;
56 EAPI extern int ECORE_EVENT_AXIS_UPDATE; /**< @since 1.13 */ 56 EAPI extern int ECORE_EVENT_AXIS_UPDATE; /**< @since 1.13 */
57 EAPI extern int ECORE_EVENT_MOUSE_BUTTON_CANCEL; /**< @since 1.15 */ 57 EAPI extern int ECORE_EVENT_MOUSE_BUTTON_CANCEL; /**< @since 1.15 */
58 EAPI extern int ECORE_EVENT_JOYSTICK; /**< @since 1.18 */
58 59
59#define ECORE_EVENT_MODIFIER_SHIFT 0x0001 60#define ECORE_EVENT_MODIFIER_SHIFT 0x0001
60#define ECORE_EVENT_MODIFIER_CTRL 0x0002 61#define ECORE_EVENT_MODIFIER_CTRL 0x0002
@@ -82,6 +83,7 @@ extern "C" {
82 typedef struct _Ecore_Event_Modifiers Ecore_Event_Modifiers; 83 typedef struct _Ecore_Event_Modifiers Ecore_Event_Modifiers;
83 typedef struct _Ecore_Event_Axis_Update Ecore_Event_Axis_Update; /**< @since 1.13 */ 84 typedef struct _Ecore_Event_Axis_Update Ecore_Event_Axis_Update; /**< @since 1.13 */
84 typedef struct _Ecore_Axis Ecore_Axis; /**< @since 1.13 */ 85 typedef struct _Ecore_Axis Ecore_Axis; /**< @since 1.13 */
86 typedef struct _Ecore_Event_Joystick Ecore_Event_Joystick; /**< @since 1.18 */
85 87
86 /** 88 /**
87 * @typedef Ecore_Event_Modifier 89 * @typedef Ecore_Event_Modifier
@@ -133,6 +135,59 @@ extern "C" {
133 } Ecore_Compose_State; 135 } Ecore_Compose_State;
134 136
135 /** 137 /**
138 * @struct _Ecore_Event_Joystic_Button
139 * Contains information about a joystick button event.
140 */
141 typedef enum _Ecore_Event_Joystick_Button
142 {
143 ECORE_EVENT_JOYSTICK_BUTTON_NONE,
144 ECORE_EVENT_JOYSTICK_BUTTON_FACE_0,
145 ECORE_EVENT_JOYSTICK_BUTTON_FACE_1,
146 ECORE_EVENT_JOYSTICK_BUTTON_FACE_2,
147 ECORE_EVENT_JOYSTICK_BUTTON_FACE_3,
148 ECORE_EVENT_JOYSTICK_BUTTON_LEFT_SHOULDER,
149 ECORE_EVENT_JOYSTICK_BUTTON_RIGHT_SHOULDER,
150 ECORE_EVENT_JOYSTICK_BUTTON_SELECT,
151 ECORE_EVENT_JOYSTICK_BUTTON_START,
152 ECORE_EVENT_JOYSTICK_BUTTON_LEFT_ANALOG_STICK,
153 ECORE_EVENT_JOYSTICK_BUTTON_RIGHT_ANALOG_STICK,
154 ECORE_EVENT_JOYSTICK_BUTTON_META,
155 ECORE_EVENT_JOYSTICK_BUTTON_LAST
156 } Ecore_Event_Joystick_Button; /**< @since 1.18 */
157
158 /**
159 * @struct _Ecore_Event_Joystic_Axis
160 * Contains information about a joystick axis event.
161 */
162 typedef enum _Ecore_Event_Joystick_Axis
163 {
164 ECORE_EVENT_JOYSTICK_AXIS_NONE,
165 ECORE_EVENT_JOYSTICK_AXIS_HAT_X,
166 ECORE_EVENT_JOYSTICK_AXIS_HAT_Y,
167 ECORE_EVENT_JOYSTICK_AXIS_LEFT_SHOULDER,
168 ECORE_EVENT_JOYSTICK_AXIS_RIGHT_SHOULDER,
169 ECORE_EVENT_JOYSTICK_AXIS_LEFT_ANALOG_HOR,
170 ECORE_EVENT_JOYSTICK_AXIS_LEFT_ANALOG_VER,
171 ECORE_EVENT_JOYSTICK_AXIS_RIGHT_ANALOG_HOR,
172 ECORE_EVENT_JOYSTICK_AXIS_RIGHT_ANALOG_VER,
173 ECORE_EVENT_JOYSTICK_AXIS_LAST
174 } Ecore_Event_Joystick_Axis; /**< @since 1.18 */
175
176 /**
177 * @struct _Ecore_Event_Joystic_Event_Type
178 * Contains information about a joystick event type.
179 */
180 typedef enum _Ecore_Event_Joystick_Event
181 {
182 ECORE_EVENT_JOYSTICK_EVENT_TYPE_NONE,
183 ECORE_EVENT_JOYSTICK_EVENT_TYPE_CONNECTED,
184 ECORE_EVENT_JOYSTICK_EVENT_TYPE_DISCONNECTED,
185 ECORE_EVENT_JOYSTICK_EVENT_TYPE_BUTTON,
186 ECORE_EVENT_JOYSTICK_EVENT_TYPE_AXIS,
187 ECORE_EVENT_JOYSTICK_EVENT_TYPE_LAST
188 } Ecore_Event_Joystick_Event_Type; /**< @since 1.18 */
189
190 /**
136 * @struct _Ecore_Event_Key 191 * @struct _Ecore_Event_Key
137 * Contains information about an Ecore keyboard event. 192 * Contains information about an Ecore keyboard event.
138 */ 193 */
@@ -314,6 +369,32 @@ extern "C" {
314 }; 369 };
315 370
316 /** 371 /**
372 * @struct _Ecore_Event_Joystick
373 * Contains information about a joystick event.
374 */
375 struct _Ecore_Event_Joystick
376 {
377 Ecore_Event_Joystick_Event_Type type;
378 unsigned int index;
379 unsigned int timestamp;
380
381 union
382 {
383 struct
384 {
385 Ecore_Event_Joystick_Axis index;
386 double value; /* [-1.0 .. 1.0] -1.0 == up or left, 1.0 == down or right */
387 } axis;
388
389 struct
390 {
391 Ecore_Event_Joystick_Button index;
392 double value; /* [0.0 .. 1.0] 0.0 == fully unpressed, 1.0 == fully pressed */
393 } button;
394 };
395 };
396
397 /**
317 * Initialises the Ecore Event system. 398 * Initialises the Ecore Event system.
318 */ 399 */
319 EAPI int ecore_event_init(void); 400 EAPI int ecore_event_init(void);
diff --git a/src/lib/ecore_input/ecore_input.c b/src/lib/ecore_input/ecore_input.c
index 6b52eff631..32441ddb9f 100644
--- a/src/lib/ecore_input/ecore_input.c
+++ b/src/lib/ecore_input/ecore_input.c
@@ -24,6 +24,7 @@ EAPI int ECORE_EVENT_MOUSE_IN = 0;
24EAPI int ECORE_EVENT_MOUSE_OUT = 0; 24EAPI int ECORE_EVENT_MOUSE_OUT = 0;
25EAPI int ECORE_EVENT_AXIS_UPDATE = 0; 25EAPI int ECORE_EVENT_AXIS_UPDATE = 0;
26EAPI int ECORE_EVENT_MOUSE_BUTTON_CANCEL = 0; 26EAPI int ECORE_EVENT_MOUSE_BUTTON_CANCEL = 0;
27EAPI int ECORE_EVENT_JOYSTICK = 0;
27 28
28static int _ecore_event_init_count = 0; 29static int _ecore_event_init_count = 0;
29 30
@@ -56,6 +57,9 @@ ecore_event_init(void)
56 ECORE_EVENT_MOUSE_OUT = ecore_event_type_new(); 57 ECORE_EVENT_MOUSE_OUT = ecore_event_type_new();
57 ECORE_EVENT_AXIS_UPDATE = ecore_event_type_new(); 58 ECORE_EVENT_AXIS_UPDATE = ecore_event_type_new();
58 ECORE_EVENT_MOUSE_BUTTON_CANCEL = ecore_event_type_new(); 59 ECORE_EVENT_MOUSE_BUTTON_CANCEL = ecore_event_type_new();
60 ECORE_EVENT_JOYSTICK = ecore_event_type_new();
61
62 ecore_input_joystick_init();
59 63
60 return _ecore_event_init_count; 64 return _ecore_event_init_count;
61} 65}
@@ -76,6 +80,8 @@ ecore_event_shutdown(void)
76 ECORE_EVENT_MOUSE_OUT = 0; 80 ECORE_EVENT_MOUSE_OUT = 0;
77 ECORE_EVENT_AXIS_UPDATE = 0; 81 ECORE_EVENT_AXIS_UPDATE = 0;
78 ECORE_EVENT_MOUSE_BUTTON_CANCEL = 0; 82 ECORE_EVENT_MOUSE_BUTTON_CANCEL = 0;
83 ECORE_EVENT_JOYSTICK = 0;
84 ecore_input_joystick_shutdown();
79 eina_log_domain_unregister(_ecore_input_log_dom); 85 eina_log_domain_unregister(_ecore_input_log_dom);
80 _ecore_input_log_dom = -1; 86 _ecore_input_log_dom = -1;
81 ecore_shutdown(); 87 ecore_shutdown();
diff --git a/src/lib/ecore_input/ecore_input_joystick.c b/src/lib/ecore_input/ecore_input_joystick.c
new file mode 100644
index 0000000000..1f65ce48db
--- /dev/null
+++ b/src/lib/ecore_input/ecore_input_joystick.c
@@ -0,0 +1,386 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5/*FIXME: change OS specific value */
6#ifdef __linux__
7# include <linux/joystick.h>
8#endif
9
10#include <stdio.h>
11#include <fcntl.h>
12#include <unistd.h>
13
14#ifdef HAVE_EEZE
15 #include "Eeze.h"
16#endif
17#include "Ecore.h"
18#include "Ecore_Input.h"
19#include "ecore_input_private.h"
20
21static int _ecore_input_joystick_init_count = 0;
22
23#ifdef HAVE_EEZE
24
25typedef void (*Joystick_Mapper)(struct js_event *event, Ecore_Event_Joystick *e);
26static void _joystick_xiinput_mapper(struct js_event *event, Ecore_Event_Joystick *e);
27
28struct _Joystick_Info
29{
30 Ecore_Fd_Handler *fd_handler;
31 Eina_Stringshare *system_path;
32 int index;
33 Joystick_Mapper mapper;
34};
35typedef struct _Joystick_Info Joystick_Info;
36
37struct _Joystick_Mapping_Info
38{
39 const char *vendor;
40 const char *product;
41 Joystick_Mapper mapper;
42} Joystick_Mapping_Info[] = {{"045e", "028e", _joystick_xiinput_mapper}};
43
44static const char joystickPrefix[] = "/dev/input/js";
45static Eina_List *joystick_list;
46static Eeze_Udev_Watch *watch = NULL;
47
48static void
49_joystick_connected_event_add(int index, Eina_Bool connected)
50{
51 Ecore_Event_Joystick *e;
52 if (!(e = calloc(1, sizeof(Ecore_Event_Joystick)))) return;
53
54 e->index = index;
55 if (connected)
56 e->type = ECORE_EVENT_JOYSTICK_EVENT_TYPE_CONNECTED;
57 else
58 e->type = ECORE_EVENT_JOYSTICK_EVENT_TYPE_DISCONNECTED;
59
60 INF("index: %d, connected: %d", index, connected);
61 ecore_event_add(ECORE_EVENT_JOYSTICK, e, NULL, NULL);
62}
63
64static void
65_joystick_xiinput_mapper(struct js_event *event, Ecore_Event_Joystick *e)
66{
67 if (event->type == JS_EVENT_BUTTON)
68 {
69 e->type = ECORE_EVENT_JOYSTICK_EVENT_TYPE_BUTTON;
70 e->button.value = event->value;
71 switch (event->number)
72 {
73 case 0:
74 e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_FACE_0;
75 break;
76
77 case 1:
78 e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_FACE_1;
79 break;
80
81 case 2:
82 e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_FACE_2;
83 break;
84
85 case 3:
86 e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_FACE_3;
87 break;
88
89 case 4:
90 e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_LEFT_SHOULDER;
91 break;
92
93 case 5:
94 e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_RIGHT_SHOULDER;
95 break;
96
97 case 6:
98 e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_SELECT;
99 break;
100
101 case 7:
102 e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_START;
103 break;
104
105 case 8:
106 e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_META;
107 break;
108
109 case 9:
110 e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_LEFT_ANALOG_STICK;
111 break;
112
113 case 10:
114 e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_RIGHT_ANALOG_STICK;
115 break;
116
117 default:
118 ERR("Unsupported joystick event: %d", event->number);
119 break;
120 }
121 }
122 else
123 {
124 e->type = ECORE_EVENT_JOYSTICK_EVENT_TYPE_AXIS;
125 e->axis.value = event->value / 32767.0f;;
126 switch (event->number)
127 {
128 case 0:
129 e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_LEFT_ANALOG_HOR;
130 break;
131
132 case 1:
133 e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_LEFT_ANALOG_VER;
134 break;
135
136 case 2:
137 e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_LEFT_SHOULDER;
138 break;
139
140 case 3:
141 e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_RIGHT_ANALOG_HOR;
142 break;
143
144 case 4:
145 e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_RIGHT_ANALOG_VER;
146 break;
147
148 case 5:
149 e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_RIGHT_SHOULDER;
150 break;
151
152 case 6:
153 e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_HAT_X;
154 break;
155
156 case 7:
157 e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_HAT_Y;
158 break;
159
160 default:
161 ERR("Unsupported joystick event: %d", event->number);
162 break;
163 }
164 }
165}
166
167static void
168_joystick_event_add(struct js_event *event, Joystick_Info *ji)
169{
170 Ecore_Event_Joystick *e;
171
172 if ((event->type != JS_EVENT_BUTTON) && (event->type != JS_EVENT_AXIS)) return;
173 if (!(e = calloc(1, sizeof(Ecore_Event_Joystick)))) return;
174
175 e->index = ji->index;
176 e->timestamp = event->time;
177
178 ji->mapper(event, e);
179
180 ecore_event_add(ECORE_EVENT_JOYSTICK, e, NULL, NULL);
181}
182
183static Eina_Bool
184_fd_handler_cb(void* userData, Ecore_Fd_Handler* fdHandler)
185{
186 int fd;
187 Joystick_Info *ji = userData;
188 struct js_event event;
189 ssize_t len;
190
191 fd = ecore_main_fd_handler_fd_get(fdHandler);
192
193 len = read(fd, &event, sizeof(event));
194 if (len == -1) return ECORE_CALLBACK_RENEW;
195
196 INF("index: %d, type: %d, number: %d, value: %d",
197 ji->index, event.type, event.number, event.value);
198
199 _joystick_event_add(&event, ji);
200
201 return ECORE_CALLBACK_RENEW;
202}
203
204static Joystick_Mapper
205_joystick_mapping_info_get(const char* syspath)
206{
207 int index, mapping_info_size;
208 const char *parent, *vendor, *product;
209 Joystick_Mapper ret;
210
211 ret = NULL;
212 parent = eeze_udev_syspath_get_parent_filtered(syspath, "input", NULL);
213 vendor = eeze_udev_syspath_get_sysattr(parent, "id/vendor");
214 product = eeze_udev_syspath_get_sysattr(parent, "id/product");
215
216 mapping_info_size = (int)(sizeof(Joystick_Mapping_Info) / sizeof(Joystick_Mapping_Info[0]));
217 for (index = 0; index < mapping_info_size; index++)
218 {
219 if ((vendor && !strcmp(vendor, Joystick_Mapping_Info[index].vendor)) &&
220 (product && !strcmp(product, Joystick_Mapping_Info[index].product)))
221 {
222 INF("joystick mapping info found (vendor: %s, product: %s)", vendor, product);
223 ret = Joystick_Mapping_Info[index].mapper;
224 break;
225 }
226 }
227
228 eina_stringshare_del(parent);
229 eina_stringshare_del(vendor);
230 eina_stringshare_del(product);
231
232 return ret;
233}
234
235static int
236_joystick_index_get(const char *dev)
237{
238 int plen, dlen, diff, ret = -1;
239
240 dlen = strlen(dev);
241 plen = strlen(joystickPrefix);
242 diff = dlen - plen;
243
244 if (diff > 0)
245 {
246 ret = atoi(dev + plen);
247 }
248
249 return ret;
250}
251
252static void
253_joystick_register(const char* syspath)
254{
255 int fd, index;
256 const char *devnode;
257 Joystick_Info *ji;
258 Joystick_Mapper mapper;
259
260 devnode = eeze_udev_syspath_get_devpath(syspath);
261 if (!devnode) return;
262 if (!eina_str_has_prefix(devnode, joystickPrefix)) goto register_failed;
263
264 mapper = _joystick_mapping_info_get(syspath);
265 if (!mapper)
266 {
267 ERR("Unsupported joystick.");
268 goto register_failed;
269 }
270
271 index = _joystick_index_get(devnode);
272 if (index == -1)
273 {
274 ERR("Invalid index value.");
275 goto register_failed;
276 }
277
278 ji = calloc(1, sizeof(Joystick_Info));
279 if (!ji)
280 {
281 ERR("Cannot allocate memory.");
282 goto register_failed;
283 }
284
285 ji->index = index;
286 ji->mapper = mapper;
287 ji->system_path = eina_stringshare_ref(syspath);
288
289 fd = open(devnode, O_RDONLY | O_NONBLOCK);
290 ji->fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ,
291 _fd_handler_cb, ji, 0, 0);
292
293 joystick_list = eina_list_append(joystick_list, ji);
294 _joystick_connected_event_add(index, EINA_TRUE);
295
296register_failed:
297 eina_stringshare_del(devnode);
298}
299
300static void
301_joystick_unregister(const char *syspath)
302{
303 int fd;
304 Eina_List *l, *l2;
305 Joystick_Info *ji;
306
307 EINA_LIST_FOREACH_SAFE(joystick_list, l, l2, ji)
308 {
309 if (syspath == ji->system_path)
310 {
311 fd = ecore_main_fd_handler_fd_get(ji->fd_handler);
312 close(fd);
313 ecore_main_fd_handler_del(ji->fd_handler);
314 joystick_list = eina_list_remove(joystick_list, ji);
315 _joystick_connected_event_add(ji->index, EINA_FALSE);
316 eina_stringshare_del(ji->system_path);
317 free(ji);
318 break;
319 }
320 }
321}
322
323static void
324_watch_cb(const char *syspath, Eeze_Udev_Event event,
325 void *data EINA_UNUSED, Eeze_Udev_Watch *w EINA_UNUSED)
326{
327 switch (event) {
328 case EEZE_UDEV_EVENT_ADD:
329 _joystick_register(syspath);
330 break;
331 case EEZE_UDEV_EVENT_REMOVE:
332 _joystick_unregister(syspath);
333 break;
334 default:
335 break;
336 }
337
338 eina_stringshare_del(syspath);
339}
340#endif
341
342int
343ecore_input_joystick_init(void)
344{
345#ifdef HAVE_EEZE
346 Eina_List *syspaths;
347 const char *syspath;
348
349 if (++_ecore_input_joystick_init_count != 1)
350 return _ecore_input_joystick_init_count;
351
352 if (!eeze_init())
353 return --_ecore_input_joystick_init_count;
354
355 watch = eeze_udev_watch_add(EEZE_UDEV_TYPE_JOYSTICK,
356 (EEZE_UDEV_EVENT_ADD | EEZE_UDEV_EVENT_REMOVE),
357 _watch_cb, NULL);
358
359 syspaths = eeze_udev_find_by_type(EEZE_UDEV_TYPE_JOYSTICK, NULL);
360 EINA_LIST_FREE(syspaths, syspath)
361 {
362 _joystick_register(syspath);
363 eina_stringshare_del(syspath);
364 }
365#endif
366
367 return _ecore_input_joystick_init_count;
368}
369
370int
371ecore_input_joystick_shutdown(void)
372{
373#ifdef HAVE_EEZE
374 if (--_ecore_input_joystick_init_count != 0)
375 return _ecore_input_joystick_init_count;
376
377 if (watch)
378 {
379 eeze_udev_watch_del(watch);
380 watch = NULL;
381 }
382 eeze_shutdown();
383#endif
384
385 return _ecore_input_joystick_init_count;
386}
diff --git a/src/lib/ecore_input/ecore_input_private.h b/src/lib/ecore_input/ecore_input_private.h
index 70af2276e7..4d085a19b4 100644
--- a/src/lib/ecore_input/ecore_input_private.h
+++ b/src/lib/ecore_input/ecore_input_private.h
@@ -34,4 +34,6 @@ extern int _ecore_input_log_dom;
34#endif 34#endif
35#define CRI(...) EINA_LOG_DOM_CRIT(_ecore_input_log_dom, __VA_ARGS__) 35#define CRI(...) EINA_LOG_DOM_CRIT(_ecore_input_log_dom, __VA_ARGS__)
36 36
37int ecore_input_joystick_init(void);
38int ecore_input_joystick_shutdown(void);
37#endif 39#endif