xref: /aosp_15_r20/external/crosvm/devices/src/virtio/input/defaults.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2019 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::collections::BTreeMap;
6 
7 use base::warn;
8 use linux_input_sys::constants::*;
9 
10 use super::virtio_input_absinfo;
11 use super::virtio_input_bitmap;
12 use super::virtio_input_device_ids;
13 use super::VirtioInputConfig;
14 
15 /// Instantiates a VirtioInputConfig object with the default configuration for a trackpad. It
16 /// supports touch, left button and right button events, as well as X and Y axis.
new_trackpad_config( idx: u32, width: u32, height: u32, name: Option<&str>, ) -> VirtioInputConfig17 pub fn new_trackpad_config(
18     idx: u32,
19     width: u32,
20     height: u32,
21     name: Option<&str>,
22 ) -> VirtioInputConfig {
23     let name = name
24         .map(str::to_owned)
25         .unwrap_or(format!("Crosvm Virtio Trackpad {idx}"));
26     VirtioInputConfig::new(
27         virtio_input_device_ids::new(0, 0, 0, 0),
28         name,
29         format!("virtio-trackpad-{idx}"),
30         virtio_input_bitmap::new([0u8; 128]),
31         default_trackpad_events(),
32         default_trackpad_absinfo(width, height),
33     )
34 }
35 
new_multitouch_trackpad_config( idx: u32, width: u32, height: u32, name: Option<&str>, ) -> VirtioInputConfig36 pub fn new_multitouch_trackpad_config(
37     idx: u32,
38     width: u32,
39     height: u32,
40     name: Option<&str>,
41 ) -> VirtioInputConfig {
42     let name = name
43         .map(str::to_owned)
44         .unwrap_or(format!("Crosvm Virtio Multi-touch Trackpad {idx}"));
45     VirtioInputConfig::new(
46         virtio_input_device_ids::new(0, 0, 0, 0),
47         name,
48         format!("virtio-multi-touch-trackpad-{idx}"),
49         virtio_input_bitmap::from_bits(&[INPUT_PROP_POINTER, INPUT_PROP_BUTTONPAD]),
50         default_multitouchpad_events(),
51         default_multitouchpad_absinfo(width, height, 10, 65536),
52     )
53 }
54 
55 /// Instantiates a VirtioInputConfig object with the default configuration for a mouse.
56 /// It supports left, right and middle buttons, as wel as X, Y and wheel relative axes.
new_mouse_config(idx: u32) -> VirtioInputConfig57 pub fn new_mouse_config(idx: u32) -> VirtioInputConfig {
58     VirtioInputConfig::new(
59         virtio_input_device_ids::new(0, 0, 0, 0),
60         format!("Crosvm Virtio Mouse {idx}"),
61         format!("virtio-mouse-{idx}"),
62         virtio_input_bitmap::new([0u8; 128]),
63         default_mouse_events(),
64         BTreeMap::new(),
65     )
66 }
67 
68 /// Instantiates a VirtioInputConfig object with the default configuration for a keyboard.
69 /// It supports the same keys as a en-us keyboard and the CAPSLOCK, NUMLOCK and SCROLLLOCK leds.
new_keyboard_config(idx: u32) -> VirtioInputConfig70 pub fn new_keyboard_config(idx: u32) -> VirtioInputConfig {
71     VirtioInputConfig::new(
72         virtio_input_device_ids::new(0, 0, 0, 0),
73         format!("Crosvm Virtio Keyboard {idx}"),
74         format!("virtio-keyboard-{idx}"),
75         virtio_input_bitmap::new([0u8; 128]),
76         default_keyboard_events(),
77         BTreeMap::new(),
78     )
79 }
80 
81 /// Instantiates a VirtioInputConfig object with the default configuration for a collection of
82 /// switches.
new_switches_config(idx: u32) -> VirtioInputConfig83 pub fn new_switches_config(idx: u32) -> VirtioInputConfig {
84     VirtioInputConfig::new(
85         virtio_input_device_ids::new(0, 0, 0, 0),
86         format!("Crosvm Virtio Switches {idx}"),
87         format!("virtio-switches-{idx}"),
88         virtio_input_bitmap::new([0u8; 128]),
89         default_switch_events(),
90         BTreeMap::new(),
91     )
92 }
93 
94 /// Instantiates a VirtioInputConfig object with the default configuration for a collection of
95 /// rotary.
new_rotary_config(idx: u32) -> VirtioInputConfig96 pub fn new_rotary_config(idx: u32) -> VirtioInputConfig {
97     VirtioInputConfig::new(
98         virtio_input_device_ids::new(0, 0, 0, 0),
99         format!("Crosvm Virtio Rotary {idx}"),
100         format!("virtio-rotary-{idx}"),
101         virtio_input_bitmap::new([0u8; 128]),
102         default_rotary_events(),
103         BTreeMap::new(),
104     )
105 }
106 
107 /// Instantiates a VirtioInputConfig object with the default configuration for a touchscreen (no
108 /// multitouch support).
new_single_touch_config( idx: u32, width: u32, height: u32, name: Option<&str>, ) -> VirtioInputConfig109 pub fn new_single_touch_config(
110     idx: u32,
111     width: u32,
112     height: u32,
113     name: Option<&str>,
114 ) -> VirtioInputConfig {
115     let name = name
116         .map(str::to_owned)
117         .unwrap_or(format!("Crosvm Virtio Touchscreen {idx}"));
118     VirtioInputConfig::new(
119         virtio_input_device_ids::new(0, 0, 0, 0),
120         name,
121         format!("virtio-touchscreen-{idx}"),
122         virtio_input_bitmap::from_bits(&[INPUT_PROP_DIRECT]),
123         default_touchscreen_events(),
124         default_touchscreen_absinfo(width, height),
125     )
126 }
127 
128 /// Instantiates a VirtioInputConfig object with the default configuration for a multitouch
129 /// touchscreen.
new_multi_touch_config( idx: u32, width: u32, height: u32, name: Option<&str>, ) -> VirtioInputConfig130 pub fn new_multi_touch_config(
131     idx: u32,
132     width: u32,
133     height: u32,
134     name: Option<&str>,
135 ) -> VirtioInputConfig {
136     let name = name
137         .map(str::to_owned)
138         .unwrap_or(format!("Crosvm Virtio Multitouch Touchscreen {idx}"));
139     VirtioInputConfig::new(
140         virtio_input_device_ids::new(0, 0, 0, 0),
141         name,
142         format!("virtio-touchscreen-{idx}"),
143         virtio_input_bitmap::from_bits(&[INPUT_PROP_DIRECT]),
144         default_multitouchscreen_events(),
145         default_multitouchscreen_absinfo(width, height, 10, 10),
146     )
147 }
148 
149 /// Initializes a VirtioInputConfig object for a custom virtio-input device.
150 ///
151 /// # Arguments
152 ///
153 /// * `idx` - input device index
154 /// * `name` - input device name
155 /// * `serial_name` - input device serial name
156 /// * `supported_events` - Event configuration provided by a configuration file
new_custom_config( idx: u32, name: &str, serial_name: &str, supported_events: BTreeMap<u16, virtio_input_bitmap>, ) -> VirtioInputConfig157 pub fn new_custom_config(
158     idx: u32,
159     name: &str,
160     serial_name: &str,
161     supported_events: BTreeMap<u16, virtio_input_bitmap>,
162 ) -> VirtioInputConfig {
163     let name: String = format!("{name} {idx}");
164     let serial_name = format!("{serial_name}-{idx}");
165     if name.as_bytes().len() > 128 {
166         warn!("name: {name} exceeds 128 bytes, will be truncated.");
167     }
168     if serial_name.as_bytes().len() > 128 {
169         warn!("serial_name: {serial_name} exceeds 128 bytes, will be truncated.");
170     }
171 
172     VirtioInputConfig::new(
173         virtio_input_device_ids::new(0, 0, 0, 0),
174         name,
175         serial_name,
176         virtio_input_bitmap::new([0u8; 128]),
177         supported_events,
178         BTreeMap::new(),
179     )
180 }
181 
default_touchscreen_absinfo(width: u32, height: u32) -> BTreeMap<u16, virtio_input_absinfo>182 fn default_touchscreen_absinfo(width: u32, height: u32) -> BTreeMap<u16, virtio_input_absinfo> {
183     let mut absinfo: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new();
184     absinfo.insert(ABS_X, virtio_input_absinfo::new(0, width, 0, 0));
185     absinfo.insert(ABS_Y, virtio_input_absinfo::new(0, height, 0, 0));
186     absinfo
187 }
188 
default_touchscreen_events() -> BTreeMap<u16, virtio_input_bitmap>189 fn default_touchscreen_events() -> BTreeMap<u16, virtio_input_bitmap> {
190     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
191     supported_events.insert(EV_KEY, virtio_input_bitmap::from_bits(&[BTN_TOUCH]));
192     supported_events.insert(EV_ABS, virtio_input_bitmap::from_bits(&[ABS_X, ABS_Y]));
193     supported_events
194 }
195 
default_multitouchscreen_absinfo( width: u32, height: u32, slot: u32, id: u32, ) -> BTreeMap<u16, virtio_input_absinfo>196 fn default_multitouchscreen_absinfo(
197     width: u32,
198     height: u32,
199     slot: u32,
200     id: u32,
201 ) -> BTreeMap<u16, virtio_input_absinfo> {
202     let mut absinfo: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new();
203     absinfo.insert(ABS_MT_SLOT, virtio_input_absinfo::new(0, slot, 0, 0));
204     absinfo.insert(ABS_MT_TRACKING_ID, virtio_input_absinfo::new(0, id, 0, 0));
205     absinfo.insert(ABS_X, virtio_input_absinfo::new(0, width, 0, 0));
206     absinfo.insert(ABS_Y, virtio_input_absinfo::new(0, height, 0, 0));
207     absinfo.insert(ABS_MT_POSITION_X, virtio_input_absinfo::new(0, width, 0, 0));
208     absinfo.insert(
209         ABS_MT_POSITION_Y,
210         virtio_input_absinfo::new(0, height, 0, 0),
211     );
212     absinfo
213 }
214 
default_multitouchscreen_events() -> BTreeMap<u16, virtio_input_bitmap>215 fn default_multitouchscreen_events() -> BTreeMap<u16, virtio_input_bitmap> {
216     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
217     supported_events.insert(EV_KEY, virtio_input_bitmap::from_bits(&[BTN_TOUCH]));
218     supported_events.insert(
219         EV_ABS,
220         virtio_input_bitmap::from_bits(&[
221             ABS_MT_SLOT,
222             ABS_MT_TRACKING_ID,
223             ABS_MT_POSITION_X,
224             ABS_MT_POSITION_Y,
225             ABS_X,
226             ABS_Y,
227         ]),
228     );
229     supported_events
230 }
231 
default_multitouchpad_absinfo( width: u32, height: u32, slot: u32, id: u32, ) -> BTreeMap<u16, virtio_input_absinfo>232 fn default_multitouchpad_absinfo(
233     width: u32,
234     height: u32,
235     slot: u32,
236     id: u32,
237 ) -> BTreeMap<u16, virtio_input_absinfo> {
238     let mut absinfo: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new();
239     absinfo.insert(ABS_MT_SLOT, virtio_input_absinfo::new(0, slot, 0, 0));
240     absinfo.insert(ABS_MT_TRACKING_ID, virtio_input_absinfo::new(0, id, 0, 0));
241     // TODO(b/347253952): make them configurable if necessary
242     absinfo.insert(ABS_MT_PRESSURE, virtio_input_absinfo::new(0, 255, 0, 0));
243     absinfo.insert(ABS_PRESSURE, virtio_input_absinfo::new(0, 255, 0, 0));
244     absinfo.insert(ABS_MT_TOUCH_MAJOR, virtio_input_absinfo::new(0, 4095, 0, 0));
245     absinfo.insert(ABS_MT_TOUCH_MINOR, virtio_input_absinfo::new(0, 4095, 0, 0));
246     absinfo.insert(ABS_X, virtio_input_absinfo::new(0, width, 0, 0));
247     absinfo.insert(ABS_Y, virtio_input_absinfo::new(0, height, 0, 0));
248     absinfo.insert(ABS_MT_POSITION_X, virtio_input_absinfo::new(0, width, 0, 0));
249     absinfo.insert(ABS_MT_TOOL_TYPE, virtio_input_absinfo::new(0, 2, 0, 0));
250     absinfo.insert(
251         ABS_MT_POSITION_Y,
252         virtio_input_absinfo::new(0, height, 0, 0),
253     );
254     absinfo
255 }
256 
default_multitouchpad_events() -> BTreeMap<u16, virtio_input_bitmap>257 fn default_multitouchpad_events() -> BTreeMap<u16, virtio_input_bitmap> {
258     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
259     supported_events.insert(
260         EV_KEY,
261         virtio_input_bitmap::from_bits(&[
262             BTN_TOUCH,
263             BTN_TOOL_FINGER,
264             BTN_TOOL_DOUBLETAP,
265             BTN_TOOL_TRIPLETAP,
266             BTN_TOOL_QUADTAP,
267             BTN_LEFT,
268         ]),
269     );
270     supported_events.insert(
271         EV_ABS,
272         virtio_input_bitmap::from_bits(&[
273             ABS_MT_SLOT,
274             ABS_MT_TRACKING_ID,
275             ABS_MT_POSITION_X,
276             ABS_MT_POSITION_Y,
277             ABS_MT_TOOL_TYPE,
278             ABS_MT_PRESSURE,
279             ABS_X,
280             ABS_Y,
281             ABS_PRESSURE,
282             ABS_MT_TOUCH_MAJOR,
283             ABS_MT_TOUCH_MINOR,
284             ABS_PRESSURE,
285         ]),
286     );
287     supported_events
288 }
289 
default_trackpad_absinfo(width: u32, height: u32) -> BTreeMap<u16, virtio_input_absinfo>290 fn default_trackpad_absinfo(width: u32, height: u32) -> BTreeMap<u16, virtio_input_absinfo> {
291     let mut absinfo: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new();
292     absinfo.insert(ABS_X, virtio_input_absinfo::new(0, width, 0, 0));
293     absinfo.insert(ABS_Y, virtio_input_absinfo::new(0, height, 0, 0));
294     absinfo
295 }
296 
default_trackpad_events() -> BTreeMap<u16, virtio_input_bitmap>297 fn default_trackpad_events() -> BTreeMap<u16, virtio_input_bitmap> {
298     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
299     supported_events.insert(
300         EV_KEY,
301         virtio_input_bitmap::from_bits(&[BTN_TOOL_FINGER, BTN_TOUCH, BTN_LEFT, BTN_RIGHT]),
302     );
303     supported_events.insert(EV_ABS, virtio_input_bitmap::from_bits(&[ABS_X, ABS_Y]));
304     supported_events
305 }
306 
default_mouse_events() -> BTreeMap<u16, virtio_input_bitmap>307 fn default_mouse_events() -> BTreeMap<u16, virtio_input_bitmap> {
308     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
309     supported_events.insert(
310         EV_KEY,
311         virtio_input_bitmap::from_bits(&[BTN_LEFT, BTN_RIGHT, BTN_MIDDLE]),
312     );
313     supported_events.insert(
314         EV_REL,
315         virtio_input_bitmap::from_bits(&[REL_X, REL_Y, REL_WHEEL]),
316     );
317     supported_events
318 }
319 
default_keyboard_events() -> BTreeMap<u16, virtio_input_bitmap>320 fn default_keyboard_events() -> BTreeMap<u16, virtio_input_bitmap> {
321     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
322     supported_events.insert(
323         EV_KEY,
324         virtio_input_bitmap::from_bits(&[
325             KEY_ESC,
326             KEY_1,
327             KEY_2,
328             KEY_3,
329             KEY_4,
330             KEY_5,
331             KEY_6,
332             KEY_7,
333             KEY_8,
334             KEY_9,
335             KEY_0,
336             KEY_MINUS,
337             KEY_EQUAL,
338             KEY_BACKSPACE,
339             KEY_TAB,
340             KEY_Q,
341             KEY_W,
342             KEY_E,
343             KEY_R,
344             KEY_T,
345             KEY_Y,
346             KEY_U,
347             KEY_I,
348             KEY_O,
349             KEY_P,
350             KEY_LEFTBRACE,
351             KEY_RIGHTBRACE,
352             KEY_ENTER,
353             KEY_LEFTCTRL,
354             KEY_A,
355             KEY_S,
356             KEY_D,
357             KEY_F,
358             KEY_G,
359             KEY_H,
360             KEY_J,
361             KEY_K,
362             KEY_L,
363             KEY_SEMICOLON,
364             KEY_APOSTROPHE,
365             KEY_GRAVE,
366             KEY_LEFTSHIFT,
367             KEY_BACKSLASH,
368             KEY_Z,
369             KEY_X,
370             KEY_C,
371             KEY_V,
372             KEY_B,
373             KEY_N,
374             KEY_M,
375             KEY_COMMA,
376             KEY_DOT,
377             KEY_SLASH,
378             KEY_RIGHTSHIFT,
379             KEY_KPASTERISK,
380             KEY_LEFTALT,
381             KEY_SPACE,
382             KEY_CAPSLOCK,
383             KEY_F1,
384             KEY_F2,
385             KEY_F3,
386             KEY_F4,
387             KEY_F5,
388             KEY_F6,
389             KEY_F7,
390             KEY_F8,
391             KEY_F9,
392             KEY_F10,
393             KEY_NUMLOCK,
394             KEY_SCROLLLOCK,
395             KEY_KP7,
396             KEY_KP8,
397             KEY_KP9,
398             KEY_KPMINUS,
399             KEY_KP4,
400             KEY_KP5,
401             KEY_KP6,
402             KEY_KPPLUS,
403             KEY_KP1,
404             KEY_KP2,
405             KEY_KP3,
406             KEY_KP0,
407             KEY_KPDOT,
408             KEY_F11,
409             KEY_F12,
410             KEY_KPENTER,
411             KEY_RIGHTCTRL,
412             KEY_KPSLASH,
413             KEY_SYSRQ,
414             KEY_RIGHTALT,
415             KEY_HOME,
416             KEY_UP,
417             KEY_PAGEUP,
418             KEY_LEFT,
419             KEY_RIGHT,
420             KEY_END,
421             KEY_DOWN,
422             KEY_PAGEDOWN,
423             KEY_INSERT,
424             KEY_DELETE,
425             KEY_PAUSE,
426             KEY_MENU,
427             KEY_PRINT,
428             KEY_POWER,
429             KEY_HOMEPAGE,
430             KEY_MUTE,
431             KEY_VOLUMEDOWN,
432             KEY_VOLUMEUP,
433             KEY_BACK,
434         ]),
435     );
436     supported_events.insert(
437         EV_REP,
438         virtio_input_bitmap::from_bits(&[REP_DELAY, REP_PERIOD]),
439     );
440     supported_events.insert(
441         EV_LED,
442         virtio_input_bitmap::from_bits(&[LED_CAPSL, LED_NUML, LED_SCROLLL]),
443     );
444     supported_events
445 }
446 
default_switch_events() -> BTreeMap<u16, virtio_input_bitmap>447 fn default_switch_events() -> BTreeMap<u16, virtio_input_bitmap> {
448     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
449     supported_events.insert(
450         EV_SW,
451         virtio_input_bitmap::from_bits(&[
452             SW_LID,
453             SW_TABLET_MODE,
454             SW_HEADPHONE_INSERT,
455             SW_RFKILL_ALL,
456             SW_MICROPHONE_INSERT,
457             SW_DOCK,
458             SW_LINEOUT_INSERT,
459             SW_JACK_PHYSICAL_INSERT,
460             SW_VIDEOOUT_INSERT,
461             SW_CAMERA_LENS_COVER,
462             SW_KEYPAD_SLIDE,
463             SW_FRONT_PROXIMITY,
464             SW_ROTATE_LOCK,
465             SW_LINEIN_INSERT,
466             SW_MUTE_DEVICE,
467             SW_PEN_INSERTED,
468             SW_MACHINE_COVER,
469         ]),
470     );
471     supported_events
472 }
473 
default_rotary_events() -> BTreeMap<u16, virtio_input_bitmap>474 fn default_rotary_events() -> BTreeMap<u16, virtio_input_bitmap> {
475     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
476     supported_events.insert(EV_REL, virtio_input_bitmap::from_bits(&[REL_WHEEL]));
477     supported_events
478 }
479 
480 #[cfg(test)]
481 mod tests {
482     use super::*;
483 
484     #[test]
test_new_switches_config()485     fn test_new_switches_config() {
486         let config = new_switches_config(0);
487         assert_eq!(config.serial_name, "virtio-switches-0");
488 
489         let events = config.supported_events;
490         assert_eq!(events.len(), 1);
491         assert_eq!(events.contains_key(&EV_SW), true);
492 
493         // The bitmap should contain SW_CNT=0x10+1=17 ones,
494         // where each one is packed into the u8 bitmap.
495         let mut expected_bitmap = [0_u8; 128];
496         expected_bitmap[0] = 0b11111111u8;
497         expected_bitmap[1] = 0b11111111u8;
498         expected_bitmap[2] = 0b1u8;
499         assert_eq!(events[&EV_SW].bitmap, expected_bitmap);
500     }
501 }
502