blob: 30fe80e325a5d1ef00932d624306a08180250107 [file] [log] [blame]
Marcos Paulo de Souzaaea415b2017-04-24 16:19:49 -07001=============
2uinput module
3=============
4
5Introduction
6============
7
8uinput is a kernel module that makes it possible to emulate input devices
9from userspace. By writing to /dev/uinput (or /dev/input/uinput) device, a
10process can create a virtual input device with specific capabilities. Once
11this virtual device is created, the process can send events through it,
12that will be delivered to userspace and in-kernel consumers.
13
14Interface
15=========
16
17::
18
19 linux/uinput.h
20
21The uinput header defines ioctls to create, set up, and destroy virtual
22devices.
23
24libevdev
25========
26
27libevdev is a wrapper library for evdev devices that provides interfaces to
28create uinput devices and send events. libevdev is less error-prone than
29accessing uinput directly, and should be considered for new software.
30
31For examples and more information about libevdev:
32https://www.freedesktop.org/software/libevdev/doc/latest/
33
34Examples
35========
36
37Keyboard events
38---------------
39
40This first example shows how to create a new virtual device, and how to
41send a key event. All default imports and error handlers were removed for
42the sake of simplicity.
43
44.. code-block:: c
45
46 #include <linux/uinput.h>
47
48 void emit(int fd, int type, int code, int val)
49 {
50 struct input_event ie;
51
52 ie.type = type;
53 ie.code = code;
54 ie.value = val;
55 /* timestamp values below are ignored */
56 ie.time.tv_sec = 0;
57 ie.time.tv_usec = 0;
58
59 write(fd, &ie, sizeof(ie));
60 }
61
62 int main(void)
63 {
64 struct uinput_setup usetup;
65
66 int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
67
68
69 /*
70 * The ioctls below will enable the device that is about to be
71 * created, to pass key events, in this case the space key.
72 */
73 ioctl(fd, UI_SET_EVBIT, EV_KEY);
74 ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
75
76 memset(&usetup, 0, sizeof(usetup));
77 usetup.id.bustype = BUS_USB;
78 usetup.id.vendor = 0x1234; /* sample vendor */
79 usetup.id.product = 0x5678; /* sample product */
80 strcpy(usetup.name, "Example device");
81
82 ioctl(fd, UI_DEV_SETUP, &usetup);
83 ioctl(fd, UI_DEV_CREATE);
84
85 /*
86 * On UI_DEV_CREATE the kernel will create the device node for this
87 * device. We are inserting a pause here so that userspace has time
88 * to detect, initialize the new device, and can start listening to
89 * the event, otherwise it will not notice the event we are about
90 * to send. This pause is only needed in our example code!
91 */
92 sleep(1);
93
94 /* Key press, report the event, send key release, and report again */
95 emit(fd, EV_KEY, KEY_SPACE, 1);
96 emit(fd, EV_SYN, SYN_REPORT, 0);
97 emit(fd, EV_KEY, KEY_SPACE, 0);
98 emit(fd, EV_SYN, SYN_REPORT, 0);
99
100 /*
101 * Give userspace some time to read the events before we destroy the
Pavel Machekbbca4d342020-07-24 10:36:06 -0700102 * device with UI_DEV_DESTROY.
Marcos Paulo de Souzaaea415b2017-04-24 16:19:49 -0700103 */
104 sleep(1);
105
106 ioctl(fd, UI_DEV_DESTROY);
107 close(fd);
108
109 return 0;
110 }
111
112Mouse movements
113---------------
114
115This example shows how to create a virtual device that behaves like a physical
116mouse.
117
118.. code-block:: c
119
120 #include <linux/uinput.h>
121
122 /* emit function is identical to of the first example */
123
124 int main(void)
125 {
126 struct uinput_setup usetup;
127 int i = 50;
128
129 int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
130
131 /* enable mouse button left and relative events */
132 ioctl(fd, UI_SET_EVBIT, EV_KEY);
133 ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
134
135 ioctl(fd, UI_SET_EVBIT, EV_REL);
136 ioctl(fd, UI_SET_RELBIT, REL_X);
137 ioctl(fd, UI_SET_RELBIT, REL_Y);
138
139 memset(&usetup, 0, sizeof(usetup));
140 usetup.id.bustype = BUS_USB;
141 usetup.id.vendor = 0x1234; /* sample vendor */
142 usetup.id.product = 0x5678; /* sample product */
143 strcpy(usetup.name, "Example device");
144
145 ioctl(fd, UI_DEV_SETUP, &usetup);
146 ioctl(fd, UI_DEV_CREATE);
147
148 /*
149 * On UI_DEV_CREATE the kernel will create the device node for this
150 * device. We are inserting a pause here so that userspace has time
151 * to detect, initialize the new device, and can start listening to
152 * the event, otherwise it will not notice the event we are about
153 * to send. This pause is only needed in our example code!
154 */
155 sleep(1);
156
157 /* Move the mouse diagonally, 5 units per axis */
158 while (i--) {
159 emit(fd, EV_REL, REL_X, 5);
160 emit(fd, EV_REL, REL_Y, 5);
161 emit(fd, EV_SYN, SYN_REPORT, 0);
162 usleep(15000);
163 }
164
165 /*
166 * Give userspace some time to read the events before we destroy the
Pavel Machekbbca4d342020-07-24 10:36:06 -0700167 * device with UI_DEV_DESTROY.
Marcos Paulo de Souzaaea415b2017-04-24 16:19:49 -0700168 */
169 sleep(1);
170
171 ioctl(fd, UI_DEV_DESTROY);
172 close(fd);
173
174 return 0;
175 }
176
177
178uinput old interface
179--------------------
180
181Before uinput version 5, there wasn't a dedicated ioctl to set up a virtual
Randy Dunlap8bd490e2021-03-02 14:35:23 -0800182device. Programs supporting older versions of uinput interface need to fill
Marcos Paulo de Souzaaea415b2017-04-24 16:19:49 -0700183a uinput_user_dev structure and write it to the uinput file descriptor to
184configure the new uinput device. New code should not use the old interface
185but interact with uinput via ioctl calls, or use libevdev.
186
187.. code-block:: c
188
189 #include <linux/uinput.h>
190
191 /* emit function is identical to of the first example */
192
193 int main(void)
194 {
195 struct uinput_user_dev uud;
196 int version, rc, fd;
197
198 fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
199 rc = ioctl(fd, UI_GET_VERSION, &version);
200
201 if (rc == 0 && version >= 5) {
202 /* use UI_DEV_SETUP */
203 return 0;
204 }
205
206 /*
207 * The ioctls below will enable the device that is about to be
208 * created, to pass key events, in this case the space key.
209 */
210 ioctl(fd, UI_SET_EVBIT, EV_KEY);
211 ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
212
213 memset(&uud, 0, sizeof(uud));
214 snprintf(uud.name, UINPUT_MAX_NAME_SIZE, "uinput old interface");
215 write(fd, &uud, sizeof(uud));
216
217 ioctl(fd, UI_DEV_CREATE);
218
219 /*
220 * On UI_DEV_CREATE the kernel will create the device node for this
221 * device. We are inserting a pause here so that userspace has time
222 * to detect, initialize the new device, and can start listening to
223 * the event, otherwise it will not notice the event we are about
224 * to send. This pause is only needed in our example code!
225 */
226 sleep(1);
227
228 /* Key press, report the event, send key release, and report again */
229 emit(fd, EV_KEY, KEY_SPACE, 1);
230 emit(fd, EV_SYN, SYN_REPORT, 0);
231 emit(fd, EV_KEY, KEY_SPACE, 0);
232 emit(fd, EV_SYN, SYN_REPORT, 0);
233
234 /*
235 * Give userspace some time to read the events before we destroy the
Pavel Machekbbca4d342020-07-24 10:36:06 -0700236 * device with UI_DEV_DESTROY.
Marcos Paulo de Souzaaea415b2017-04-24 16:19:49 -0700237 */
238 sleep(1);
239
240 ioctl(fd, UI_DEV_DESTROY);
241
242 close(fd);
243 return 0;
244 }
245