input_device/platform/linux/
evdev.rs

1#![allow(dead_code)]
2use crate::{
3    ButtonId, ElementState, Event, KeyboardInput, MouseButton, MouseScrollDelta, VirtualKeyCode,
4};
5use libc::{input_event, timeval};
6use std::convert::{TryFrom, TryInto};
7use std::fmt::{self, Debug, Display};
8use std::fs::{self, File};
9use std::io::{ErrorKind, Read};
10use std::os::unix::io::{AsRawFd, RawFd};
11use std::path::Path;
12use std::str::FromStr;
13use std::sync::{Arc, Mutex};
14
15const EV_SYN: u16 = 0x00;
16const EV_KEY: u16 = 0x01;
17const EV_REL: u16 = 0x02;
18const EV_ABS: u16 = 0x03;
19const EV_MSC: u16 = 0x04;
20const EV_SW: u16 = 0x05;
21const EV_LED: u16 = 0x11;
22const EV_SND: u16 = 0x12;
23const EV_REP: u16 = 0x14;
24const EV_FF: u16 = 0x15;
25const EV_PWR: u16 = 0x16;
26const EV_FF_STATUS: u16 = 0x17;
27const EV_MAX: u16 = 0x1f;
28const EV_CNT: u16 = EV_MAX + 1;
29
30const KEY_RESERVED: u16 = 0;
31const KEY_ESC: u16 = 1;
32const KEY_1: u16 = 2;
33const KEY_2: u16 = 3;
34const KEY_3: u16 = 4;
35const KEY_4: u16 = 5;
36const KEY_5: u16 = 6;
37const KEY_6: u16 = 7;
38const KEY_7: u16 = 8;
39const KEY_8: u16 = 9;
40const KEY_9: u16 = 10;
41const KEY_0: u16 = 11;
42const KEY_MINUS: u16 = 12;
43const KEY_EQUAL: u16 = 13;
44const KEY_BACKSPACE: u16 = 14;
45const KEY_TAB: u16 = 15;
46const KEY_Q: u16 = 16;
47const KEY_W: u16 = 17;
48const KEY_E: u16 = 18;
49const KEY_R: u16 = 19;
50const KEY_T: u16 = 20;
51const KEY_Y: u16 = 21;
52const KEY_U: u16 = 22;
53const KEY_I: u16 = 23;
54const KEY_O: u16 = 24;
55const KEY_P: u16 = 25;
56const KEY_LEFTBRACE: u16 = 26;
57const KEY_RIGHTBRACE: u16 = 27;
58const KEY_ENTER: u16 = 28;
59const KEY_LEFTCTRL: u16 = 29;
60const KEY_A: u16 = 30;
61const KEY_S: u16 = 31;
62const KEY_D: u16 = 32;
63const KEY_F: u16 = 33;
64const KEY_G: u16 = 34;
65const KEY_H: u16 = 35;
66const KEY_J: u16 = 36;
67const KEY_K: u16 = 37;
68const KEY_L: u16 = 38;
69const KEY_SEMICOLON: u16 = 39;
70const KEY_APOSTROPHE: u16 = 40;
71const KEY_GRAVE: u16 = 41;
72const KEY_LEFTSHIFT: u16 = 42;
73const KEY_BACKSLASH: u16 = 43;
74const KEY_Z: u16 = 44;
75const KEY_X: u16 = 45;
76const KEY_C: u16 = 46;
77const KEY_V: u16 = 47;
78const KEY_B: u16 = 48;
79const KEY_N: u16 = 49;
80const KEY_M: u16 = 50;
81const KEY_COMMA: u16 = 51;
82const KEY_DOT: u16 = 52;
83const KEY_SLASH: u16 = 53;
84const KEY_RIGHTSHIFT: u16 = 54;
85const KEY_KPASTERISK: u16 = 55;
86const KEY_LEFTALT: u16 = 56;
87const KEY_SPACE: u16 = 57;
88const KEY_CAPSLOCK: u16 = 58;
89const KEY_F1: u16 = 59;
90const KEY_F2: u16 = 60;
91const KEY_F3: u16 = 61;
92const KEY_F4: u16 = 62;
93const KEY_F5: u16 = 63;
94const KEY_F6: u16 = 64;
95const KEY_F7: u16 = 65;
96const KEY_F8: u16 = 66;
97const KEY_F9: u16 = 67;
98const KEY_F10: u16 = 68;
99const KEY_NUMLOCK: u16 = 69;
100const KEY_SCROLLLOCK: u16 = 70;
101const KEY_KP7: u16 = 71;
102const KEY_KP8: u16 = 72;
103const KEY_KP9: u16 = 73;
104const KEY_KPMINUS: u16 = 74;
105const KEY_KP4: u16 = 75;
106const KEY_KP5: u16 = 76;
107const KEY_KP6: u16 = 77;
108const KEY_KPPLUS: u16 = 78;
109const KEY_KP1: u16 = 79;
110const KEY_KP2: u16 = 80;
111const KEY_KP3: u16 = 81;
112const KEY_KP0: u16 = 82;
113const KEY_KPDOT: u16 = 83;
114
115const KEY_ZENKAKUHANKAKU: u16 = 85;
116const KEY_102ND: u16 = 86;
117const KEY_F11: u16 = 87;
118const KEY_F12: u16 = 88;
119const KEY_RO: u16 = 89;
120const KEY_KATAKANA: u16 = 90;
121const KEY_HIRAGANA: u16 = 91;
122const KEY_HENKAN: u16 = 92;
123const KEY_KATAKANAHIRAGANA: u16 = 93;
124const KEY_MUHENKAN: u16 = 94;
125const KEY_KPJPCOMMA: u16 = 95;
126const KEY_KPENTER: u16 = 96;
127const KEY_RIGHTCTRL: u16 = 97;
128const KEY_KPSLASH: u16 = 98;
129const KEY_SYSRQ: u16 = 99;
130const KEY_RIGHTALT: u16 = 100;
131const KEY_LINEFEED: u16 = 101;
132const KEY_HOME: u16 = 102;
133const KEY_UP: u16 = 103;
134const KEY_PAGEUP: u16 = 104;
135const KEY_LEFT: u16 = 105;
136const KEY_RIGHT: u16 = 106;
137const KEY_END: u16 = 107;
138const KEY_DOWN: u16 = 108;
139const KEY_PAGEDOWN: u16 = 109;
140const KEY_INSERT: u16 = 110;
141const KEY_DELETE: u16 = 111;
142const KEY_MACRO: u16 = 112;
143const KEY_MUTE: u16 = 113;
144const KEY_VOLUMEDOWN: u16 = 114;
145const KEY_VOLUMEUP: u16 = 115;
146const KEY_POWER: u16 = 116; // SC System Power Down
147const KEY_KPEQUAL: u16 = 117;
148const KEY_KPPLUSMINUS: u16 = 118;
149const KEY_PAUSE: u16 = 119;
150const KEY_SCALE: u16 = 120; // AL Compiz Scale (Expose)
151
152const KEY_KPCOMMA: u16 = 121;
153const KEY_HANGEUL: u16 = 122;
154const KEY_HANGUEL: u16 = KEY_HANGEUL;
155const KEY_HANJA: u16 = 123;
156const KEY_YEN: u16 = 124;
157const KEY_LEFTMETA: u16 = 125;
158const KEY_RIGHTMETA: u16 = 126;
159const KEY_COMPOSE: u16 = 127;
160
161const KEY_STOP: u16 = 128; // AC Stop
162const KEY_AGAIN: u16 = 129;
163const KEY_PROPS: u16 = 130; // AC Properties
164const KEY_UNDO: u16 = 131; // AC Undo
165const KEY_FRONT: u16 = 132;
166const KEY_COPY: u16 = 133; // AC Copy
167const KEY_OPEN: u16 = 134; // AC Open
168const KEY_PASTE: u16 = 135; // AC Paste
169const KEY_FIND: u16 = 136; // AC Search
170const KEY_CUT: u16 = 137; // AC Cut
171const KEY_HELP: u16 = 138; // AL Integrated Help Center
172const KEY_MENU: u16 = 139; // Menu (show menu)
173const KEY_CALC: u16 = 140; // AL Calculator
174const KEY_SETUP: u16 = 141;
175const KEY_SLEEP: u16 = 142; // SC System Sleep
176const KEY_WAKEUP: u16 = 143; // System Wake Up
177const KEY_FILE: u16 = 144; // AL Local Machine Browser
178const KEY_SENDFILE: u16 = 145;
179const KEY_DELETEFILE: u16 = 146;
180const KEY_XFER: u16 = 147;
181const KEY_PROG1: u16 = 148;
182const KEY_PROG2: u16 = 149;
183const KEY_WWW: u16 = 150; // AL Internet Browser
184const KEY_MSDOS: u16 = 151;
185const KEY_COFFEE: u16 = 152; // AL Terminal Lock/Screensaver
186const KEY_SCREENLOCK: u16 = KEY_COFFEE;
187const KEY_ROTATE_DISPLAY: u16 = 153; // Display orientation for e.g. tablets
188const KEY_DIRECTION: u16 = KEY_ROTATE_DISPLAY;
189const KEY_CYCLEWINDOWS: u16 = 154;
190const KEY_MAIL: u16 = 155;
191const KEY_BOOKMARKS: u16 = 156; // AC Bookmarks
192const KEY_COMPUTER: u16 = 157;
193const KEY_BACK: u16 = 158; // AC Back
194const KEY_FORWARD: u16 = 159; // AC Forward
195const KEY_CLOSECD: u16 = 160;
196const KEY_EJECTCD: u16 = 161;
197const KEY_EJECTCLOSECD: u16 = 162;
198const KEY_NEXTSONG: u16 = 163;
199const KEY_PLAYPAUSE: u16 = 164;
200const KEY_PREVIOUSSONG: u16 = 165;
201const KEY_STOPCD: u16 = 166;
202const KEY_RECORD: u16 = 167;
203const KEY_REWIND: u16 = 168;
204const KEY_PHONE: u16 = 169; // Media Select Telephone
205const KEY_ISO: u16 = 170;
206const KEY_CONFIG: u16 = 171; // AL Consumer Control Configuration
207const KEY_HOMEPAGE: u16 = 172; // AC Home
208const KEY_REFRESH: u16 = 173; // AC Refresh
209const KEY_EXIT: u16 = 174; // AC Exit
210const KEY_MOVE: u16 = 175;
211const KEY_EDIT: u16 = 176;
212const KEY_SCROLLUP: u16 = 177;
213const KEY_SCROLLDOWN: u16 = 178;
214const KEY_KPLEFTPAREN: u16 = 179;
215const KEY_KPRIGHTPAREN: u16 = 180;
216const KEY_NEW: u16 = 181; // AC New
217const KEY_REDO: u16 = 182; // AC Redo/Repeat
218
219const KEY_F13: u16 = 183;
220const KEY_F14: u16 = 184;
221const KEY_F15: u16 = 185;
222const KEY_F16: u16 = 186;
223const KEY_F17: u16 = 187;
224const KEY_F18: u16 = 188;
225const KEY_F19: u16 = 189;
226const KEY_F20: u16 = 190;
227const KEY_F21: u16 = 191;
228const KEY_F22: u16 = 192;
229const KEY_F23: u16 = 193;
230const KEY_F24: u16 = 194;
231
232const KEY_PLAYCD: u16 = 200;
233const KEY_PAUSECD: u16 = 201;
234const KEY_PROG3: u16 = 202;
235const KEY_PROG4: u16 = 203;
236const KEY_DASHBOARD: u16 = 204; // AL Dashboard
237const KEY_SUSPEND: u16 = 205;
238const KEY_CLOSE: u16 = 206; // AC Close
239const KEY_PLAY: u16 = 207;
240const KEY_FASTFORWARD: u16 = 208;
241const KEY_BASSBOOST: u16 = 209;
242const KEY_PRINT: u16 = 210; // AC Print
243const KEY_HP: u16 = 211;
244const KEY_CAMERA: u16 = 212;
245const KEY_SOUND: u16 = 213;
246const KEY_QUESTION: u16 = 214;
247const KEY_EMAIL: u16 = 215;
248const KEY_CHAT: u16 = 216;
249const KEY_SEARCH: u16 = 217;
250const KEY_CONNECT: u16 = 218;
251const KEY_FINANCE: u16 = 219; // AL Checkbook/Finance
252const KEY_SPORT: u16 = 220;
253const KEY_SHOP: u16 = 221;
254const KEY_ALTERASE: u16 = 222;
255const KEY_CANCEL: u16 = 223; // AC Cancel
256const KEY_BRIGHTNESSDOWN: u16 = 224;
257const KEY_BRIGHTNESSUP: u16 = 225;
258const KEY_MEDIA: u16 = 226;
259
260// Cycle between available video outputs (Monitor/LCD/TV-out/etc)
261const KEY_SWITCHVIDEOMODE: u16 = 227;
262const KEY_KBDILLUMTOGGLE: u16 = 228;
263const KEY_KBDILLUMDOWN: u16 = 229;
264const KEY_KBDILLUMUP: u16 = 230;
265
266const KEY_SEND: u16 = 231; // AC Send
267const KEY_REPLY: u16 = 232; // AC Reply
268const KEY_FORWARDMAIL: u16 = 233; // AC Forward Msg
269const KEY_SAVE: u16 = 234; // AC Save
270const KEY_DOCUMENTS: u16 = 235;
271
272const KEY_BATTERY: u16 = 236;
273
274const KEY_BLUETOOTH: u16 = 237;
275const KEY_WLAN: u16 = 238;
276const KEY_UWB: u16 = 239;
277
278const KEY_UNKNOWN: u16 = 240;
279
280const KEY_VIDEO_NEXT: u16 = 241; // drive next video source
281const KEY_VIDEO_PREV: u16 = 242; // drive previous video source
282const KEY_BRIGHTNESS_CYCLE: u16 = 243; // brightness up, after max is min
283                                       // Set Auto Brightness: manual; brightness control is off, rely on ambient
284const KEY_BRIGHTNESS_AUTO: u16 = 244;
285const KEY_BRIGHTNESS_ZERO: u16 = KEY_BRIGHTNESS_AUTO;
286const KEY_DISPLAY_OFF: u16 = 245; // display device to off state
287
288const KEY_WWAN: u16 = 246; // Wireless WAN (LTE, UMTS, GSM, etc.)
289const KEY_WIMAX: u16 = KEY_WWAN;
290const KEY_RFKILL: u16 = 247; // Key that controls all radios
291
292const KEY_MICMUTE: u16 = 248; // Mute / unmute the microphone
293
294// Code 255 is reserved for special needs of AT keyboard driver
295
296const BTN_MISC: u16 = 0x100;
297
298const BTN_0: u16 = 0x100;
299const BTN_1: u16 = 0x101;
300const BTN_2: u16 = 0x102;
301const BTN_3: u16 = 0x103;
302const BTN_4: u16 = 0x104;
303const BTN_5: u16 = 0x105;
304const BTN_6: u16 = 0x106;
305const BTN_7: u16 = 0x107;
306const BTN_8: u16 = 0x108;
307const BTN_9: u16 = 0x109;
308
309const BTN_MOUSE: u16 = 0x110;
310const BTN_LEFT: u16 = 0x110;
311const BTN_RIGHT: u16 = 0x111;
312const BTN_MIDDLE: u16 = 0x112;
313const BTN_SIDE: u16 = 0x113;
314const BTN_EXTRA: u16 = 0x114;
315const BTN_FORWARD: u16 = 0x115;
316const BTN_BACK: u16 = 0x116;
317const BTN_TASK: u16 = 0x117;
318
319const BTN_JOYSTICK: u16 = 0x120;
320const BTN_TRIGGER: u16 = 0x120;
321const BTN_THUMB: u16 = 0x121;
322const BTN_THUMB2: u16 = 0x122;
323const BTN_TOP: u16 = 0x123;
324const BTN_TOP2: u16 = 0x124;
325const BTN_PINKIE: u16 = 0x125;
326const BTN_BASE: u16 = 0x126;
327const BTN_BASE2: u16 = 0x127;
328const BTN_BASE3: u16 = 0x128;
329const BTN_BASE4: u16 = 0x129;
330const BTN_BASE5: u16 = 0x12a;
331const BTN_BASE6: u16 = 0x12b;
332const BTN_DEAD: u16 = 0x12f;
333
334const BTN_GAMEPAD: u16 = 0x130;
335const BTN_SOUTH: u16 = 0x130;
336const BTN_A: u16 = BTN_SOUTH;
337const BTN_EAST: u16 = 0x131;
338const BTN_B: u16 = BTN_EAST;
339const BTN_C: u16 = 0x132;
340const BTN_NORTH: u16 = 0x133;
341const BTN_X: u16 = BTN_NORTH;
342const BTN_WEST: u16 = 0x134;
343const BTN_Y: u16 = BTN_WEST;
344const BTN_Z: u16 = 0x135;
345const BTN_TL: u16 = 0x136;
346const BTN_TR: u16 = 0x137;
347const BTN_TL2: u16 = 0x138;
348const BTN_TR2: u16 = 0x139;
349const BTN_SELECT: u16 = 0x13a;
350const BTN_START: u16 = 0x13b;
351const BTN_MODE: u16 = 0x13c;
352const BTN_THUMBL: u16 = 0x13d;
353const BTN_THUMBR: u16 = 0x13e;
354
355const BTN_DIGI: u16 = 0x140;
356const BTN_TOOL_PEN: u16 = 0x140;
357const BTN_TOOL_RUBBER: u16 = 0x141;
358const BTN_TOOL_BRUSH: u16 = 0x142;
359const BTN_TOOL_PENCIL: u16 = 0x143;
360const BTN_TOOL_AIRBRUSH: u16 = 0x144;
361const BTN_TOOL_FINGER: u16 = 0x145;
362const BTN_TOOL_MOUSE: u16 = 0x146;
363const BTN_TOOL_LENS: u16 = 0x147;
364const BTN_TOOL_QUINTTAP: u16 = 0x148; // Five fingers on trackpad
365const BTN_TOUCH: u16 = 0x14a;
366const BTN_STYLUS: u16 = 0x14b;
367const BTN_STYLUS2: u16 = 0x14c;
368const BTN_TOOL_DOUBLETAP: u16 = 0x14d;
369const BTN_TOOL_TRIPLETAP: u16 = 0x14e;
370const BTN_TOOL_QUADTAP: u16 = 0x14f; // Four fingers on trackpad
371
372const BTN_WHEEL: u16 = 0x150;
373const BTN_GEAR_DOWN: u16 = 0x150;
374const BTN_GEAR_UP: u16 = 0x151;
375
376const KEY_OK: u16 = 0x160;
377const KEY_SELECT: u16 = 0x161;
378const KEY_GOTO: u16 = 0x162;
379const KEY_CLEAR: u16 = 0x163;
380const KEY_POWER2: u16 = 0x164;
381const KEY_OPTION: u16 = 0x165;
382const KEY_INFO: u16 = 0x166; // AL OEM Features/Tips/Tutorial
383const KEY_TIME: u16 = 0x167;
384const KEY_VENDOR: u16 = 0x168;
385const KEY_ARCHIVE: u16 = 0x169;
386const KEY_PROGRAM: u16 = 0x16a; // Media Select Program Guide
387const KEY_CHANNEL: u16 = 0x16b;
388const KEY_FAVORITES: u16 = 0x16c;
389const KEY_EPG: u16 = 0x16d;
390const KEY_PVR: u16 = 0x16e; // Media Select Home
391const KEY_MHP: u16 = 0x16f;
392const KEY_LANGUAGE: u16 = 0x170;
393const KEY_TITLE: u16 = 0x171;
394const KEY_SUBTITLE: u16 = 0x172;
395const KEY_ANGLE: u16 = 0x173;
396const KEY_ZOOM: u16 = 0x174;
397const KEY_MODE: u16 = 0x175;
398const KEY_KEYBOARD: u16 = 0x176;
399const KEY_SCREEN: u16 = 0x177;
400const KEY_PC: u16 = 0x178; // Media Select Computer
401const KEY_TV: u16 = 0x179; // Media Select TV
402const KEY_TV2: u16 = 0x17a; // Media Select Cable
403const KEY_VCR: u16 = 0x17b; // Media Select VCR
404const KEY_VCR2: u16 = 0x17c; // VCR Plus
405const KEY_SAT: u16 = 0x17d; // Media Select Satellite
406const KEY_SAT2: u16 = 0x17e;
407const KEY_CD: u16 = 0x17f; // Media Select CD
408const KEY_TAPE: u16 = 0x180; // Media Select Tape
409const KEY_RADIO: u16 = 0x181;
410const KEY_TUNER: u16 = 0x182; // Media Select Tuner
411const KEY_PLAYER: u16 = 0x183;
412const KEY_TEXT: u16 = 0x184;
413const KEY_DVD: u16 = 0x185; // Media Select DVD
414const KEY_AUX: u16 = 0x186;
415const KEY_MP3: u16 = 0x187;
416const KEY_AUDIO: u16 = 0x188; // AL Audio Browser
417const KEY_VIDEO: u16 = 0x189; // AL Movie Browser
418const KEY_DIRECTORY: u16 = 0x18a;
419const KEY_LIST: u16 = 0x18b;
420const KEY_MEMO: u16 = 0x18c; // Media Select Messages
421const KEY_CALENDAR: u16 = 0x18d;
422const KEY_RED: u16 = 0x18e;
423const KEY_GREEN: u16 = 0x18f;
424const KEY_YELLOW: u16 = 0x190;
425const KEY_BLUE: u16 = 0x191;
426const KEY_CHANNELUP: u16 = 0x192; // Channel Increment
427const KEY_CHANNELDOWN: u16 = 0x193; // Channel Decrement
428const KEY_FIRST: u16 = 0x194;
429const KEY_LAST: u16 = 0x195; // Recall Last
430const KEY_AB: u16 = 0x196;
431const KEY_NEXT: u16 = 0x197;
432const KEY_RESTART: u16 = 0x198;
433const KEY_SLOW: u16 = 0x199;
434const KEY_SHUFFLE: u16 = 0x19a;
435const KEY_BREAK: u16 = 0x19b;
436const KEY_PREVIOUS: u16 = 0x19c;
437const KEY_DIGITS: u16 = 0x19d;
438const KEY_TEEN: u16 = 0x19e;
439const KEY_TWEN: u16 = 0x19f;
440const KEY_VIDEOPHONE: u16 = 0x1a0; // Media Select Video Phone
441const KEY_GAMES: u16 = 0x1a1; // Media Select Games
442const KEY_ZOOMIN: u16 = 0x1a2; // AC Zoom In
443const KEY_ZOOMOUT: u16 = 0x1a3; // AC Zoom Out
444const KEY_ZOOMRESET: u16 = 0x1a4; // AC Zoom
445const KEY_WORDPROCESSOR: u16 = 0x1a5; // AL Word Processor
446const KEY_EDITOR: u16 = 0x1a6; // AL Text Editor
447const KEY_SPREADSHEET: u16 = 0x1a7; // AL Spreadsheet
448const KEY_GRAPHICSEDITOR: u16 = 0x1a8; // AL Graphics Editor
449const KEY_PRESENTATION: u16 = 0x1a9; // AL Presentation App
450const KEY_DATABASE: u16 = 0x1aa; // AL Database App
451const KEY_NEWS: u16 = 0x1ab; // AL Newsreader
452const KEY_VOICEMAIL: u16 = 0x1ac; // AL Voicemail
453const KEY_ADDRESSBOOK: u16 = 0x1ad; // AL Contacts/Address Book
454const KEY_MESSENGER: u16 = 0x1ae; // AL Instant Messaging
455const KEY_DISPLAYTOGGLE: u16 = 0x1af; // Turn display (LCD) on and off
456const KEY_BRIGHTNESS_TOGGLE: u16 = KEY_DISPLAYTOGGLE;
457const KEY_SPELLCHECK: u16 = 0x1b0; // AL Spell Check
458const KEY_LOGOFF: u16 = 0x1b1; // AL Logoff
459
460const KEY_DOLLAR: u16 = 0x1b2;
461const KEY_EURO: u16 = 0x1b3;
462
463const KEY_FRAMEBACK: u16 = 0x1b4; // Consumer - transport controls
464const KEY_FRAMEFORWARD: u16 = 0x1b5;
465const KEY_CONTEXT_MENU: u16 = 0x1b6; // GenDesc - system context menu
466const KEY_MEDIA_REPEAT: u16 = 0x1b7; // Consumer - transport control
467const KEY_10CHANNELSUP: u16 = 0x1b8; // 10 channels up (10+)
468const KEY_10CHANNELSDOWN: u16 = 0x1b9; // 10 channels down (10-)
469const KEY_IMAGES: u16 = 0x1ba; // AL Image Browser
470
471const KEY_DEL_EOL: u16 = 0x1c0;
472const KEY_DEL_EOS: u16 = 0x1c1;
473const KEY_INS_LINE: u16 = 0x1c2;
474const KEY_DEL_LINE: u16 = 0x1c3;
475
476const KEY_FN: u16 = 0x1d0;
477const KEY_FN_ESC: u16 = 0x1d1;
478const KEY_FN_F1: u16 = 0x1d2;
479const KEY_FN_F2: u16 = 0x1d3;
480const KEY_FN_F3: u16 = 0x1d4;
481const KEY_FN_F4: u16 = 0x1d5;
482const KEY_FN_F5: u16 = 0x1d6;
483const KEY_FN_F6: u16 = 0x1d7;
484const KEY_FN_F7: u16 = 0x1d8;
485const KEY_FN_F8: u16 = 0x1d9;
486const KEY_FN_F9: u16 = 0x1da;
487const KEY_FN_F10: u16 = 0x1db;
488const KEY_FN_F11: u16 = 0x1dc;
489const KEY_FN_F12: u16 = 0x1dd;
490const KEY_FN_1: u16 = 0x1de;
491const KEY_FN_2: u16 = 0x1df;
492const KEY_FN_D: u16 = 0x1e0;
493const KEY_FN_E: u16 = 0x1e1;
494const KEY_FN_F: u16 = 0x1e2;
495const KEY_FN_S: u16 = 0x1e3;
496const KEY_FN_B: u16 = 0x1e4;
497
498const KEY_BRL_DOT1: u16 = 0x1f1;
499const KEY_BRL_DOT2: u16 = 0x1f2;
500const KEY_BRL_DOT3: u16 = 0x1f3;
501const KEY_BRL_DOT4: u16 = 0x1f4;
502const KEY_BRL_DOT5: u16 = 0x1f5;
503const KEY_BRL_DOT6: u16 = 0x1f6;
504const KEY_BRL_DOT7: u16 = 0x1f7;
505const KEY_BRL_DOT8: u16 = 0x1f8;
506const KEY_BRL_DOT9: u16 = 0x1f9;
507const KEY_BRL_DOT10: u16 = 0x1fa;
508
509const KEY_NUMERIC_0: u16 = 0x200; // used by phones, remote controls,
510const KEY_NUMERIC_1: u16 = 0x201; // and other keypads
511const KEY_NUMERIC_2: u16 = 0x202;
512const KEY_NUMERIC_3: u16 = 0x203;
513const KEY_NUMERIC_4: u16 = 0x204;
514const KEY_NUMERIC_5: u16 = 0x205;
515const KEY_NUMERIC_6: u16 = 0x206;
516const KEY_NUMERIC_7: u16 = 0x207;
517const KEY_NUMERIC_8: u16 = 0x208;
518const KEY_NUMERIC_9: u16 = 0x209;
519const KEY_NUMERIC_STAR: u16 = 0x20a;
520const KEY_NUMERIC_POUND: u16 = 0x20b;
521const KEY_NUMERIC_A: u16 = 0x20c; // Phone key A - HUT Telephony 0xb9
522const KEY_NUMERIC_B: u16 = 0x20d;
523const KEY_NUMERIC_C: u16 = 0x20e;
524const KEY_NUMERIC_D: u16 = 0x20f;
525
526const KEY_CAMERA_FOCUS: u16 = 0x210;
527const KEY_WPS_BUTTON: u16 = 0x211; // WiFi Protected Setup key
528
529const KEY_TOUCHPAD_TOGGLE: u16 = 0x212; // Request switch touchpad on or off
530const KEY_TOUCHPAD_ON: u16 = 0x213;
531const KEY_TOUCHPAD_OFF: u16 = 0x214;
532
533const KEY_CAMERA_ZOOMIN: u16 = 0x215;
534const KEY_CAMERA_ZOOMOUT: u16 = 0x216;
535const KEY_CAMERA_UP: u16 = 0x217;
536const KEY_CAMERA_DOWN: u16 = 0x218;
537const KEY_CAMERA_LEFT: u16 = 0x219;
538const KEY_CAMERA_RIGHT: u16 = 0x21a;
539
540const KEY_ATTENDANT_ON: u16 = 0x21b;
541const KEY_ATTENDANT_OFF: u16 = 0x21c;
542const KEY_ATTENDANT_TOGGLE: u16 = 0x21d; // Attendant call on or off
543const KEY_LIGHTS_TOGGLE: u16 = 0x21e; // Reading light on or off
544
545const BTN_DPAD_UP: u16 = 0x220;
546const BTN_DPAD_DOWN: u16 = 0x221;
547const BTN_DPAD_LEFT: u16 = 0x222;
548const BTN_DPAD_RIGHT: u16 = 0x223;
549
550const KEY_ALS_TOGGLE: u16 = 0x230; // Ambient light sensor
551
552const KEY_BUTTONCONFIG: u16 = 0x240; // AL Button Configuration
553const KEY_TASKMANAGER: u16 = 0x241; // AL Task/Project Manager
554const KEY_JOURNAL: u16 = 0x242; // AL Log/Journal/Timecard
555const KEY_CONTROLPANEL: u16 = 0x243; // AL Control Panel
556const KEY_APPSELECT: u16 = 0x244; // AL Select Task/Application
557const KEY_SCREENSAVER: u16 = 0x245; // AL Screen Saver
558const KEY_VOICECOMMAND: u16 = 0x246; // Listening Voice Command
559
560const KEY_BRIGHTNESS_MIN: u16 = 0x250; // Set Brightness to Minimum
561const KEY_BRIGHTNESS_MAX: u16 = 0x251; // Set Brightness to Maximum
562
563const KEY_KBDINPUTASSIST_PREV: u16 = 0x260;
564const KEY_KBDINPUTASSIST_NEXT: u16 = 0x261;
565const KEY_KBDINPUTASSIST_PREVGROUP: u16 = 0x262;
566const KEY_KBDINPUTASSIST_NEXTGROUP: u16 = 0x263;
567const KEY_KBDINPUTASSIST_ACCEPT: u16 = 0x264;
568const KEY_KBDINPUTASSIST_CANCEL: u16 = 0x265;
569
570// Diagonal movement keys
571const KEY_RIGHT_UP: u16 = 0x266;
572const KEY_RIGHT_DOWN: u16 = 0x267;
573const KEY_LEFT_UP: u16 = 0x268;
574const KEY_LEFT_DOWN: u16 = 0x269;
575
576// Show Device's Root Menu
577const KEY_ROOT_MENU: u16 = 0x26a;
578// Show Top Menu of the Media (e.g. DVD)
579const KEY_MEDIA_TOP_MENU: u16 = 0x26b;
580const KEY_NUMERIC_11: u16 = 0x26c;
581const KEY_NUMERIC_12: u16 = 0x26d;
582
583// Toggle Audio Description: refers to an audio service that helps blind and
584// visually impaired consumers understand the action in a program. Note: in
585// some countries this is referred to as "Video Description".
586const KEY_AUDIO_DESC: u16 = 0x26e;
587const KEY_3D_MODE: u16 = 0x26f;
588const KEY_NEXT_FAVORITE: u16 = 0x270;
589const KEY_STOP_RECORD: u16 = 0x271;
590const KEY_PAUSE_RECORD: u16 = 0x272;
591const KEY_VOD: u16 = 0x273; // Video on Demand
592const KEY_UNMUTE: u16 = 0x274;
593const KEY_FASTREVERSE: u16 = 0x275;
594const KEY_SLOWREVERSE: u16 = 0x276;
595
596// Control a data application associated with the currently viewed channel,
597// e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
598const KEY_DATA: u16 = 0x277;
599
600const BTN_TRIGGER_HAPPY: u16 = 0x2c0;
601const BTN_TRIGGER_HAPPY1: u16 = 0x2c0;
602const BTN_TRIGGER_HAPPY2: u16 = 0x2c1;
603const BTN_TRIGGER_HAPPY3: u16 = 0x2c2;
604const BTN_TRIGGER_HAPPY4: u16 = 0x2c3;
605const BTN_TRIGGER_HAPPY5: u16 = 0x2c4;
606const BTN_TRIGGER_HAPPY6: u16 = 0x2c5;
607const BTN_TRIGGER_HAPPY7: u16 = 0x2c6;
608const BTN_TRIGGER_HAPPY8: u16 = 0x2c7;
609const BTN_TRIGGER_HAPPY9: u16 = 0x2c8;
610const BTN_TRIGGER_HAPPY10: u16 = 0x2c9;
611const BTN_TRIGGER_HAPPY11: u16 = 0x2ca;
612const BTN_TRIGGER_HAPPY12: u16 = 0x2cb;
613const BTN_TRIGGER_HAPPY13: u16 = 0x2cc;
614const BTN_TRIGGER_HAPPY14: u16 = 0x2cd;
615const BTN_TRIGGER_HAPPY15: u16 = 0x2ce;
616const BTN_TRIGGER_HAPPY16: u16 = 0x2cf;
617const BTN_TRIGGER_HAPPY17: u16 = 0x2d0;
618const BTN_TRIGGER_HAPPY18: u16 = 0x2d1;
619const BTN_TRIGGER_HAPPY19: u16 = 0x2d2;
620const BTN_TRIGGER_HAPPY20: u16 = 0x2d3;
621const BTN_TRIGGER_HAPPY21: u16 = 0x2d4;
622const BTN_TRIGGER_HAPPY22: u16 = 0x2d5;
623const BTN_TRIGGER_HAPPY23: u16 = 0x2d6;
624const BTN_TRIGGER_HAPPY24: u16 = 0x2d7;
625const BTN_TRIGGER_HAPPY25: u16 = 0x2d8;
626const BTN_TRIGGER_HAPPY26: u16 = 0x2d9;
627const BTN_TRIGGER_HAPPY27: u16 = 0x2da;
628const BTN_TRIGGER_HAPPY28: u16 = 0x2db;
629const BTN_TRIGGER_HAPPY29: u16 = 0x2dc;
630const BTN_TRIGGER_HAPPY30: u16 = 0x2dd;
631const BTN_TRIGGER_HAPPY31: u16 = 0x2de;
632const BTN_TRIGGER_HAPPY32: u16 = 0x2df;
633const BTN_TRIGGER_HAPPY33: u16 = 0x2e0;
634const BTN_TRIGGER_HAPPY34: u16 = 0x2e1;
635const BTN_TRIGGER_HAPPY35: u16 = 0x2e2;
636const BTN_TRIGGER_HAPPY36: u16 = 0x2e3;
637const BTN_TRIGGER_HAPPY37: u16 = 0x2e4;
638const BTN_TRIGGER_HAPPY38: u16 = 0x2e5;
639const BTN_TRIGGER_HAPPY39: u16 = 0x2e6;
640const BTN_TRIGGER_HAPPY40: u16 = 0x2e7;
641
642/// Relative axes
643const REL_X: u16 = 0x00;
644const REL_Y: u16 = 0x01;
645const REL_Z: u16 = 0x02;
646const REL_RX: u16 = 0x03;
647const REL_RY: u16 = 0x04;
648const REL_RZ: u16 = 0x05;
649const REL_HWHEEL: u16 = 0x06;
650const REL_DIAL: u16 = 0x07;
651const REL_WHEEL: u16 = 0x08;
652const REL_MISC: u16 = 0x09;
653// 0x0a is reserved and should not be used in input drivers.
654// It was used by HID as REL_MISC+1 and userspace needs to detect if
655// the next REL_* event is correct or is just REL_MISC + n.
656// We define here REL_RESERVED so userspace can rely on it and detect
657// the situation described above.
658const REL_RESERVED: u16 = 0x0a;
659const REL_WHEEL_HI_RES: u16 = 0x0b;
660const REL_HWHEEL_HI_RES: u16 = 0x0c;
661const REL_MAX: u16 = 0x0f;
662const REL_CNT: u16 = REL_MAX + 1;
663
664const EVIOCGREP: usize = 2148025603;
665const EVIOCSREP: usize = 1074283779;
666
667impl From<u16> for ButtonId {
668    fn from(val: u16) -> Self {
669        match val {
670            0x100..=0x109 => ButtonId((val - 0x100) as u32),
671            _ => ButtonId(0),
672        }
673    }
674}
675
676impl From<i32> for ElementState {
677    fn from(val: i32) -> Self {
678        match val {
679            0 => Self::Released,
680            1 => Self::Pressed,
681            2 => Self::Repeated,
682            _ => Self::Unknown,
683        }
684    }
685}
686
687impl From<RawEvent> for Event {
688    fn from(val: RawEvent) -> Self {
689        match val.type_() {
690            EV_KEY => match val.code() {
691                0..=255 => Event::Key(KeyboardInput {
692                    scancode: val.code() as u32,
693                    state: val.value().into(),
694                    virtual_keycode: val.code().try_into().ok(),
695                }),
696                0x100..=0x109 => Event::Button {
697                    button: val.code().into(),
698                    state: val.value().into(),
699                },
700                0x110 => Event::MouseButton {
701                    button: MouseButton::Left,
702                    state: val.value().into(),
703                },
704                0x111 => Event::MouseButton {
705                    button: MouseButton::Right,
706                    state: val.value().into(),
707                },
708                0x112 => Event::MouseButton {
709                    button: MouseButton::Middle,
710                    state: val.value().into(),
711                },
712                _ => Event::Key(KeyboardInput::default()),
713            },
714            EV_REL => match val.code() {
715                REL_X => Event::MouseMotion {
716                    delta: (val.value() as i32 as f64, 0.0),
717                },
718                REL_Y => Event::MouseMotion {
719                    delta: (0.0, val.value() as i32 as f64),
720                },
721                REL_WHEEL | REL_WHEEL_HI_RES => Event::MouseWheel {
722                    delta: MouseScrollDelta::LineDelta(0.0, val.value() as i32 as f32),
723                },
724                REL_HWHEEL | REL_HWHEEL_HI_RES => Event::MouseWheel {
725                    delta: MouseScrollDelta::LineDelta(val.value() as i32 as f32, 0.0),
726                },
727                _ => Event::Dummy,
728            },
729            _ => Event::Dummy,
730        }
731    }
732}
733
734impl TryFrom<u16> for VirtualKeyCode {
735    type Error = &'static str;
736
737    fn try_from(val: u16) -> Result<Self, Self::Error> {
738        match val {
739            KEY_ESC => Ok(VirtualKeyCode::Escape),
740            KEY_1 => Ok(VirtualKeyCode::Key1),
741            KEY_2 => Ok(VirtualKeyCode::Key2),
742            KEY_3 => Ok(VirtualKeyCode::Key3),
743            KEY_4 => Ok(VirtualKeyCode::Key4),
744            KEY_5 => Ok(VirtualKeyCode::Key5),
745            KEY_6 => Ok(VirtualKeyCode::Key6),
746            KEY_7 => Ok(VirtualKeyCode::Key7),
747            KEY_8 => Ok(VirtualKeyCode::Key8),
748            KEY_9 => Ok(VirtualKeyCode::Key9),
749            KEY_0 => Ok(VirtualKeyCode::Key0),
750            KEY_MINUS => Ok(VirtualKeyCode::Minus),
751            KEY_EQUAL => Ok(VirtualKeyCode::Equals),
752            KEY_BACKSPACE => Ok(VirtualKeyCode::Back),
753            KEY_TAB => Ok(VirtualKeyCode::Tab),
754            KEY_Q => Ok(VirtualKeyCode::Q),
755            KEY_W => Ok(VirtualKeyCode::W),
756            KEY_E => Ok(VirtualKeyCode::E),
757            KEY_R => Ok(VirtualKeyCode::R),
758            KEY_T => Ok(VirtualKeyCode::T),
759            KEY_Y => Ok(VirtualKeyCode::Y),
760            KEY_U => Ok(VirtualKeyCode::U),
761            KEY_I => Ok(VirtualKeyCode::I),
762            KEY_O => Ok(VirtualKeyCode::O),
763            KEY_P => Ok(VirtualKeyCode::P),
764            KEY_LEFTBRACE => Ok(VirtualKeyCode::LBracket),
765            KEY_RIGHTBRACE => Ok(VirtualKeyCode::RBracket),
766            KEY_ENTER => Ok(VirtualKeyCode::Return),
767            KEY_LEFTCTRL => Ok(VirtualKeyCode::LControl),
768            KEY_A => Ok(VirtualKeyCode::A),
769            KEY_S => Ok(VirtualKeyCode::S),
770            KEY_D => Ok(VirtualKeyCode::D),
771            KEY_F => Ok(VirtualKeyCode::F),
772            KEY_G => Ok(VirtualKeyCode::G),
773            KEY_H => Ok(VirtualKeyCode::H),
774            KEY_J => Ok(VirtualKeyCode::J),
775            KEY_K => Ok(VirtualKeyCode::K),
776            KEY_L => Ok(VirtualKeyCode::L),
777            KEY_SEMICOLON => Ok(VirtualKeyCode::Semicolon),
778            KEY_APOSTROPHE => Ok(VirtualKeyCode::Apostrophe),
779            KEY_GRAVE => Ok(VirtualKeyCode::Grave),
780            KEY_LEFTSHIFT => Ok(VirtualKeyCode::LShift),
781            KEY_BACKSLASH => Ok(VirtualKeyCode::Backslash),
782            KEY_Z => Ok(VirtualKeyCode::Z),
783            KEY_X => Ok(VirtualKeyCode::X),
784            KEY_C => Ok(VirtualKeyCode::C),
785            KEY_V => Ok(VirtualKeyCode::V),
786            KEY_B => Ok(VirtualKeyCode::B),
787            KEY_N => Ok(VirtualKeyCode::N),
788            KEY_M => Ok(VirtualKeyCode::M),
789            KEY_COMMA => Ok(VirtualKeyCode::Comma),
790            KEY_DOT => Ok(VirtualKeyCode::Period),
791            KEY_SLASH => Ok(VirtualKeyCode::Slash),
792            KEY_RIGHTSHIFT => Ok(VirtualKeyCode::RShift),
793            // KEY_KPASTERISK => todo!(),
794            KEY_LEFTALT => Ok(VirtualKeyCode::LAlt),
795            KEY_SPACE => Ok(VirtualKeyCode::Space),
796            KEY_CAPSLOCK => Ok(VirtualKeyCode::Capital),
797            KEY_F1 => Ok(VirtualKeyCode::F1),
798            KEY_F2 => Ok(VirtualKeyCode::F2),
799            KEY_F3 => Ok(VirtualKeyCode::F3),
800            KEY_F4 => Ok(VirtualKeyCode::F4),
801            KEY_F5 => Ok(VirtualKeyCode::F5),
802            KEY_F6 => Ok(VirtualKeyCode::F6),
803            KEY_F7 => Ok(VirtualKeyCode::F7),
804            KEY_F8 => Ok(VirtualKeyCode::F8),
805            KEY_F9 => Ok(VirtualKeyCode::F9),
806            KEY_F10 => Ok(VirtualKeyCode::F10),
807            KEY_NUMLOCK => Ok(VirtualKeyCode::Numlock),
808            KEY_SCROLLLOCK => Ok(VirtualKeyCode::Scroll),
809            KEY_KP7 => Ok(VirtualKeyCode::Numpad7),
810            KEY_KP8 => Ok(VirtualKeyCode::Numpad8),
811            KEY_KP9 => Ok(VirtualKeyCode::Numpad9),
812            KEY_KPMINUS => Ok(VirtualKeyCode::Minus),
813            KEY_KP4 => Ok(VirtualKeyCode::Numpad4),
814            KEY_KP5 => Ok(VirtualKeyCode::Numpad5),
815            KEY_KP6 => Ok(VirtualKeyCode::Numpad6),
816            KEY_KPPLUS => Ok(VirtualKeyCode::Plus),
817            KEY_KP1 => Ok(VirtualKeyCode::Numpad1),
818            KEY_KP2 => Ok(VirtualKeyCode::Numpad2),
819            KEY_KP3 => Ok(VirtualKeyCode::Numpad3),
820            KEY_KP0 => Ok(VirtualKeyCode::Numpad0),
821            // KEY_KPDOT => todo!(),
822            // KEY_ZENKAKUHANKAKU => todo!(),
823            // KEY_102ND => todo!(),
824            KEY_F11 => Ok(VirtualKeyCode::F11),
825            KEY_F12 => Ok(VirtualKeyCode::F12),
826            // KEY_RO => todo!(),
827            // KEY_KATAKANA => todo!(),
828            // KEY_HIRAGANA => todo!(),
829            // KEY_HENKAN => todo!(),
830            // KEY_KATAKANAHIRAGANA => todo!(),
831            // KEY_MUHENKAN => todo!(),
832            // KEY_KPJPCOMMA => todo!(),
833            // KEY_KPENTER => todo!(),
834            KEY_RIGHTCTRL => Ok(VirtualKeyCode::RControl),
835            // KEY_KPSLASH => todo!(),
836            KEY_SYSRQ => Ok(VirtualKeyCode::Sysrq),
837            KEY_RIGHTALT => Ok(VirtualKeyCode::RAlt),
838            // KEY_LINEFEED => todo!(),
839            KEY_HOME => Ok(VirtualKeyCode::Home),
840            KEY_UP => Ok(VirtualKeyCode::Up),
841            KEY_PAGEUP => Ok(VirtualKeyCode::PageUp),
842            KEY_LEFT => Ok(VirtualKeyCode::Left),
843            KEY_RIGHT => Ok(VirtualKeyCode::Right),
844            KEY_END => Ok(VirtualKeyCode::End),
845            KEY_DOWN => Ok(VirtualKeyCode::Down),
846            KEY_PAGEDOWN => Ok(VirtualKeyCode::PageDown),
847            KEY_INSERT => Ok(VirtualKeyCode::Insert),
848            KEY_DELETE => Ok(VirtualKeyCode::Delete),
849            // KEY_MACRO => todo!(),
850            // KEY_MUTE => todo!(),
851            // KEY_VOLUMEDOWN => todo!(),
852            // KEY_VOLUMEUP => todo!(),
853            KEY_POWER => Ok(VirtualKeyCode::Power),
854            // KEY_KPEQUAL => todo!(),
855            // KEY_KPPLUSMINUS => todo!(),
856            KEY_PAUSE => Ok(VirtualKeyCode::Pause),
857            // KEY_SCALE => todo!(),
858            _ => Err("Unsupported!"),
859        }
860    }
861}
862
863/// Identifier of an input device.
864#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
865pub struct DeviceId(usize);
866
867impl Display for DeviceId {
868    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
869        write!(f, "{}", self.0)
870    }
871}
872
873impl FromStr for DeviceId {
874    type Err = &'static str;
875
876    fn from_str(val: &str) -> Result<Self, Self::Err> {
877        let seg = val.strip_prefix("event").ok_or("Not an event device!")?;
878        let nth = seg
879            .parse::<usize>()
880            .map_err(|_| "Not a numbered event device!")?;
881        Ok(DeviceId(nth))
882    }
883}
884
885/// Raw event data.
886#[derive(Clone, Copy)]
887#[repr(transparent)]
888pub struct RawEvent {
889    inner: input_event,
890}
891
892impl Default for RawEvent {
893    fn default() -> Self {
894        unsafe { std::mem::zeroed() }
895    }
896}
897
898impl Debug for RawEvent {
899    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
900        f.debug_struct("RawEvent")
901            .field("time", &TimeVal::from(self.inner.time))
902            .field("type", &self.inner.type_)
903            .field("code", &self.inner.code)
904            .field("value", &self.inner.value)
905            .finish()
906    }
907}
908impl Display for RawEvent {
909    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
910        write!(
911            f,
912            "RawEvent {{ time: {}, type: {}, code: {}, value: {} }}",
913            TimeVal::from(self.inner.time),
914            self.inner.type_,
915            self.inner.code,
916            self.inner.value
917        )
918    }
919}
920
921impl RawEvent {
922    /// Returns the timestamp of the event.
923    pub fn time(&self) -> TimeVal {
924        TimeVal::from(self.inner.time)
925    }
926
927    /// Returns the type of the event.
928    pub fn type_(&self) -> u16 {
929        self.inner.type_
930    }
931
932    /// Returns the code of the event.
933    pub fn code(&self) -> u16 {
934        self.inner.code
935    }
936
937    /// Returns the value of the event.
938    pub fn value(&self) -> i32 {
939        self.inner.value
940    }
941
942    /// Return true if the event is a `SYN`.
943    pub fn is_sync(&self) -> bool {
944        self.type_() == 0 && self.code() == 0 && self.value() == 0
945    }
946}
947
948/// Posix time value
949#[derive(Clone, Copy)]
950#[repr(transparent)]
951pub struct TimeVal {
952    inner: timeval,
953}
954
955impl From<timeval> for TimeVal {
956    fn from(val: timeval) -> Self {
957        Self { inner: val }
958    }
959}
960
961impl From<TimeVal> for timeval {
962    fn from(val: TimeVal) -> timeval {
963        val.inner
964    }
965}
966
967impl From<TimeVal> for (u32, u32) {
968    fn from(val: TimeVal) -> Self {
969        (val.inner.tv_sec as u32, val.inner.tv_usec as u32)
970    }
971}
972
973impl From<TimeVal> for u64 {
974    fn from(val: TimeVal) -> Self {
975        val.inner.tv_sec as u64 * 1_000_000u64 + val.inner.tv_usec as u64
976    }
977}
978
979impl std::fmt::Debug for TimeVal {
980    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
981        f.debug_struct("TimeVal")
982            .field("sec", &self.inner.tv_sec)
983            .field("usec", &self.inner.tv_usec)
984            .finish()
985    }
986}
987
988impl std::fmt::Display for TimeVal {
989    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
990        write!(
991            f,
992            "{}.{number:>0width$}",
993            self.inner.tv_sec,
994            number = self.inner.tv_usec,
995            width = 6
996        )
997    }
998}
999
1000/// Metadata of an input device.
1001pub struct DeviceMeta {}
1002
1003/// The input device.
1004pub struct Device {
1005    file: File,
1006    id: DeviceId,
1007}
1008
1009impl AsRawFd for Device {
1010    fn as_raw_fd(&self) -> RawFd {
1011        self.file.as_raw_fd()
1012    }
1013}
1014
1015impl Debug for Device {
1016    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1017        write!(f, "Device {{ id = {} }}", self.id())
1018    }
1019}
1020
1021impl Device {
1022    /// Open device on specified `path`.
1023    pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, std::io::Error> {
1024        let file = File::open(&path)?;
1025        let mut id = DeviceId::default();
1026        if let Some(name) = path.as_ref().file_name() {
1027            id = DeviceId::from_str(name.to_str().unwrap_or("")).unwrap_or_default();
1028        }
1029        Ok(Self { file, id })
1030    }
1031
1032    /// Enable or disable non-blocking access.
1033    pub fn set_non_blocking(&mut self, non_block: bool) {
1034        unsafe {
1035            let fd = self.file.as_raw_fd();
1036            let mut flags = libc::fcntl(fd, libc::F_GETFL, 0);
1037            if non_block {
1038                flags |= libc::O_NONBLOCK;
1039            } else {
1040                flags &= !libc::O_NONBLOCK;
1041            }
1042            libc::fcntl(fd, libc::F_SETFL, flags);
1043        }
1044    }
1045
1046    /// Returns the repeat settings (delay, period) of the device.
1047    pub fn repeat_settings(&self) -> Result<(u32, u32), std::io::Error> {
1048        unsafe {
1049            let fd = self.file.as_raw_fd();
1050            let mut rep: [u32; 2] = [0, 0];
1051            let err = libc::ioctl(fd, EVIOCGREP.try_into().unwrap(), &mut rep);
1052            match err {
1053                0 => Ok((rep[0], rep[1])),
1054                _ => Err(std::io::Error::last_os_error()),
1055            }
1056        }
1057    }
1058
1059    /// Change the repeat settings of the device.
1060    pub fn set_repeat_settings(&mut self, delay: u32, peroid: u32) -> Result<(), std::io::Error> {
1061        unsafe {
1062            let fd = self.file.as_raw_fd();
1063            let rep: [u32; 2] = [delay, peroid];
1064            let err = libc::ioctl(fd, EVIOCGREP.try_into().unwrap(), &rep);
1065            match err {
1066                0 => Ok(()),
1067                _ => Err(std::io::Error::last_os_error()),
1068            }
1069        }
1070    }
1071
1072    /// Returns an Events iterator.
1073    pub fn events(&mut self) -> Events<'_> {
1074        Events::new(self)
1075    }
1076
1077    /// Returns the DeviceId.
1078    pub fn id(&self) -> DeviceId {
1079        self.id
1080    }
1081
1082    /// Returns the metadata of the device.
1083    pub fn meta(&mut self) -> DeviceMeta {
1084        DeviceMeta {}
1085    }
1086
1087    /// Returns a RawEvents iterator.
1088    pub fn raw_events(&mut self) -> RawEvents<'_> {
1089        RawEvents::new(self)
1090    }
1091
1092    /// Returns a RawEvents iterator with SYN event filtered.
1093    pub fn raw_events_no_sync(&mut self) -> RawEventsNoSync {
1094        RawEventsNoSync::new(self)
1095    }
1096
1097    /// Read one RawEvent from the device.
1098    pub fn read_one(&mut self) -> Result<RawEvent, std::io::Error> {
1099        const N: usize = std::mem::size_of::<RawEvent>();
1100        let mut ev: RawEvent = Default::default();
1101        let buf = unsafe { &mut *(&mut ev as *mut RawEvent as *mut [u8; N]) };
1102        self.file.read_exact(buf)?;
1103        Ok(ev)
1104    }
1105}
1106
1107/// Translated event iterator.
1108pub struct Events<'a> {
1109    raw_events: RawEventsNoSync<'a>,
1110}
1111
1112impl<'a> Iterator for Events<'a> {
1113    type Item = Event;
1114
1115    fn next(&mut self) -> Option<Self::Item> {
1116        self.raw_events.next().map(|x| x.into())
1117    }
1118}
1119
1120impl<'a> Events<'a> {
1121    /// Create a translated event iterator on `dev`.
1122    pub fn new(dev: &'a mut Device) -> Self {
1123        Self {
1124            raw_events: dev.raw_events_no_sync(),
1125        }
1126    }
1127}
1128
1129/// Raw event iterator.
1130pub struct RawEvents<'a> {
1131    dev: &'a mut Device,
1132}
1133
1134impl<'a> Iterator for RawEvents<'a> {
1135    type Item = RawEvent;
1136
1137    fn next(&mut self) -> Option<Self::Item> {
1138        match self.dev.read_one() {
1139            Ok(ev) => Some(ev),
1140            Err(err) => match err.kind() {
1141                ErrorKind::WouldBlock => None,
1142                _ => unreachable!(),
1143            },
1144        }
1145    }
1146}
1147
1148impl<'a> RawEvents<'a> {
1149    /// Create a raw event iterator on `dev`.
1150    pub fn new(dev: &'a mut Device) -> Self {
1151        Self { dev }
1152    }
1153}
1154
1155/// Raw event iterator with `SYN` filtered.
1156pub struct RawEventsNoSync<'a> {
1157    raw_events: RawEvents<'a>,
1158}
1159
1160impl<'a> Iterator for RawEventsNoSync<'a> {
1161    type Item = RawEvent;
1162
1163    fn next(&mut self) -> Option<Self::Item> {
1164        for ev in &mut self.raw_events {
1165            if ev.type_() != EV_SYN {
1166                return Some(ev);
1167            }
1168        }
1169        None
1170    }
1171}
1172
1173impl<'a> RawEventsNoSync<'a> {
1174    /// Create a raw event iterator with `SYN` filtered on `dev`.
1175    pub fn new(dev: &'a mut Device) -> Self {
1176        Self {
1177            raw_events: dev.raw_events(),
1178        }
1179    }
1180}
1181
1182/// Enumerate all devices.
1183/// # Examples
1184/// ```
1185/// use input_device::enumerate;
1186/// let devs = enumerate();
1187/// for dev in &devs {
1188///     println!("{}", dev.id());
1189/// }
1190/// assert!(devs.len() > 0);
1191/// ```
1192pub fn enumerate() -> Vec<Device> {
1193    let mut devices = Vec::new();
1194    if let Ok(dir) = fs::read_dir("/dev/input") {
1195        for entry in dir.flatten() {
1196            let path = entry.path();
1197            if !path.is_dir() {
1198                if let Some(name) = path.file_name() {
1199                    if !name.to_str().unwrap_or("").starts_with("event") {
1200                        continue;
1201                    }
1202                }
1203                if let Ok(dev) = Device::open(path) {
1204                    devices.push(dev);
1205                }
1206            }
1207        }
1208    }
1209    devices
1210}
1211
1212/// Enumerate all devices with multi-threading supports.
1213/// # Examples
1214/// ```
1215/// use input_device::enumerate_shareable;
1216/// let devs = enumerate_shareable();
1217/// for dev in &devs {
1218///     println!("{}", dev.lock().unwrap().id());
1219/// }
1220/// assert!(devs.len() > 0);
1221/// ```
1222pub fn enumerate_shareable() -> Vec<Arc<Mutex<Device>>> {
1223    enumerate()
1224        .into_iter()
1225        .map(|x| Arc::new(Mutex::new(x)))
1226        .collect()
1227}
1228
1229#[cfg(test)]
1230mod tests {
1231    use super::*;
1232
1233    #[test]
1234    fn test_device() {
1235        let mut dev = Device::open("/dev/input/event2").unwrap();
1236        dev.set_non_blocking(true);
1237        match dev.read_one() {
1238            Ok(_ev) => {}
1239            Err(err) => match err.kind() {
1240                ErrorKind::WouldBlock => {}
1241                _ => {}
1242            },
1243        }
1244    }
1245}