test_input: use new input API
[platform/upstream/kmscon.git] / tests / test_input.c
1 /*
2  * test_input - Test the input system - hotplug and keypresses
3  *
4  * Copyright (c) 2011 Ran Benita <ran234@gmail.com>
5  * Copyright (c) 2012 David Herrmann <dh.herrmann@googlemail.com>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files
9  * (the "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26
27 #include <errno.h>
28 #include <linux/input.h>
29 #include <locale.h>
30 #include <signal.h>
31 #include <stdbool.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sys/signalfd.h>
36 #include <unistd.h>
37 #include <X11/keysym.h>
38 #include "eloop.h"
39 #include "log.h"
40 #include "uterm.h"
41 #include "test_include.h"
42
43 extern void kbd_dev_keysym_to_string(uint32_t keysym, char *str, size_t size);
44
45 static struct ev_eloop *eloop;
46 static struct uterm_input *input;
47
48 /* Pressing Ctrl-\ should toggle the capturing. */
49 static void sig_quit(struct ev_eloop *p,
50                         struct signalfd_siginfo *info,
51                         void *data)
52 {
53         if (!input)
54                 return;
55
56         if (uterm_input_is_awake(input)) {
57                 uterm_input_sleep(input);
58                 log_info("Went to sleep\n");
59         } else {
60                 uterm_input_wake_up(input);
61                 log_info("Woke Up\n");
62         }
63 }
64
65 static void print_modifiers(unsigned int mods)
66 {
67         if (mods & UTERM_SHIFT_MASK)
68                 printf("SHIFT ");
69         if (mods & UTERM_LOCK_MASK)
70                 printf("LOCK ");
71         if (mods & UTERM_CONTROL_MASK)
72                 printf("CONTROL ");
73         if (mods & UTERM_MOD1_MASK)
74                 printf("MOD1 ");
75         if (mods & UTERM_MOD2_MASK)
76                 printf("MOD2 ");
77         if (mods & UTERM_MOD3_MASK)
78                 printf("MOD3 ");
79         if (mods & UTERM_MOD4_MASK)
80                 printf("MOD4 ");
81         if (mods & UTERM_MOD5_MASK)
82                 printf("MOD5 ");
83         printf("\n");
84 }
85
86 static void input_arrived(struct uterm_input *input,
87                                 struct uterm_input_event *ev,
88                                 void *data)
89 {
90         char s[16];
91
92         if (ev->unicode == UTERM_INPUT_INVALID) {
93                 kbd_dev_keysym_to_string(ev->keysym, s, sizeof(s));
94                 printf("sym %s ", s);
95         } else {
96                 /*
97                  * Just a proof-of-concept hack. This works because glibc uses
98                  * UTF-32 (= UCS-4) as the internal wchar_t encoding.
99                  */
100                 printf("unicode %lc ", ev->unicode);
101         }
102         print_modifiers(ev->mods);
103 }
104
105 static void monitor_event(struct uterm_monitor *mon,
106                                 struct uterm_monitor_event *ev,
107                                 void *data)
108 {
109         int ret;
110
111         if (ev->type == UTERM_MONITOR_NEW_SEAT) {
112                 if (strcmp(ev->seat_name, "seat0"))
113                         return;
114
115                 ret = uterm_input_new(&input, eloop);
116                 if (ret)
117                         return;
118                 ret = uterm_input_register_cb(input, input_arrived, NULL);
119                 if (ret)
120                         return;
121                 uterm_input_wake_up(input);
122         } else if (ev->type == UTERM_MONITOR_FREE_SEAT) {
123                 uterm_input_unregister_cb(input, input_arrived, NULL);
124                 uterm_input_unref(input);
125         } else if (ev->type == UTERM_MONITOR_NEW_DEV) {
126                 if (ev->dev_type == UTERM_MONITOR_INPUT)
127                         uterm_input_add_dev(input, ev->dev_node);
128         } else if (ev->type == UTERM_MONITOR_FREE_DEV) {
129                 if (ev->dev_type == UTERM_MONITOR_INPUT)
130                         uterm_input_remove_dev(input, ev->dev_node);
131         }
132 }
133
134 int main(int argc, char **argv)
135 {
136         int ret;
137         struct uterm_monitor *mon;
138
139         ret = test_prepare(argc, argv, &eloop);
140         if (ret)
141                 goto err_fail;
142
143         if (!setlocale(LC_ALL, "")) {
144                 log_err("Cannot set locale: %m");
145                 ret = -EFAULT;
146                 goto err_exit;
147         }
148
149         ret = uterm_monitor_new(&mon, eloop, monitor_event, NULL);
150         if (ret)
151                 goto err_exit;
152
153         ret = ev_eloop_register_signal_cb(eloop, SIGQUIT, sig_quit, NULL);
154         if (ret)
155                 goto err_mon;
156
157         system("stty -echo");
158         uterm_monitor_scan(mon);
159         ev_eloop_run(eloop, -1);
160         system("stty echo");
161
162         ev_eloop_unregister_signal_cb(eloop, SIGQUIT, sig_quit, NULL);
163 err_mon:
164         uterm_monitor_unref(mon);
165 err_exit:
166         test_exit(eloop);
167 err_fail:
168         test_fail(ret);
169         return abs(ret);
170 }