Remove unused code
[platform/upstream/enlightenment.git] / src / bin / e_input_inputs.c
1 #include "e.h"
2 #include "e_input_private.h"
3 #include "e_input_event.h"
4
5 #include <glib.h>
6
7 static gboolean input_dispatch(GSource *source, GSourceFunc callback, gpointer user_data);
8 static gboolean input_thread_prepare(GSource *source, gint *time);
9
10 static E_Input_Event_Source *g_input_event_source = NULL;
11
12 GSourceFuncs input_event_funcs = {
13    .prepare = input_thread_prepare,
14    .check = NULL,
15    .dispatch = input_dispatch,
16    .finalize = NULL
17 };
18
19 typedef struct
20 {
21    GSource gsource;
22    gpointer tag;
23 } InputEventSource;
24
25 static char *
26 _e_input_ecore_device_class_to_string(Ecore_Device_Class clas)
27 {
28    switch (clas)
29      {
30         case ECORE_DEVICE_CLASS_NONE:
31           return "None";
32           break;
33         case ECORE_DEVICE_CLASS_SEAT:
34           return "Seat";
35           break;
36         case ECORE_DEVICE_CLASS_KEYBOARD:
37           return "Keyboard";
38           break;
39         case ECORE_DEVICE_CLASS_MOUSE:
40           return "Mouse";
41           break;
42         case ECORE_DEVICE_CLASS_TOUCH:
43           return "Touch";
44           break;
45         case ECORE_DEVICE_CLASS_PEN:
46           return "Pen";
47           break;
48         case ECORE_DEVICE_CLASS_WAND:
49           return "Wand";
50           break;
51         case ECORE_DEVICE_CLASS_GAMEPAD:
52           return "Gamepad";
53           break;
54         default:
55           return "Unknown";
56      }
57 }
58
59 static Ecore_Device_Class
60 _e_input_seat_cap_to_ecore_device_class(unsigned int cap)
61 {
62    switch(cap)
63      {
64       case E_INPUT_SEAT_POINTER:
65          return ECORE_DEVICE_CLASS_MOUSE;
66       case E_INPUT_SEAT_KEYBOARD:
67          return ECORE_DEVICE_CLASS_KEYBOARD;
68       case E_INPUT_SEAT_TOUCH:
69          return ECORE_DEVICE_CLASS_TOUCH;
70       default:
71          return ECORE_DEVICE_CLASS_NONE;
72      }
73    return ECORE_DEVICE_CLASS_NONE;
74 }
75
76 static void
77 _e_input_ecore_device_info_free(void *data EINA_UNUSED, void *ev)
78 {
79    Ecore_Event_Device_Info *e;
80
81    e = ev;
82    eina_stringshare_del(e->name);
83    eina_stringshare_del(e->identifier);
84    eina_stringshare_del(e->seatname);
85
86    free(e);
87 }
88
89 void
90 _e_input_ecore_device_event(Ecore_Device *dev, const char* seat_name, Eina_Bool flag)
91 {
92    Ecore_Event_Device_Info *e;
93    E_Input *e_input;
94    const char *name, *identifier;
95
96    ecore_thread_main_loop_begin();
97
98    if (!(name = ecore_device_name_get(dev))) goto end;
99    if (!(identifier = ecore_device_identifier_get(dev))) goto end;
100
101    if (!(e = calloc(1, sizeof(Ecore_Event_Device_Info)))) goto end;
102
103    e_input = e_input_get();
104
105    e->window = e_input?e_input->window:(Ecore_Window)0;
106    e->name = eina_stringshare_add(name);
107    e->identifier = eina_stringshare_add(identifier);
108    if (seat_name && strlen(seat_name))
109      e->seatname = eina_stringshare_add(seat_name);
110    else
111      e->seatname = eina_stringshare_add(name);
112    e->clas = ecore_device_class_get(dev);
113    e->subclas = ecore_device_subclass_get(dev);
114
115    if (flag)
116      ecore_event_add(ECORE_EVENT_DEVICE_ADD, e, _e_input_ecore_device_info_free, NULL);
117    else
118      ecore_event_add(ECORE_EVENT_DEVICE_DEL, e, _e_input_ecore_device_info_free, NULL);
119
120 end:
121    ecore_thread_main_loop_end();
122 }
123
124 static E_Input_Seat *
125 _seat_create(E_Input_Backend *input, const char *seat)
126 {
127    E_Input_Seat *s;
128    Ecore_Device *ecore_dev = NULL;
129    E_Device *e_dev = NULL;
130
131    ecore_thread_main_loop_begin();
132
133    /* create an evas device of a seat */
134    ecore_dev = ecore_device_add();
135    if (!ecore_dev)
136      {
137         ERR("Failed to create an ecore device for a seat !\n");
138         ecore_thread_main_loop_end();
139                 return NULL;
140      }
141
142    ecore_device_name_set(ecore_dev, seat);
143    ecore_device_identifier_set(ecore_dev, "Enlightenment seat");
144    ecore_device_class_set(ecore_dev, ECORE_DEVICE_CLASS_SEAT);
145    ecore_device_subclass_set(ecore_dev, ECORE_DEVICE_SUBCLASS_NONE);
146
147    /* create an e device of a seat */
148    e_dev = e_device_new();
149    if (!e_dev)
150      {
151         ERR("Failed to create an ecore device for a seat !\n");
152         ecore_thread_main_loop_end();
153                 return NULL;
154      }
155
156    e_device_name_set(e_dev, seat);
157    e_device_identifier_set(e_dev, "Enlightenment seat");
158    e_device_class_set(e_dev, ECORE_DEVICE_CLASS_SEAT);
159    e_device_subclass_set(e_dev, ECORE_DEVICE_SUBCLASS_NONE);
160
161    /* try to allocate space for new seat */
162    if (!(s = calloc(1, sizeof(E_Input_Seat))))
163      {
164         ecore_device_del(ecore_dev);
165         ecore_thread_main_loop_end();
166         return NULL;
167      }
168
169    s->input = input;
170    s->name = eina_stringshare_add(seat);
171    s->ecore_dev = ecore_dev;
172    s->e_dev = e_dev;
173
174    /* add this new seat to list */
175    input->dev->seats = eina_list_append(input->dev->seats, s);
176    s->dev = input->dev;
177
178    ecore_event_add(E_INPUT_EVENT_SEAT_ADD, NULL, NULL, NULL);
179    ecore_thread_main_loop_end();
180
181    _e_input_ecore_device_event(ecore_dev, seat, EINA_TRUE);
182
183    return s;
184 }
185
186 static E_Input_Seat *
187 _seat_get(E_Input_Backend *input, const char *seat)
188 {
189    E_Input_Seat *s;
190    Eina_List *l;
191
192    /* search for this name in existing seats */
193    EINA_LIST_FOREACH(input->dev->seats, l, s)
194      if (!strcmp(s->name, seat))
195        return s;
196
197    return _seat_create(input, seat);
198 }
199
200 static Eina_Bool
201 _e_input_add_ecore_device(E_Input_Evdev *edev, Ecore_Device_Class clas)
202 {
203    const Eina_List *dev_list = NULL;
204    const Eina_List *l;
205    Ecore_Device *dev = NULL;
206    E_Device *e_dev = NULL;
207    const char *identifier;
208
209    if (!edev || !edev->path) return EINA_FALSE;
210
211    ecore_thread_main_loop_begin();
212
213    dev_list = ecore_device_list();
214    if (dev_list)
215      {
216         EINA_LIST_FOREACH(dev_list, l, dev)
217           {
218              if (!dev) continue;
219              identifier = ecore_device_identifier_get(dev);
220              if (!identifier) continue;
221              if ((ecore_device_class_get(dev) == clas) && (!strcmp(identifier, edev->path)))
222                {
223                   ecore_thread_main_loop_end();
224                   return EINA_FALSE;
225                }
226           }
227      }
228
229    // create ecore device info
230    dev = ecore_device_add();
231    if (!dev)
232      {
233         edev->ecore_dev = NULL;
234         ecore_thread_main_loop_end();
235         return EINA_FALSE;
236      }
237
238    ecore_device_name_set(dev, libinput_device_get_name(edev->device));
239    ecore_device_identifier_set(dev, edev->path);
240    ecore_device_class_set(dev, clas);
241    ecore_device_subclass_set(dev, ECORE_DEVICE_SUBCLASS_NONE);
242
243    if (!edev->ecore_dev)
244      {
245         if (!edev->ecore_dev_list || (eina_list_count(edev->ecore_dev_list) == 0))
246           {
247              /* 1st Ecore_Device is added */
248              edev->ecore_dev = ecore_device_ref(dev);
249           }
250         else
251           {
252              /* 3rd or more Ecore_Device is added */
253              edev->ecore_dev_list = eina_list_append(edev->ecore_dev_list, ecore_device_ref(dev));
254           }
255      }
256    else
257      {
258         /* 2nd Ecore_Device is added */
259         edev->ecore_dev_list = eina_list_append(edev->ecore_dev_list, edev->ecore_dev);
260         edev->ecore_dev = NULL;
261
262         edev->ecore_dev_list = eina_list_append(edev->ecore_dev_list, ecore_device_ref(dev));
263      }
264
265    // create E_Device info
266    e_dev = e_device_new();
267    if (!e_dev)
268      {
269         edev->e_dev = NULL;
270         ecore_thread_main_loop_end();
271         return EINA_FALSE;
272      }
273
274    e_device_name_set(e_dev, libinput_device_get_name(edev->device));
275    e_device_identifier_set(e_dev, edev->path);
276    e_device_class_set(e_dev, clas);
277    e_device_subclass_set(e_dev, ECORE_DEVICE_SUBCLASS_NONE);
278
279    if (!edev->e_dev)
280      {
281         if (!edev->e_dev_list || (g_list_length(edev->e_dev_list) == 0))
282           {
283              /* 1st Ecore_Device is added */
284              edev->e_dev = g_object_ref(e_dev);
285           }
286         else
287           {
288              /* 3rd or more Ecore_Device is added */
289              edev->e_dev_list = g_list_append(edev->e_dev_list, g_object_ref(e_dev));
290           }
291      }
292    else
293      {
294         /* 2nd Ecore_Device is added */
295         edev->e_dev_list = g_list_append(edev->e_dev_list, edev->e_dev);
296         edev->e_dev = NULL;
297
298         edev->e_dev_list = g_list_append(edev->e_dev_list, g_object_ref(e_dev));
299      }
300
301    _e_input_ecore_device_event(dev, edev->seat ? edev->seat->name : NULL, EINA_TRUE);
302
303    ecore_thread_main_loop_end();
304    return EINA_TRUE;
305 }
306
307 static Eina_Bool
308 _e_input_remove_ecore_device(E_Input_Evdev *edev, Ecore_Device_Class clas)
309 {
310    const Eina_List *dev_list = NULL, *l;
311    Eina_List *ll, *ll_next;
312    Ecore_Device *dev = NULL, *data;
313    const char *identifier;
314
315    if (!edev->path) return EINA_FALSE;
316
317    dev_list = ecore_device_list();
318    if (!dev_list) return EINA_FALSE;
319
320    ecore_thread_main_loop_begin();
321    EINA_LIST_FOREACH(dev_list, l, dev)
322       {
323          if (!dev) continue;
324          identifier = ecore_device_identifier_get(dev);
325          if (!identifier) continue;
326          if ((ecore_device_class_get(dev) == clas) && (!strcmp(identifier, edev->path)))
327            {
328               if (edev->ecore_dev)
329                 {
330                    ecore_device_unref(dev);
331                    edev->ecore_dev = NULL;
332                 }
333               else if (edev->ecore_dev_list)
334                 {
335                    EINA_LIST_FOREACH_SAFE(edev->ecore_dev_list, ll, ll_next, data)
336                      {
337                         if (data == dev)
338                           {
339                              ecore_device_unref(dev);
340                              edev->ecore_dev_list = eina_list_remove_list(edev->ecore_dev_list, ll);
341                           }
342                      }
343                 }
344               _e_input_ecore_device_event(dev, edev->seat ? edev->seat->name : NULL, EINA_FALSE);
345               ecore_device_del(dev);
346               ecore_thread_main_loop_end();
347               return EINA_TRUE;
348            }
349       }
350    ecore_thread_main_loop_end();
351    return EINA_FALSE;
352 }
353
354 Eina_Bool
355 _e_input_device_add(E_Input_Evdev *edev)
356 {
357    Eina_Bool ret = EINA_FALSE;
358    Ecore_Device_Class clas = ECORE_DEVICE_CLASS_NONE;
359
360    if (edev->caps & E_INPUT_SEAT_POINTER)
361      {
362         if (!e_devicemgr_detent_is_detent(libinput_device_get_name(edev->device)))
363           clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_POINTER);
364         ret = _e_input_add_ecore_device(edev, clas);
365      }
366    if (edev->caps & E_INPUT_SEAT_KEYBOARD)
367      {
368         clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_KEYBOARD);
369         ret = _e_input_add_ecore_device(edev, clas);
370      }
371    if (edev->caps & E_INPUT_SEAT_TOUCH)
372      {
373         clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_TOUCH);
374         ret = _e_input_add_ecore_device(edev, clas);
375      }
376
377    return ret;
378 }
379
380 void
381 _e_input_device_remove(E_Input_Evdev *edev)
382 {
383    Ecore_Device_Class clas = ECORE_DEVICE_CLASS_NONE;
384    Ecore_Device *data;
385
386    if (edev->caps & E_INPUT_SEAT_POINTER)
387      {
388         if (!e_devicemgr_detent_is_detent(libinput_device_get_name(edev->device)))
389           clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_POINTER);
390         _e_input_remove_ecore_device(edev, clas);
391      }
392    if (edev->caps & E_INPUT_SEAT_KEYBOARD)
393      {
394         clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_KEYBOARD);
395         _e_input_remove_ecore_device(edev, clas);
396      }
397    if (edev->caps & E_INPUT_SEAT_TOUCH)
398      {
399         clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_TOUCH);
400         _e_input_remove_ecore_device(edev, clas);
401      }
402
403    if (edev->ecore_dev_list)
404      {
405         if (eina_list_count(edev->ecore_dev_list) > 0)
406           {
407              ecore_thread_main_loop_begin();
408              EINA_LIST_FREE(edev->ecore_dev_list, data)
409                {
410                   WRN("Invalid device is left. name: %s, identifier: %s, clas: %s\n",
411                       ecore_device_name_get(data), ecore_device_identifier_get(data),
412                       _e_input_ecore_device_class_to_string(ecore_device_class_get(data)));
413
414                   ecore_device_unref(data);
415                   ecore_device_del(data);
416                }
417              ecore_thread_main_loop_end();
418           }
419         edev->ecore_dev_list = NULL;
420      }
421 }
422
423 static void
424 _device_added(E_Input_Backend *input, struct libinput_device *device)
425 {
426    struct libinput_seat *libinput_seat;
427    const char *seat_name;
428    E_Input_Seat *seat;
429    E_Input_Evdev *edev;
430
431    libinput_seat = libinput_device_get_seat(device);
432    seat_name = libinput_seat_get_logical_name(libinput_seat);
433
434    /* try to get a seat */
435    if (!(seat = _seat_get(input, seat_name)))
436      {
437         ERR("Could not get matching seat: %s", seat_name);
438         return;
439      }
440
441    /* try to create a new evdev device */
442    if (!(edev = _e_input_evdev_device_create(seat, device)))
443      {
444         ERR("Failed to create new evdev device");
445         return;
446      }
447
448    /* append this device to the seat */
449    seat->devices = eina_list_append(seat->devices, edev);
450
451    if (EINA_FALSE == _e_input_device_add(edev))
452      {
453         ERR("Failed to create evas device !\n");
454         return;
455      }
456 }
457
458 static void
459 _device_removed(E_Input_Backend *input, struct libinput_device *device)
460 {
461    E_Input_Evdev *edev;
462
463    /* try to get the evdev structure */
464    if (!(edev = libinput_device_get_user_data(device)))
465      {
466         return;
467      }
468
469    _e_input_device_remove(edev);
470
471    /* remove this evdev from the seat's list of devices */
472    edev->seat->devices = eina_list_remove(edev->seat->devices, edev);
473
474    /* destroy this evdev */
475    _e_input_evdev_device_destroy(edev);
476 }
477
478 static int
479 _udev_event_process(struct libinput_event *event)
480 {
481    struct libinput *libinput;
482    struct libinput_device *device;
483    E_Input_Backend *input;
484    Eina_Bool ret = EINA_TRUE;
485
486    libinput = libinput_event_get_context(event);
487    input = libinput_get_user_data(libinput);
488    device = libinput_event_get_device(event);
489
490    switch (libinput_event_get_type(event))
491      {
492       case LIBINPUT_EVENT_DEVICE_ADDED:
493         _device_added(input, device);
494         break;
495       case LIBINPUT_EVENT_DEVICE_REMOVED:
496         _device_removed(input, device);
497         break;
498       default:
499         ret = EINA_FALSE;
500      }
501
502    return ret;
503 }
504
505 static void
506 _input_event_process(struct libinput_event *event)
507 {
508    if (_udev_event_process(event)) return;
509    if (_e_input_evdev_event_process(event)) return;
510 }
511
512 void
513 _input_events_process(E_Input_Backend *input)
514 {
515    struct libinput_event *event;
516
517    while ((event = libinput_get_event(input->libinput)))
518      {
519         _input_event_process(event);
520         libinput_event_destroy(event);
521      }
522 }
523
524 static Eina_Bool
525 _cb_input_dispatch(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
526 {
527    E_Input_Backend *input;
528
529    if (!(input = data)) return EINA_TRUE;
530
531    if (libinput_dispatch(input->libinput) != 0)
532      ERR("Failed to dispatch libinput events: %m");
533
534    /* process pending events */
535    _input_events_process(input);
536
537    return EINA_TRUE;
538 }
539
540 static gboolean
541 input_thread_prepare(GSource *source, gint *time)
542 {
543    /* flush pending client events */
544    e_comp_wl_display_flush();
545
546    if (time)
547      *time = -1;
548
549    return FALSE;
550 }
551
552 static gboolean
553 input_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
554 {
555    InputEventSource *src = (InputEventSource *)source;
556    E_Input_Backend *input = (E_Input_Backend *)user_data;
557    if (!src) return G_SOURCE_REMOVE;
558    if (!input) return G_SOURCE_REMOVE;
559
560    GIOCondition cond;
561    cond = g_source_query_unix_fd(source, src->tag);
562
563    if (cond & G_IO_ERR || cond & G_IO_HUP || cond & G_IO_NVAL)
564      {
565         INF("error cond(%d)\n", cond);
566         return G_SOURCE_CONTINUE;
567      }
568
569    if (libinput_dispatch(input->libinput) != 0)
570      ERR("Failed to dispatch libinput events: %m");
571
572    /* process pending events */
573    _input_events_process(input);
574
575    e_input_event_process((GSource *)input->event_source);
576
577    return G_SOURCE_CONTINUE;
578 }
579
580 static void
581 input_thread_start(void *data, Ecore_Thread *th)
582 {
583    E_Input_Backend *input;
584    GMainContext *context = NULL;
585    InputEventSource *input_event_source = NULL;
586
587    INF("input thread start");
588
589    if (!(input = data)) return;
590
591    eina_thread_name_set(eina_thread_self(), "input-thread");
592
593    //create a context
594    context = g_main_context_new();
595    g_main_context_push_thread_default(context);
596
597    input_event_source = (InputEventSource *)g_source_new(&input_event_funcs, sizeof(InputEventSource));
598    input_event_source->tag = g_source_add_unix_fd(&input_event_source->gsource, input->fd, G_IO_IN);
599
600    if (!input->event_source)
601      e_input_create_event_source(input);
602
603    //create main loop
604    input->input_thread_loop = g_main_loop_new(context, FALSE);
605
606    //set the callback for this source
607    g_source_set_callback(&input_event_source->gsource, NULL, input, NULL);
608    g_source_attach(&input_event_source->gsource, context);
609
610    g_main_loop_run(input->input_thread_loop);
611 }
612
613 static void
614 input_thread_feedback(void *data, Ecore_Thread *th, void *msgdata)
615 {
616    E_Input_Backend *input;
617
618    INF("input thread start");
619
620    if (!(input = data)) return;
621 }
622
623 static void
624 input_thread_end(void *data, Ecore_Thread *th)
625 {
626    E_Input_Backend *input;
627
628    if (!(input = data)) return;
629    INF("input thread complete");
630
631    e_input_event_source_destroy(input->event_source);
632    input->event_source = NULL;
633
634    g_main_loop_quit(input->input_thread_loop);
635    g_main_loop_unref(input->input_thread_loop);
636    input->input_thread_loop = NULL;
637
638    if (th == input->input_thread)
639      input->input_thread = NULL;
640 }
641
642 static void
643 input_thread_cancel(void *data, Ecore_Thread *th)
644 {
645    E_Input_Backend *input;
646
647    if (!(input = data)) return;
648
649    INF("input thread cancel");
650
651    if (th == input->input_thread)
652      input->input_thread = NULL;
653 }
654
655 EINTERN Eina_Bool
656 e_input_enable_input(E_Input_Backend *input)
657 {
658    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
659    EINA_SAFETY_ON_NULL_RETURN_VAL(input->libinput, EINA_FALSE);
660
661    input->fd = libinput_get_fd(input->libinput);
662
663    if (!e_input_thread_mode_get())
664      {
665         if (!input->hdlr)
666           {
667              input->hdlr =
668                 ecore_main_fd_handler_add(input->fd, ECORE_FD_READ,
669                                           _cb_input_dispatch, input, NULL, NULL);
670           }
671
672         if (input->suspended)
673           {
674              if (libinput_resume(input->libinput) != 0)
675                goto err;
676
677              input->suspended = EINA_FALSE;
678
679              /* process pending events */
680              _input_events_process(input);
681           }
682      }
683
684    input->enabled = EINA_TRUE;
685    input->suspended = EINA_FALSE;
686
687    if (e_input_thread_mode_get())
688      {
689         input->input_thread = ecore_thread_feedback_run(input_thread_start, input_thread_feedback, input_thread_end, input_thread_cancel, input, EINA_FALSE);
690      }
691
692    return EINA_TRUE;
693
694 err:
695    input->enabled = EINA_FALSE;
696    if (!e_input_thread_mode_get())
697      {
698         if (input->hdlr)
699           ecore_main_fd_handler_del(input->hdlr);
700         input->hdlr = NULL;
701      }
702
703    return EINA_FALSE;
704 }
705
706 EINTERN void
707 e_input_disable_input(E_Input_Backend *input)
708 {
709    EINA_SAFETY_ON_NULL_RETURN(input);
710    EINA_SAFETY_ON_TRUE_RETURN(input->suspended);
711
712    /* suspend this input */
713    libinput_suspend(input->libinput);
714
715    /* process pending events */
716    _input_events_process(input);
717
718    input->suspended = EINA_TRUE;
719
720    if (e_input_thread_mode_get())
721      {
722         if (input->input_thread && !ecore_thread_check(input->input_thread))
723           ecore_thread_cancel(input->input_thread);
724      }
725 }
726
727 EINTERN Eina_List *
728 e_input_seat_evdev_list_get(E_Input_Seat *seat)
729 {
730    EINA_SAFETY_ON_NULL_RETURN_VAL(seat, NULL);
731    return seat->devices;
732 }
733
734 E_API E_Input_Event_Source *
735 e_input_event_source_get()
736 {
737    return g_input_event_source;
738 }
739
740 E_API Eina_Bool
741 e_input_thread_mode_get()
742 {
743    if (e_config)
744      return e_config->input_thread_mode;
745    else
746      return EINA_TRUE;
747 }
748
749 EINTERN void
750 e_input_create_event_source(E_Input_Backend *input)
751 {
752    input->event_source = e_input_event_source_create();
753
754    g_input_event_source = input->event_source;
755 }