e_input: add E_API e_input_device_mouse_accel_enable_set(device_name, enable)
[platform/upstream/enlightenment.git] / src / bin / e_info_server_input.c
1 #include "e.h"
2 #include "e_info_server_input.h"
3 #include "e_info_shared_types.h"
4 #include "e_input_private.h"
5
6 #include <linux/uinput.h>
7
8 #ifndef KEY_LIGHTS_TOGGLE
9 #define KEY_LIGHTS_TOGGLE 0x21e
10 #endif
11 #ifndef KEY_ALS_TOGGLE
12 #define KEY_ALS_TOGGLE 0x230
13 #endif
14 #ifndef KEY_ONSCREEN_KEYBOARD
15 #define KEY_ONSCREEN_KEYBOARD 0x278
16 #endif
17
18 typedef struct _E_Info_Server_Input
19 {
20    struct
21      {
22         Eina_Bool virtual_dev;
23         int fd;
24         Eina_Stringshare *name;
25      } gen;
26 } E_Info_Server_Input;
27
28 static E_Info_Server_Input _e_info_input =
29 {
30   {
31      EINA_FALSE, /* virtual_dev */
32      -1,         /* fd */
33      NULL        /* dev_name */
34   }
35 };
36
37 static void
38 _e_info_input_set_keyboard(struct uinput_user_dev *uinput_dev, int uinput_fd)
39 {
40    int i;
41
42    for (i = KEY_ESC; i <= KEY_MICMUTE; i++)
43      ioctl(uinput_fd, UI_SET_KEYBIT, i);
44    for (i = KEY_OK; i <= KEY_LIGHTS_TOGGLE; i++)
45      ioctl(uinput_fd, UI_SET_KEYBIT, i);
46    for (i = KEY_ALS_TOGGLE; i <= KEY_ONSCREEN_KEYBOARD; i++)
47      ioctl(uinput_fd, UI_SET_KEYBIT, i);
48 }
49
50 static void
51 _e_info_input_set_touch(struct uinput_user_dev *uinput_dev, int uinput_fd)
52 {
53    E_Output *output;
54    int w = 0, h = 0;
55    int max_mt_slot = 9;//set touch max count 10 by default
56
57    output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
58    e_output_size_get(output, &w, &h);
59
60    if ((w <= 0) || (h <= 0))
61      WRN("Failed to get output size for creating touch device in e_info. So set arbitrary output size [%d x %d]\n", w, h);
62
63    if (w <= 0) w = 4096;
64    if (h <= 0) h = 4096;
65
66    if (e_config->configured_max_touch.use)
67      {
68         max_mt_slot = e_config->configured_max_touch.count - 1;
69
70         if (max_mt_slot < 0)
71           max_mt_slot = 9;//set touch max count 10 by default
72      }
73
74    ioctl(uinput_fd, UI_SET_EVBIT, EV_ABS);
75
76    ioctl(uinput_fd, UI_SET_KEYBIT, BTN_TOUCH);
77    ioctl(uinput_fd, UI_SET_ABSBIT, ABS_X);
78    ioctl(uinput_fd, UI_SET_ABSBIT, ABS_Y);
79    ioctl(uinput_fd, UI_SET_ABSBIT, ABS_MT_SLOT);
80    ioctl(uinput_fd, UI_SET_ABSBIT, ABS_MT_TOUCH_MAJOR);
81    ioctl(uinput_fd, UI_SET_ABSBIT, ABS_MT_TOUCH_MINOR);
82    ioctl(uinput_fd, UI_SET_ABSBIT, ABS_MT_WIDTH_MAJOR);
83    ioctl(uinput_fd, UI_SET_ABSBIT, ABS_MT_POSITION_X);
84    ioctl(uinput_fd, UI_SET_ABSBIT, ABS_MT_POSITION_Y);
85    ioctl(uinput_fd, UI_SET_ABSBIT, ABS_MT_TRACKING_ID);
86
87    uinput_dev->absmin[ABS_X] = 0;
88    uinput_dev->absmax[ABS_X] = w - 1;
89    uinput_dev->absmin[ABS_Y] = 0;
90    uinput_dev->absmax[ABS_Y] = h - 1;
91    uinput_dev->absmin[ABS_MT_SLOT] = 0;
92    uinput_dev->absmax[ABS_MT_SLOT] = max_mt_slot;
93    uinput_dev->absmin[ABS_MT_TOUCH_MAJOR] = 0;
94    uinput_dev->absmax[ABS_MT_TOUCH_MAJOR] = 255;
95    uinput_dev->absmin[ABS_MT_TOUCH_MINOR] = 0;
96    uinput_dev->absmax[ABS_MT_TOUCH_MINOR] = 255;
97    uinput_dev->absmin[ABS_MT_WIDTH_MAJOR] = 0;
98    uinput_dev->absmax[ABS_MT_WIDTH_MAJOR] = 255;
99    uinput_dev->absmin[ABS_MT_POSITION_X] = 0;
100    uinput_dev->absmax[ABS_MT_POSITION_X] = w - 1;
101    uinput_dev->absmin[ABS_MT_POSITION_Y] = 0;
102    uinput_dev->absmax[ABS_MT_POSITION_Y] = h - 1;
103    uinput_dev->absmin[ABS_MT_TRACKING_ID] = 0;
104    uinput_dev->absmax[ABS_MT_TRACKING_ID] = 65535;
105    uinput_dev->absmin[ABS_MT_ORIENTATION] = 0;
106    uinput_dev->absmax[ABS_MT_ORIENTATION] = 2;
107 }
108
109 static void
110 _e_info_input_set_pointer(struct uinput_user_dev *uinput_dev, int uinput_fd)
111 {
112    int i;
113
114    ioctl(uinput_fd, UI_SET_EVBIT, EV_REL);
115
116    ioctl(uinput_fd, UI_SET_RELBIT, REL_X);
117    ioctl(uinput_fd, UI_SET_RELBIT, REL_Y);
118    ioctl(uinput_fd, UI_SET_RELBIT, REL_WHEEL);
119    ioctl(uinput_fd, UI_SET_RELBIT, REL_HWHEEL);
120
121    for (i = BTN_MISC; i <= BTN_TASK; i++)
122      ioctl(uinput_fd, UI_SET_KEYBIT, i);
123 }
124
125 int _e_info_input_create_device(const char *dev_name, unsigned int type)
126 {
127    int uinput_fd = -1, nwrite = 0;
128    struct uinput_user_dev uinput_dev = {0, };
129
130    uinput_fd = open("/dev/uinput", O_WRONLY | O_NDELAY);
131    EINA_SAFETY_ON_FALSE_RETURN_VAL(uinput_fd >= 0, -1);
132
133    strncpy(uinput_dev.name, dev_name, UINPUT_MAX_NAME_SIZE - 1);
134    uinput_dev.id.version = 4;
135    uinput_dev.id.bustype = BUS_VIRTUAL;
136
137    ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY);
138    ioctl(uinput_fd, UI_SET_EVBIT, EV_SYN);
139    ioctl(uinput_fd, UI_SET_EVBIT, EV_MSC);
140    ioctl(uinput_fd, UI_SET_MSCBIT, MSC_SCAN);
141
142    if (type & E_INPUT_SEAT_KEYBOARD)
143      {
144         _e_info_input_set_keyboard(&uinput_dev, uinput_fd);
145      }
146    if (type & E_INPUT_SEAT_TOUCH)
147      {
148         _e_info_input_set_touch(&uinput_dev, uinput_fd);
149      }
150    if (type & E_INPUT_SEAT_POINTER)
151      {
152         _e_info_input_set_pointer(&uinput_dev, uinput_fd);
153      }
154
155    /* Create input device into input sub-system */
156    nwrite = write(uinput_fd, &uinput_dev, sizeof(uinput_dev));
157    if (nwrite < 0) WRN("Failed to write for create device using uinput (err: %m)\n");
158
159    if (ioctl(uinput_fd, UI_DEV_CREATE))
160      {
161         WRN("Failed to create %s device (err: %m)", dev_name);
162         close (uinput_fd);
163         return -1;
164      }
165
166    return uinput_fd;
167 }
168
169 static int
170 _e_info_input_open_device(char *identifier)
171 {
172    int fd = -1;
173
174    fd = open(identifier, O_WRONLY | O_NDELAY);
175    if (fd < 0)
176      {
177         ERR("Failed to open %s node. (err: %m)\n", identifier);
178         return -1;
179      }
180
181    return fd;
182 }
183
184 static int
185 _write_event_to_device_node(int type, int code, int value)
186 {
187    int nwrite;
188    struct input_event ev;
189
190    gettimeofday(&ev.time, NULL);
191
192    ev.type = type;
193    ev.code = code;
194    ev.value = value;
195
196    nwrite = write(_e_info_input.gen.fd, &ev, sizeof(ev));
197
198    return nwrite;
199 }
200
201 static void
202 _key_gen(int keycode, int value)
203 {
204    _write_event_to_device_node(EV_KEY, keycode, value);
205 }
206
207 static void
208 _sync_gen(void)
209 {
210    _write_event_to_device_node(EV_SYN, 0, 0);
211 }
212
213 static void
214 _key_gen_down(int key_code)
215 {
216    _key_gen(key_code, 1);
217    _sync_gen();
218 }
219
220 static void
221 _key_gen_up(int key_code)
222 {
223    _key_gen(key_code, 0);
224    _sync_gen();
225 }
226
227 static void
228 _touch_gen_mt_slot(int value)
229 {
230    _write_event_to_device_node(EV_ABS, ABS_MT_SLOT, value);
231 }
232
233 static void
234 _touch_gen_mt_tracking_id(int value)
235 {
236    _write_event_to_device_node(EV_ABS, ABS_MT_TRACKING_ID, value);
237 }
238
239 static void
240 _touch_gen_mt_touch_major(int value)
241 {
242    _write_event_to_device_node(EV_ABS, ABS_MT_TOUCH_MAJOR, value);
243 }
244
245 static void
246 _touch_gen_mt_touch_minor(int value)
247 {
248    _write_event_to_device_node(EV_ABS, ABS_MT_TOUCH_MINOR, value);
249 }
250
251 static void
252 _touch_gen_mt_position_x(int value)
253 {
254    _write_event_to_device_node(EV_ABS, ABS_MT_POSITION_X, value);
255 }
256
257 static void
258 _touch_gen_mt_position_y(int value)
259 {
260    _write_event_to_device_node(EV_ABS, ABS_MT_POSITION_Y, value);
261 }
262
263 static int
264 _convert_button(int button)
265 {
266    switch (button)
267      {
268         case 0:
269           return BTN_LEFT;
270         case 1:
271           return BTN_RIGHT;
272         case 2:
273           return BTN_MIDDLE;
274         default:
275           return button;
276      }
277 }
278
279 static void
280 _pointer_gen_x(int value)
281 {
282    _write_event_to_device_node(EV_REL, REL_X, value);
283 }
284
285 static void
286 _pointer_gen_y(int value)
287 {
288    _write_event_to_device_node(EV_REL, REL_Y, value);
289 }
290
291 static void
292 _pointer_gen_button(int button, int value)
293 {
294    _write_event_to_device_node(EV_KEY, button, value);
295 }
296
297 static void
298 _pointer_gen_wheel(int value)
299 {
300    _write_event_to_device_node(EV_REL, REL_WHEEL, value);
301    _sync_gen();
302 }
303
304 static void
305 _pointer_gen_hwheel(int value)
306 {
307    _write_event_to_device_node(EV_REL, REL_HWHEEL, value);
308    _sync_gen();
309 }
310
311 static void
312 _touch_gen_down(int idx, int x, int y)
313 {
314 #define MAX_TRACKING_ID 65535
315    static int tracking_id = 0;
316
317    _touch_gen_mt_slot(idx);
318    _touch_gen_mt_tracking_id(tracking_id);
319    tracking_id++;
320    if (tracking_id > MAX_TRACKING_ID)
321      tracking_id = 0;
322
323    _touch_gen_mt_touch_major(10);
324    _touch_gen_mt_touch_minor(5);
325    _touch_gen_mt_position_x(x);
326    _touch_gen_mt_position_y(y);
327    _sync_gen();
328 }
329
330 static void
331 _touch_gen_move(int idx, int x, int y)
332 {
333    _touch_gen_mt_slot(idx);
334    _touch_gen_mt_position_x(x);
335    _touch_gen_mt_position_y(y);
336    _sync_gen();
337 }
338
339 static void
340 _touch_gen_up(int idx)
341 {
342    _touch_gen_mt_slot(idx);
343    _touch_gen_mt_tracking_id(-1);
344    _sync_gen();
345 }
346
347 static void
348 _button_gen_down(int button)
349 {
350    if (button < 3)
351      button = _convert_button(button);
352
353    _pointer_gen_button(button, 1);
354    _sync_gen();
355 }
356
357 static void
358 _button_gen_up(int button)
359 {
360    if (button < 3)
361      button = _convert_button(button);
362
363    _pointer_gen_button(button, 0);
364    _sync_gen();
365 }
366
367 static void
368 _pointer_gen_move(int x, int y)
369 {
370    if (x != 0) _pointer_gen_x(x);
371    if (y != 0) _pointer_gen_y(y);
372    _sync_gen();
373 }
374
375 static void
376 _e_info_input_keygen(int key_code, int key_state)
377 {
378    switch (key_state)
379      {
380         case E_INFO_EVENT_STATE_PRESS:
381           _key_gen_down(key_code);
382           break;
383         case E_INFO_EVENT_STATE_RELEASE:
384           _key_gen_up(key_code);
385           break;
386         case E_INFO_EVENT_STATE_ALL:
387           _key_gen_down(key_code);
388           _key_gen_up(key_code);
389           break;
390         default:
391           return;
392      }
393 }
394
395 static void
396 _e_info_input_touchgen(int idx, int x, int y, int touch_state)
397 {
398    switch (touch_state)
399      {
400         case E_INFO_EVENT_STATE_PRESS:
401           _touch_gen_down(idx, x, y);
402           break;
403         case E_INFO_EVENT_STATE_RELEASE:
404           _touch_gen_up(idx);
405           break;
406         case E_INFO_EVENT_STATE_MOTION:
407           _touch_gen_move(idx, x, y);
408           break;
409         case E_INFO_EVENT_STATE_ALL:
410           _touch_gen_down(idx, x, y);
411           _touch_gen_move(idx, x, y);
412           _touch_gen_up(idx);
413           break;
414         default:
415           return;
416      }
417 }
418
419 static void
420 _e_info_input_mousegen(int button, int x, int y, int mouse_state)
421 {
422    switch (mouse_state)
423      {
424         case E_INFO_EVENT_STATE_PRESS:
425           _button_gen_down(button);
426           break;
427         case E_INFO_EVENT_STATE_RELEASE:
428           _button_gen_up(button);
429           break;
430         case E_INFO_EVENT_STATE_MOTION:
431           if (button == E_INFO_BUTTON_WHEEL)
432             {
433                _pointer_gen_wheel(x);
434             }
435           else if (button == E_INFO_BUTTON_HWHEEL)
436             {
437                _pointer_gen_hwheel(y);
438             }
439           else
440             _pointer_gen_move(x, y);
441           break;
442         case E_INFO_EVENT_STATE_ALL:
443           _button_gen_down(button);
444           _button_gen_up(button);
445           break;
446         default:
447           return;
448      }
449 }
450
451 static void
452 _e_info_input_close_device(void)
453 {
454    int ret;
455
456    if (_e_info_input.gen.virtual_dev)
457      {
458         ret = ioctl(_e_info_input.gen.fd, UI_DEV_DESTROY, NULL);
459         if (ret) WRN("Failed destroy fd: %d (ret: %d) (err: %m)\n", _e_info_input.gen.fd, ret);
460      }
461    close(_e_info_input.gen.fd);
462
463    _e_info_input.gen.fd = -1;
464    _e_info_input.gen.virtual_dev = EINA_FALSE;
465 }
466
467 char *
468 e_info_server_input_init_device(unsigned int type, char *name)
469 {
470    int fd = -1;
471    Eina_List *device_list, *l;
472    Ecore_Device *dev;
473
474    if (_e_info_input.gen.fd >=0) return "Already opened device is exist";
475    if (type)
476      {
477         fd = _e_info_input_create_device(name, type);
478         _e_info_input.gen.virtual_dev = EINA_TRUE;
479         _e_info_input.gen.fd = fd;
480         if (_e_info_input.gen.name)
481           eina_stringshare_del(_e_info_input.gen.name);
482         _e_info_input.gen.name = eina_stringshare_add(name);
483      }
484    else
485      {
486         device_list = (Eina_List *)ecore_device_list();
487         EINA_SAFETY_ON_NULL_RETURN_VAL(device_list, "No Opened device");
488
489         EINA_LIST_FOREACH(device_list, l, dev)
490           {
491              if (!e_util_strcmp(name, ecore_device_identifier_get(dev)))
492                {
493                   fd = _e_info_input_open_device(name);
494                   _e_info_input.gen.virtual_dev = EINA_FALSE;
495                   _e_info_input.gen.fd = fd;
496                   if (_e_info_input.gen.name)
497                     eina_stringshare_del(_e_info_input.gen.name);
498                   _e_info_input.gen.name = eina_stringshare_add(name);
499                }
500           }
501      }
502
503    if (fd < 0)
504      {
505         _e_info_input.gen.virtual_dev = EINA_FALSE;
506         _e_info_input.gen.fd = -1;
507         if (_e_info_input.gen.name)
508           eina_stringshare_del(_e_info_input.gen.name);
509         _e_info_input.gen.name = NULL;
510         return "Failed to open event node or uinput node";
511      }
512
513    return E_INFO_INPUT_RESULT_NONE;
514 }
515
516 void
517 e_info_server_input_deinit_device(void)
518 {
519    if (_e_info_input.gen.fd < 0) return;
520
521    if (_e_info_input.gen.virtual_dev)
522      _e_info_input_close_device();
523    else
524      {
525         close(_e_info_input.gen.fd);
526
527         _e_info_input.gen.fd = -1;
528         _e_info_input.gen.virtual_dev = EINA_FALSE;
529      }
530    if (_e_info_input.gen.name)
531      eina_stringshare_del(_e_info_input.gen.name);
532    _e_info_input.gen.name = NULL;
533
534    return;
535 }
536
537 char *
538 e_info_server_input_keygen(char *name, int code, int state)
539 {
540    if (_e_info_input.gen.fd < 0) return "Initialize device first";
541
542    if (strlen(name) > 0)
543      {
544         code = e_comp_wl_input_keymap_keyname_to_keycode(name) - 8;
545      }
546    else
547      code = code - 8;
548
549    _e_info_input_keygen(code, state);
550
551    return E_INFO_INPUT_RESULT_NONE;
552 }
553
554 char *
555 e_info_server_input_touchgen(int idx, int x, int y, int state)
556 {
557    if (_e_info_input.gen.fd < 0) return "Initialize device first";
558
559    _e_info_input_touchgen(idx, x, y, state);
560
561    return E_INFO_INPUT_RESULT_NONE;
562 }
563
564 char *
565 e_info_server_input_mousegen(int button, int x, int y, int state)
566 {
567    if (_e_info_input.gen.fd < 0) return "Initialize device first";
568
569    _e_info_input_mousegen(button, x, y, state);
570
571    return E_INFO_INPUT_RESULT_NONE;
572 }
573
574 char *
575 e_info_server_input_mouse_accel_set(int state)
576 {
577    if (_e_info_input.gen.fd < 0) return "Initialize device first";
578
579    if (e_input_device_mouse_accel_enable_set(_e_info_input.gen.name, state))
580      return E_INFO_INPUT_RESULT_NONE;
581
582    return "Failed to set mouse_accel";
583 }
584
585 char *
586 e_info_server_input_log_enable_set(int state)
587 {
588    E_Comp_Config *conf;
589
590    conf = e_comp_config_get();
591    if (!conf) return "Comp_conf is not valid";
592
593    if (state == 1 || state == 0)
594      {
595         conf->input_log_enable = state;
596         return E_INFO_INPUT_RESULT_NONE;
597
598      }
599
600    return "Input proper value [1: on][0: off]";
601 }