e_devicemgr: make an internal header
[platform/upstream/enlightenment.git] / src / bin / e_input_inputs.c
1 #include "e.h"
2 #include "e_devicemgr_intern.h"
3 #include "e_input_intern.h"
4 #include "e_input_private.h"
5 #include "e_input_event_intern.h"
6 #include "e_keyrouter_intern.h"
7 #include "e_comp_wl_intern.h"
8
9 #include <glib.h>
10
11 static gboolean input_dispatch(GSource *source, GSourceFunc callback, gpointer user_data);
12 static gboolean input_thread_prepare(GSource *source, gint *time);
13
14 static E_Input_Event_Source *g_input_event_source = NULL;
15 static GList *_key_event_list = NULL;
16
17 GSourceFuncs input_event_funcs = {
18    .prepare = input_thread_prepare,
19    .check = NULL,
20    .dispatch = input_dispatch,
21    .finalize = NULL
22 };
23
24 typedef struct
25 {
26    GSource gsource;
27    gpointer tag;
28 } InputEventSource;
29
30 static char *
31 _e_input_ecore_device_class_to_string(Ecore_Device_Class clas)
32 {
33    switch (clas)
34      {
35         case ECORE_DEVICE_CLASS_NONE:
36           return "None";
37           break;
38         case ECORE_DEVICE_CLASS_SEAT:
39           return "Seat";
40           break;
41         case ECORE_DEVICE_CLASS_KEYBOARD:
42           return "Keyboard";
43           break;
44         case ECORE_DEVICE_CLASS_MOUSE:
45           return "Mouse";
46           break;
47         case ECORE_DEVICE_CLASS_TOUCH:
48           return "Touch";
49           break;
50         case ECORE_DEVICE_CLASS_PEN:
51           return "Pen";
52           break;
53         case ECORE_DEVICE_CLASS_WAND:
54           return "Wand";
55           break;
56         case ECORE_DEVICE_CLASS_GAMEPAD:
57           return "Gamepad";
58           break;
59         default:
60           return "Unknown";
61      }
62 }
63
64 static Ecore_Device_Class
65 _e_input_seat_cap_to_ecore_device_class(unsigned int cap)
66 {
67    switch(cap)
68      {
69       case E_INPUT_SEAT_POINTER:
70          return ECORE_DEVICE_CLASS_MOUSE;
71       case E_INPUT_SEAT_KEYBOARD:
72          return ECORE_DEVICE_CLASS_KEYBOARD;
73       case E_INPUT_SEAT_TOUCH:
74          return ECORE_DEVICE_CLASS_TOUCH;
75       default:
76          return ECORE_DEVICE_CLASS_NONE;
77      }
78    return ECORE_DEVICE_CLASS_NONE;
79 }
80
81 static void
82 _e_input_ecore_device_info_free(void *data EINA_UNUSED, void *ev)
83 {
84    Ecore_Event_Device_Info *e;
85
86    e = ev;
87    eina_stringshare_del(e->name);
88    eina_stringshare_del(e->identifier);
89    eina_stringshare_del(e->seatname);
90
91    free(e);
92 }
93
94 void
95 _e_input_ecore_device_event(Ecore_Device *dev, const char* seat_name, Eina_Bool flag)
96 {
97    Ecore_Event_Device_Info *e;
98    E_Input *e_input;
99    const char *name, *identifier;
100
101    ecore_thread_main_loop_begin();
102
103    if (!(name = ecore_device_name_get(dev))) goto end;
104    if (!(identifier = ecore_device_identifier_get(dev))) goto end;
105
106    if (!(e = calloc(1, sizeof(Ecore_Event_Device_Info)))) goto end;
107
108    e_input = e_input_get();
109
110    e->window = e_input?e_input->window:(Ecore_Window)0;
111    e->name = eina_stringshare_add(name);
112    e->identifier = eina_stringshare_add(identifier);
113    if (seat_name && strlen(seat_name))
114      e->seatname = eina_stringshare_add(seat_name);
115    else
116      e->seatname = eina_stringshare_add(name);
117    e->clas = ecore_device_class_get(dev);
118    e->subclas = ecore_device_subclass_get(dev);
119
120    if (flag)
121      ecore_event_add(ECORE_EVENT_DEVICE_ADD, e, _e_input_ecore_device_info_free, NULL);
122    else
123      ecore_event_add(ECORE_EVENT_DEVICE_DEL, e, _e_input_ecore_device_info_free, NULL);
124
125 end:
126    ecore_thread_main_loop_end();
127 }
128
129 static E_Input_Seat *
130 _seat_create(E_Input_Backend *input, const char *seat)
131 {
132    E_Input_Seat *s;
133    Ecore_Device *ecore_dev = NULL;
134    E_Device *e_dev = NULL;
135
136    ecore_thread_main_loop_begin();
137
138    /* create an evas device of a seat */
139    ecore_dev = ecore_device_add();
140    if (!ecore_dev)
141      {
142         ERR("Failed to create an ecore device for a seat !\n");
143         ecore_thread_main_loop_end();
144                 return NULL;
145      }
146
147    ecore_device_name_set(ecore_dev, seat);
148    ecore_device_identifier_set(ecore_dev, "Enlightenment seat");
149    ecore_device_class_set(ecore_dev, ECORE_DEVICE_CLASS_SEAT);
150    ecore_device_subclass_set(ecore_dev, ECORE_DEVICE_SUBCLASS_NONE);
151
152    /* create an e device of a seat */
153    e_dev = e_device_new();
154    if (!e_dev)
155      {
156         ERR("Failed to create an ecore device for a seat !\n");
157         ecore_thread_main_loop_end();
158                 return NULL;
159      }
160
161    e_device_name_set(e_dev, seat);
162    e_device_identifier_set(e_dev, "Enlightenment seat");
163    e_device_class_set(e_dev, ECORE_DEVICE_CLASS_SEAT);
164    e_device_subclass_set(e_dev, ECORE_DEVICE_SUBCLASS_NONE);
165
166    /* try to allocate space for new seat */
167    if (!(s = calloc(1, sizeof(E_Input_Seat))))
168      {
169         ecore_device_del(ecore_dev);
170         ecore_thread_main_loop_end();
171         return NULL;
172      }
173
174    s->input = input;
175    s->name = eina_stringshare_add(seat);
176    s->ecore_dev = ecore_dev;
177    s->e_dev = e_dev;
178
179    /* add this new seat to list */
180    input->dev->seats = eina_list_append(input->dev->seats, s);
181    s->dev = input->dev;
182
183    ecore_event_add(E_INPUT_EVENT_SEAT_ADD, NULL, NULL, NULL);
184    ecore_thread_main_loop_end();
185
186    _e_input_ecore_device_event(ecore_dev, seat, EINA_TRUE);
187
188    return s;
189 }
190
191 static E_Input_Seat *
192 _seat_get(E_Input_Backend *input, const char *seat)
193 {
194    E_Input_Seat *s;
195    Eina_List *l;
196
197    /* search for this name in existing seats */
198    EINA_LIST_FOREACH(input->dev->seats, l, s)
199      if (!strcmp(s->name, seat))
200        return s;
201
202    return _seat_create(input, seat);
203 }
204
205 static Eina_Bool
206 _e_input_add_ecore_device(E_Input_Evdev *edev, Ecore_Device_Class clas)
207 {
208    const Eina_List *dev_list = NULL;
209    const Eina_List *l;
210    Ecore_Device *dev = NULL;
211    E_Device *e_dev = NULL;
212    const char *identifier;
213
214    if (!edev || !edev->path) return EINA_FALSE;
215
216    dev_list = ecore_device_list();
217    if (dev_list)
218      {
219         EINA_LIST_FOREACH(dev_list, l, dev)
220           {
221              if (!dev) continue;
222              identifier = ecore_device_identifier_get(dev);
223              if (!identifier) continue;
224              if ((ecore_device_class_get(dev) == clas) && (!strcmp(identifier, edev->path)))
225                {
226                   ERR("Found same device in device list");
227                   return EINA_FALSE;
228                }
229           }
230      }
231
232    // create ecore device info
233    dev = ecore_device_add();
234    if (!dev)
235      {
236         ERR("Failed to create ecore device");
237         edev->ecore_dev = NULL;
238         return EINA_FALSE;
239      }
240
241    ecore_device_name_set(dev, libinput_device_get_name(edev->device));
242    ecore_device_identifier_set(dev, edev->path);
243    ecore_device_class_set(dev, clas);
244    ecore_device_subclass_set(dev, ECORE_DEVICE_SUBCLASS_NONE);
245
246    if (!edev->ecore_dev)
247      {
248         if (!edev->ecore_dev_list || (eina_list_count(edev->ecore_dev_list) == 0))
249           {
250              /* 1st Ecore_Device is added */
251              edev->ecore_dev = ecore_device_ref(dev);
252           }
253         else
254           {
255              /* 3rd or more Ecore_Device is added */
256              edev->ecore_dev_list = eina_list_append(edev->ecore_dev_list, ecore_device_ref(dev));
257           }
258      }
259    else
260      {
261         /* 2nd Ecore_Device is added */
262         edev->ecore_dev_list = eina_list_append(edev->ecore_dev_list, edev->ecore_dev);
263         edev->ecore_dev = NULL;
264
265         edev->ecore_dev_list = eina_list_append(edev->ecore_dev_list, ecore_device_ref(dev));
266      }
267
268    const GList *device_list = e_device_list_get();
269    const gchar *device_identifier;
270    for (GList *list = g_list_first((GList *)device_list); list; list = list->next)
271      {
272         E_Device *device = (E_Device *)list->data;
273         if (!device) continue;
274         device_identifier = e_device_identifier_get(device);
275         if (!device_identifier) continue;
276
277         if ((e_device_class_get(device) == clas) && (!strcmp(device_identifier, edev->path)))
278           {
279              e_dev = device;
280              break;
281           }
282      }
283
284    if (!e_dev)
285      {
286         // create E_Device info
287         e_dev = e_device_new();
288         if (!e_dev)
289           {
290              ERR("Failed to add e device");
291              edev->e_dev = NULL;
292              return EINA_FALSE;
293           }
294      }
295
296    e_device_name_set(e_dev, libinput_device_get_name(edev->device));
297    e_device_identifier_set(e_dev, edev->path);
298    e_device_class_set(e_dev, clas);
299    e_device_subclass_set(e_dev, ECORE_DEVICE_SUBCLASS_NONE);
300
301    if (!edev->e_dev)
302      {
303         if (!edev->e_dev_list || (g_list_length(edev->e_dev_list) == 0))
304           {
305              /* 1st Ecore_Device is added */
306              edev->e_dev = g_object_ref(e_dev);
307           }
308         else
309           {
310              /* 3rd or more Ecore_Device is added */
311              edev->e_dev_list = g_list_append(edev->e_dev_list, g_object_ref(e_dev));
312           }
313      }
314    else
315      {
316         /* 2nd Ecore_Device is added */
317         edev->e_dev_list = g_list_append(edev->e_dev_list, edev->e_dev);
318         edev->e_dev = NULL;
319
320         edev->e_dev_list = g_list_append(edev->e_dev_list, g_object_ref(e_dev));
321      }
322
323    _e_input_ecore_device_event(dev, edev->seat ? edev->seat->name : NULL, EINA_TRUE);
324
325    INF("[Add Device] device name(%s), identifier(%s), class(%s)", e_device_name_get(e_dev), edev->path, _e_input_ecore_device_class_to_string(clas));
326
327    return EINA_TRUE;
328 }
329
330 static Eina_Bool
331 _e_input_remove_ecore_device(E_Input_Evdev *edev, Ecore_Device_Class clas)
332 {
333    Eina_Bool ret = EINA_FALSE;
334    const Eina_List *dev_list = NULL, *l;
335    const GList *e_dev_list = NULL;
336    Eina_List *ll, *ll_next;
337    Ecore_Device *dev = NULL, *data;
338    const char *identifier;
339    const gchar *device_identifier;
340    const char *device_remove_log = NULL;
341
342    if (!edev->path) return EINA_FALSE;
343
344    dev_list = ecore_device_list();
345    if (!dev_list) return EINA_FALSE;
346
347    EINA_LIST_FOREACH(dev_list, l, dev)
348       {
349          if (!dev) continue;
350          identifier = ecore_device_identifier_get(dev);
351          if (!identifier) continue;
352          if ((ecore_device_class_get(dev) == clas) && (!strcmp(identifier, edev->path)))
353            {
354               if (edev->ecore_dev)
355                 {
356                    ecore_device_unref(dev);
357                    edev->ecore_dev = NULL;
358                 }
359               else if (edev->ecore_dev_list)
360                 {
361                    EINA_LIST_FOREACH_SAFE(edev->ecore_dev_list, ll, ll_next, data)
362                      {
363                         if (data == dev)
364                           {
365                              ecore_device_unref(dev);
366                              edev->ecore_dev_list = eina_list_remove_list(edev->ecore_dev_list, ll);
367                           }
368                      }
369                 }
370               _e_input_ecore_device_event(dev, edev->seat ? edev->seat->name : NULL, EINA_FALSE);
371               ecore_device_del(dev);
372               ret = EINA_TRUE;
373            }
374       }
375
376    e_dev_list = e_device_list_get();
377    if (!e_dev_list)
378      {
379         ERR("Failed to get e device list");
380         return EINA_FALSE;
381      }
382
383    for (GList *list = g_list_first((GList *)e_dev_list); list; list = list->next)
384      {
385         E_Device *device = (E_Device *)list->data;
386         if (!device) continue;
387         device_identifier = e_device_identifier_get(device);
388         if (!device_identifier) continue;
389
390         if ((e_device_class_get(device) == clas) && (!strcmp(device_identifier, edev->path)))
391           {
392              device_remove_log = eina_stringshare_printf("[Remove Device] device name(%s), identifier(%s), class(%s)",
393                                                          e_device_name_get(device),
394                                                          device_identifier,
395                                                          _e_input_ecore_device_class_to_string(clas));
396
397              if (edev->e_dev)
398                {
399                   g_object_unref(device);
400                   edev->e_dev = NULL;
401                }
402              else if (edev->e_dev_list)
403                {
404                   GList *del_list = g_list_find(edev->e_dev_list, device);
405                   if (del_list)
406                     {
407                        edev->e_dev_list = g_list_delete_link(edev->e_dev_list, del_list);
408                     }
409                }
410              ret = EINA_TRUE;
411           }
412      }
413
414    if (device_remove_log)
415      {
416         INF("%s", device_remove_log);
417         eina_stringshare_del(device_remove_log);
418      }
419
420    return ret;
421 }
422
423 Eina_Bool
424 _e_input_device_add(E_Input_Evdev *edev)
425 {
426    Eina_Bool ret = EINA_FALSE;
427    Ecore_Device_Class clas = ECORE_DEVICE_CLASS_NONE;
428
429    if (edev->caps & E_INPUT_SEAT_POINTER)
430      {
431         if (!e_devicemgr_detent_is_detent(libinput_device_get_name(edev->device)))
432           clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_POINTER);
433         ret = _e_input_add_ecore_device(edev, clas);
434      }
435    if (edev->caps & E_INPUT_SEAT_KEYBOARD)
436      {
437         clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_KEYBOARD);
438         ret = _e_input_add_ecore_device(edev, clas);
439      }
440    if (edev->caps & E_INPUT_SEAT_TOUCH)
441      {
442         clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_TOUCH);
443         ret = _e_input_add_ecore_device(edev, clas);
444      }
445
446    return ret;
447 }
448
449 void
450 _e_input_device_remove(E_Input_Evdev *edev)
451 {
452    Ecore_Device_Class clas = ECORE_DEVICE_CLASS_NONE;
453    Ecore_Device *data;
454
455    if (edev->caps & E_INPUT_SEAT_POINTER)
456      {
457         if (!e_devicemgr_detent_is_detent(libinput_device_get_name(edev->device)))
458           clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_POINTER);
459         _e_input_remove_ecore_device(edev, clas);
460      }
461    if (edev->caps & E_INPUT_SEAT_KEYBOARD)
462      {
463         clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_KEYBOARD);
464         _e_input_remove_ecore_device(edev, clas);
465      }
466    if (edev->caps & E_INPUT_SEAT_TOUCH)
467      {
468         clas = _e_input_seat_cap_to_ecore_device_class(E_INPUT_SEAT_TOUCH);
469         _e_input_remove_ecore_device(edev, clas);
470      }
471
472    if (edev->ecore_dev_list)
473      {
474         if (eina_list_count(edev->ecore_dev_list) > 0)
475           {
476              EINA_LIST_FREE(edev->ecore_dev_list, data)
477                {
478                   WRN("Invalid device is left. name: %s, identifier: %s, clas: %s\n",
479                       ecore_device_name_get(data), ecore_device_identifier_get(data),
480                       _e_input_ecore_device_class_to_string(ecore_device_class_get(data)));
481
482                   ecore_device_unref(data);
483                   ecore_device_del(data);
484                }
485           }
486         edev->ecore_dev_list = NULL;
487      }
488 }
489
490 static void
491 _device_added(E_Input_Backend *input, struct libinput_device *device)
492 {
493    struct libinput_seat *libinput_seat;
494    const char *seat_name;
495    E_Input_Seat *seat;
496    E_Input_Evdev *edev;
497
498    ecore_thread_main_loop_begin();
499    libinput_seat = libinput_device_get_seat(device);
500    seat_name = libinput_seat_get_logical_name(libinput_seat);
501
502    /* try to get a seat */
503    if (!(seat = _seat_get(input, seat_name)))
504      {
505         ERR("Could not get matching seat: %s", seat_name);
506         ecore_thread_main_loop_end();
507         return;
508      }
509
510    /* try to create a new evdev device */
511    if (!(edev = _e_input_evdev_device_create(seat, device)))
512      {
513         ERR("Failed to create new evdev device");
514         ecore_thread_main_loop_end();
515         return;
516      }
517
518    /* append this device to the seat */
519    seat->devices = eina_list_append(seat->devices, edev);
520
521    if (EINA_FALSE == _e_input_device_add(edev))
522      {
523         ERR("Failed to create evas device !\n");
524         ecore_thread_main_loop_end();
525         return;
526      }
527
528    ecore_thread_main_loop_end();
529 }
530
531 static void
532 _device_removed(E_Input_Backend *input, struct libinput_device *device)
533 {
534    E_Input_Evdev *edev;
535
536    ecore_thread_main_loop_begin();
537
538    /* try to get the evdev structure */
539    if (!(edev = libinput_device_get_user_data(device)))
540      {
541         ecore_thread_main_loop_end();
542         return;
543      }
544
545    _e_input_device_remove(edev);
546
547    /* remove this evdev from the seat's list of devices */
548    edev->seat->devices = eina_list_remove(edev->seat->devices, edev);
549
550    /* destroy this evdev */
551    _e_input_evdev_device_destroy(edev);
552
553    ecore_thread_main_loop_end();
554 }
555
556 static int
557 _udev_event_process(struct libinput_event *event)
558 {
559    struct libinput *libinput;
560    struct libinput_device *device;
561    E_Input_Backend *input;
562    Eina_Bool ret = EINA_TRUE;
563
564    libinput = libinput_event_get_context(event);
565    input = libinput_get_user_data(libinput);
566    device = libinput_event_get_device(event);
567
568    switch (libinput_event_get_type(event))
569      {
570       case LIBINPUT_EVENT_DEVICE_ADDED:
571         if (e_config->key_input_ttrace_enable)
572           {
573              TRACE_INPUT_BEGIN(_device_added);
574              ELOGF("INPUT", "_device_added|B|", NULL);
575           }
576
577         _device_added(input, device);
578
579         if (e_config->key_input_ttrace_enable)
580           {
581              TRACE_INPUT_END();
582              ELOGF("INPUT", "_device_added|E|", NULL);
583           }
584         break;
585       case LIBINPUT_EVENT_DEVICE_REMOVED:
586         if (e_config->key_input_ttrace_enable)
587           {
588              TRACE_INPUT_BEGIN(_device_removed);
589              ELOGF("INPUT", "_device_removed|B|", NULL);
590           }
591
592         _device_removed(input, device);
593
594         if (e_config->key_input_ttrace_enable)
595           {
596              TRACE_INPUT_END();
597              ELOGF("INPUT", "_device_removed|E|", NULL);
598           }
599         break;
600       default:
601         ret = EINA_FALSE;
602      }
603
604    return ret;
605 }
606
607 static void
608 _input_event_process(struct libinput_event *event)
609 {
610    if (_udev_event_process(event)) return;
611    if (_e_input_evdev_event_process(event)) return;
612 }
613
614 void
615 _input_events_process(E_Input_Backend *input)
616 {
617    struct libinput_event *event;
618    while ((event = libinput_get_event(input->libinput)))
619      {
620         _input_event_process(event);
621         libinput_event_destroy(event);
622      }
623 }
624
625 static Eina_Bool
626 _cb_input_dispatch(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
627 {
628    E_Input_Backend *input;
629
630    if (!(input = data)) return EINA_TRUE;
631
632    if (e_config->key_input_ttrace_enable)
633      {
634         TRACE_INPUT_BEGIN(_cb_input_dispatch);
635         ELOGF("INPUT", "_cb_input_dispatch|B|", NULL);
636      }
637
638    if (libinput_dispatch(input->libinput) != 0)
639      ERR("Failed to dispatch libinput events: %m");
640
641    /* process pending events */
642    _input_events_process(input);
643
644    if (e_config->key_input_ttrace_enable)
645      {
646         TRACE_INPUT_END();
647         ELOGF("INPUT", "_cb_input_dispatch|E|", NULL);
648      }
649
650    return EINA_TRUE;
651 }
652
653 static void
654 _e_input_delayed_key_events_print()
655 {
656    struct timespec tp;
657    unsigned int time;
658
659    clock_gettime(CLOCK_MONOTONIC, &tp);
660    time = (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
661
662    GList *key_list = g_list_first(_key_event_list);
663    while (key_list)
664      {
665         Ecore_Event_Key *key = (Ecore_Event_Key *)key_list->data;
666         if (!key) continue;
667
668         if (e_config->key_input_time_limit <= (time - key->timestamp))
669           ERR("Delayed key event : keyname(%s), keycode(%u), timestamp(%u), elapsed_time(%u ms)", key->keyname, key->keycode, key->timestamp, time - key->timestamp);
670
671         if (key->keyname)
672           eina_stringshare_del(key->keyname);
673         E_FREE(key);
674
675         GList *next = key_list->next;
676         _key_event_list = g_list_delete_link(_key_event_list, key_list);
677         key_list = next;
678      }
679
680    _key_event_list = NULL;
681 }
682
683 static gboolean
684 input_thread_prepare(GSource *source, gint *time)
685 {
686    if (e_config->key_input_ttrace_enable)
687      {
688         TRACE_INPUT_BEGIN(e_comp_wl_focused_client_flush);
689         ELOGF("INPUT", "e_comp_wl_focused_client_flush|B|", NULL);
690      }
691
692    /* flush only focused client events */
693    e_comp_wl_focused_client_flush();
694
695    if (_key_event_list)
696      _e_input_delayed_key_events_print();
697
698    if (e_config->key_input_ttrace_enable)
699      {
700         TRACE_INPUT_END();
701         ELOGF("INPUT", "e_comp_wl_focused_client_flush|E|", NULL);
702      }
703
704    if (time)
705      *time = -1;
706
707    return FALSE;
708 }
709
710 static gboolean
711 input_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
712 {
713    InputEventSource *src = (InputEventSource *)source;
714    E_Input_Backend *input = (E_Input_Backend *)user_data;
715    if (!src) return G_SOURCE_REMOVE;
716    if (!input) return G_SOURCE_REMOVE;
717
718    if (e_config->key_input_ttrace_enable)
719      {
720         TRACE_INPUT_BEGIN(input_dispatch);
721         ELOGF("INPUT", "input_dispatch|B|", NULL);
722      }
723
724    GIOCondition cond;
725    cond = g_source_query_unix_fd(source, src->tag);
726
727    if (cond & G_IO_ERR || cond & G_IO_HUP || cond & G_IO_NVAL)
728      {
729         INF("error cond(%d)\n", cond);
730         return G_SOURCE_CONTINUE;
731      }
732
733    if (!input->libinput)
734      return G_SOURCE_REMOVE;
735
736    if (e_config->key_input_ttrace_enable)
737      {
738         TRACE_INPUT_BEGIN(libinput_dispatch);
739         ELOGF("INPUT", "libinput_dispatch|B|", NULL);
740      }
741
742    if (libinput_dispatch(input->libinput) != 0)
743      ERR("Failed to dispatch libinput events: %m");
744
745    if (e_config->key_input_ttrace_enable)
746      {
747         TRACE_INPUT_END();
748         ELOGF("INPUT", "libinput_dispatch|E|", NULL);
749      }
750
751    if (e_config->key_input_ttrace_enable)
752      {
753         TRACE_INPUT_BEGIN(_input_events_process);
754         ELOGF("INPUT", "_input_events_process|B|", NULL);
755      }
756
757    /* process pending events */
758    _input_events_process(input);
759
760    if (e_config->key_input_ttrace_enable)
761      {
762         TRACE_INPUT_END();
763         ELOGF("INPUT", "_input_events_process|E|", NULL);
764
765         TRACE_INPUT_END();
766         ELOGF("INPUT", "input_dispatch|E|", NULL);
767      }
768
769    e_input_event_process((GSource *)input->event_source);
770
771    return G_SOURCE_CONTINUE;
772 }
773
774 static void
775 input_thread_start(void *data, Ecore_Thread *th)
776 {
777    E_Input_Device *dev;
778    E_Input_Backend *input;
779    GMainContext *context = NULL;
780    InputEventSource *input_event_source = NULL;
781
782    if (!(input = data)) return;
783
784    eina_thread_name_set(eina_thread_self(), "input-thread");
785
786    e_input_libinput_context_create(input);
787
788    /* enable this input */
789    if (!e_input_enable_input(input))
790      {
791         ERR("Failed to enable input");
792         return;
793      }
794
795    /* append this input */
796    dev = input->dev;
797    dev->inputs = eina_list_append(dev->inputs, input);
798
799    //create a context
800    context = g_main_context_new();
801    g_main_context_push_thread_default(context);
802
803    input_event_source = (InputEventSource *)g_source_new(&input_event_funcs, sizeof(InputEventSource));
804    input_event_source->tag = g_source_add_unix_fd(&input_event_source->gsource, input->fd, G_IO_IN);
805
806    if (!input->event_source)
807      e_input_create_event_source(input);
808
809    //create main loop
810    input->input_thread_loop = g_main_loop_new(context, FALSE);
811
812    g_source_attach((GSource *)input->event_source, context);
813
814    //set the callback for this source
815    g_source_set_callback(&input_event_source->gsource, NULL, input, NULL);
816    g_source_attach(&input_event_source->gsource, context);
817
818    e_keyrouter_input_handler_add();
819
820    e_input_thread_id_set(gettid());
821    e_input_main_thread_id_set(getpid());
822
823    _e_input_hook_call(E_INPUT_HOOK_INPUT_THREAD_START, NULL);
824
825    INF("input thread start tid(%d) pid(%d)", e_input_thread_id_get(), e_input_main_thread_id_get());
826
827    g_main_loop_run(input->input_thread_loop);
828 }
829
830 static void
831 input_thread_feedback(void *data, Ecore_Thread *th, void *msgdata)
832 {
833    E_Input_Backend *input;
834
835    INF("input thread start");
836
837    if (!(input = data)) return;
838 }
839
840 static void
841 input_thread_end(void *data, Ecore_Thread *th)
842 {
843    E_Input_Backend *input;
844
845    if (!(input = data)) return;
846    INF("input thread complete");
847
848    e_input_event_source_destroy(input->event_source);
849    input->event_source = NULL;
850
851    g_main_loop_quit(input->input_thread_loop);
852    g_main_loop_unref(input->input_thread_loop);
853    input->input_thread_loop = NULL;
854
855    if (th == input->input_thread)
856      input->input_thread = NULL;
857 }
858
859 static void
860 input_thread_cancel(void *data, Ecore_Thread *th)
861 {
862    E_Input_Backend *input;
863
864    if (!(input = data)) return;
865
866    INF("input thread cancel");
867
868    if (th == input->input_thread)
869      input->input_thread = NULL;
870 }
871
872 void
873 _e_input_key_event_list_add(Ecore_Event_Key *key)
874 {
875    Ecore_Event_Key *clone = NULL;
876
877    if (!key) return;
878
879    clone = E_NEW(Ecore_Event_Key, 1);
880    if (!clone) return;
881
882    if (key->keyname)
883      clone->keyname = (char *)eina_stringshare_add(key->keyname);
884
885    clone->keycode = key->keycode;
886    clone->timestamp = key->timestamp;
887
888    _key_event_list = g_list_append(_key_event_list, clone);
889 }
890
891 EINTERN Eina_Bool
892 e_input_enable_input(E_Input_Backend *input)
893 {
894    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
895    EINA_SAFETY_ON_NULL_RETURN_VAL(input->libinput, EINA_FALSE);
896
897    input->fd = libinput_get_fd(input->libinput);
898
899    if (!e_input_thread_mode_get())
900      {
901         if (!input->hdlr)
902           {
903              input->hdlr =
904                 ecore_main_fd_handler_add(input->fd, ECORE_FD_READ,
905                                           _cb_input_dispatch, input, NULL, NULL);
906           }
907      }
908
909    if (input->suspended)
910      {
911         if (libinput_resume(input->libinput) != 0)
912           goto err;
913
914         input->suspended = EINA_FALSE;
915
916         /* process pending events */
917         _input_events_process(input);
918      }
919
920    input->enabled = EINA_TRUE;
921    input->suspended = EINA_FALSE;
922
923    return EINA_TRUE;
924
925 err:
926    input->enabled = EINA_FALSE;
927    if (!e_input_thread_mode_get())
928      {
929         if (input->hdlr)
930           ecore_main_fd_handler_del(input->hdlr);
931         input->hdlr = NULL;
932      }
933
934    return EINA_FALSE;
935 }
936
937 EINTERN void
938 e_input_disable_input(E_Input_Backend *input)
939 {
940    EINA_SAFETY_ON_NULL_RETURN(input);
941    EINA_SAFETY_ON_TRUE_RETURN(input->suspended);
942
943    /* suspend this input */
944    libinput_suspend(input->libinput);
945
946    /* process pending events */
947    _input_events_process(input);
948
949    input->suspended = EINA_TRUE;
950
951    if (e_input_thread_mode_get())
952      {
953         if (input->input_thread && !ecore_thread_check(input->input_thread))
954           ecore_thread_cancel(input->input_thread);
955      }
956 }
957
958 EINTERN Eina_List *
959 e_input_seat_evdev_list_get(E_Input_Seat *seat)
960 {
961    EINA_SAFETY_ON_NULL_RETURN_VAL(seat, NULL);
962    return seat->devices;
963 }
964
965 E_API E_Input_Event_Source *
966 e_input_event_source_get()
967 {
968    return g_input_event_source;
969 }
970
971 E_API Eina_Bool
972 e_input_thread_mode_get()
973 {
974    if (e_config)
975      return e_config->input_thread_mode;
976    else
977      return EINA_TRUE;
978 }
979
980 EINTERN void
981 e_input_create_event_source(E_Input_Backend *input)
982 {
983    input->event_source = e_input_event_source_create();
984
985    g_input_event_source = input->event_source;
986 }
987
988 EINTERN void e_input_thread_run(E_Input_Backend *input)
989 {
990    input->input_thread = ecore_thread_feedback_run(input_thread_start, input_thread_feedback, input_thread_end, input_thread_cancel, input, EINA_FALSE);
991 }