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