• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /// * `properties` - input device properties
157 /// * `supported_events` - Event configuration provided by a configuration file
158 /// * `axis_info` - Device axis configuration
new_custom_config( idx: u32, name: &str, serial_name: &str, properties: virtio_input_bitmap, supported_events: BTreeMap<u16, virtio_input_bitmap>, axis_info: BTreeMap<u16, virtio_input_absinfo>, ) -> VirtioInputConfig159 pub fn new_custom_config(
160     idx: u32,
161     name: &str,
162     serial_name: &str,
163     properties: virtio_input_bitmap,
164     supported_events: BTreeMap<u16, virtio_input_bitmap>,
165     axis_info: BTreeMap<u16, virtio_input_absinfo>,
166 ) -> VirtioInputConfig {
167     let name: String = format!("{name} {idx}");
168     let serial_name = format!("{serial_name}-{idx}");
169     if name.len() > 128 {
170         warn!("name: {name} exceeds 128 bytes, will be truncated.");
171     }
172     if serial_name.len() > 128 {
173         warn!("serial_name: {serial_name} exceeds 128 bytes, will be truncated.");
174     }
175 
176     VirtioInputConfig::new(
177         virtio_input_device_ids::new(0, 0, 0, 0),
178         name,
179         serial_name,
180         properties,
181         supported_events,
182         axis_info,
183     )
184 }
185 
default_touchscreen_absinfo(width: u32, height: u32) -> BTreeMap<u16, virtio_input_absinfo>186 fn default_touchscreen_absinfo(width: u32, height: u32) -> BTreeMap<u16, virtio_input_absinfo> {
187     let mut absinfo: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new();
188     absinfo.insert(ABS_X, virtio_input_absinfo::new(0, width, 0, 0));
189     absinfo.insert(ABS_Y, virtio_input_absinfo::new(0, height, 0, 0));
190     absinfo
191 }
192 
default_touchscreen_events() -> BTreeMap<u16, virtio_input_bitmap>193 fn default_touchscreen_events() -> BTreeMap<u16, virtio_input_bitmap> {
194     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
195     supported_events.insert(EV_KEY, virtio_input_bitmap::from_bits(&[BTN_TOUCH]));
196     supported_events.insert(EV_ABS, virtio_input_bitmap::from_bits(&[ABS_X, ABS_Y]));
197     supported_events
198 }
199 
default_multitouchscreen_absinfo( width: u32, height: u32, slot: u32, id: u32, ) -> BTreeMap<u16, virtio_input_absinfo>200 fn default_multitouchscreen_absinfo(
201     width: u32,
202     height: u32,
203     slot: u32,
204     id: u32,
205 ) -> BTreeMap<u16, virtio_input_absinfo> {
206     let mut absinfo: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new();
207     absinfo.insert(ABS_MT_SLOT, virtio_input_absinfo::new(0, slot, 0, 0));
208     absinfo.insert(ABS_MT_TRACKING_ID, virtio_input_absinfo::new(0, id, 0, 0));
209     absinfo.insert(ABS_X, virtio_input_absinfo::new(0, width, 0, 0));
210     absinfo.insert(ABS_Y, virtio_input_absinfo::new(0, height, 0, 0));
211     absinfo.insert(ABS_MT_POSITION_X, virtio_input_absinfo::new(0, width, 0, 0));
212     absinfo.insert(
213         ABS_MT_POSITION_Y,
214         virtio_input_absinfo::new(0, height, 0, 0),
215     );
216     absinfo
217 }
218 
default_multitouchscreen_events() -> BTreeMap<u16, virtio_input_bitmap>219 fn default_multitouchscreen_events() -> BTreeMap<u16, virtio_input_bitmap> {
220     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
221     supported_events.insert(EV_KEY, virtio_input_bitmap::from_bits(&[BTN_TOUCH]));
222     supported_events.insert(
223         EV_ABS,
224         virtio_input_bitmap::from_bits(&[
225             ABS_MT_SLOT,
226             ABS_MT_TRACKING_ID,
227             ABS_MT_POSITION_X,
228             ABS_MT_POSITION_Y,
229             ABS_X,
230             ABS_Y,
231         ]),
232     );
233     supported_events
234 }
235 
default_multitouchpad_absinfo( width: u32, height: u32, slot: u32, id: u32, ) -> BTreeMap<u16, virtio_input_absinfo>236 fn default_multitouchpad_absinfo(
237     width: u32,
238     height: u32,
239     slot: u32,
240     id: u32,
241 ) -> BTreeMap<u16, virtio_input_absinfo> {
242     let mut absinfo: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new();
243     absinfo.insert(ABS_MT_SLOT, virtio_input_absinfo::new(0, slot, 0, 0));
244     absinfo.insert(ABS_MT_TRACKING_ID, virtio_input_absinfo::new(0, id, 0, 0));
245     // TODO(b/347253952): make them configurable if necessary
246     absinfo.insert(ABS_MT_PRESSURE, virtio_input_absinfo::new(0, 255, 0, 0));
247     absinfo.insert(ABS_PRESSURE, virtio_input_absinfo::new(0, 255, 0, 0));
248     absinfo.insert(ABS_MT_TOUCH_MAJOR, virtio_input_absinfo::new(0, 4095, 0, 0));
249     absinfo.insert(ABS_MT_TOUCH_MINOR, virtio_input_absinfo::new(0, 4095, 0, 0));
250     absinfo.insert(ABS_X, virtio_input_absinfo::new(0, width, 0, 0));
251     absinfo.insert(ABS_Y, virtio_input_absinfo::new(0, height, 0, 0));
252     absinfo.insert(ABS_MT_POSITION_X, virtio_input_absinfo::new(0, width, 0, 0));
253     absinfo.insert(ABS_MT_TOOL_TYPE, virtio_input_absinfo::new(0, 2, 0, 0));
254     absinfo.insert(
255         ABS_MT_POSITION_Y,
256         virtio_input_absinfo::new(0, height, 0, 0),
257     );
258     absinfo
259 }
260 
default_multitouchpad_events() -> BTreeMap<u16, virtio_input_bitmap>261 fn default_multitouchpad_events() -> BTreeMap<u16, virtio_input_bitmap> {
262     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
263     supported_events.insert(
264         EV_KEY,
265         virtio_input_bitmap::from_bits(&[
266             BTN_TOUCH,
267             BTN_TOOL_FINGER,
268             BTN_TOOL_DOUBLETAP,
269             BTN_TOOL_TRIPLETAP,
270             BTN_TOOL_QUADTAP,
271             BTN_LEFT,
272         ]),
273     );
274     supported_events.insert(
275         EV_ABS,
276         virtio_input_bitmap::from_bits(&[
277             ABS_MT_SLOT,
278             ABS_MT_TRACKING_ID,
279             ABS_MT_POSITION_X,
280             ABS_MT_POSITION_Y,
281             ABS_MT_TOOL_TYPE,
282             ABS_MT_PRESSURE,
283             ABS_X,
284             ABS_Y,
285             ABS_PRESSURE,
286             ABS_MT_TOUCH_MAJOR,
287             ABS_MT_TOUCH_MINOR,
288             ABS_PRESSURE,
289         ]),
290     );
291     supported_events
292 }
293 
default_trackpad_absinfo(width: u32, height: u32) -> BTreeMap<u16, virtio_input_absinfo>294 fn default_trackpad_absinfo(width: u32, height: u32) -> BTreeMap<u16, virtio_input_absinfo> {
295     let mut absinfo: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new();
296     absinfo.insert(ABS_X, virtio_input_absinfo::new(0, width, 0, 0));
297     absinfo.insert(ABS_Y, virtio_input_absinfo::new(0, height, 0, 0));
298     absinfo
299 }
300 
default_trackpad_events() -> BTreeMap<u16, virtio_input_bitmap>301 fn default_trackpad_events() -> BTreeMap<u16, virtio_input_bitmap> {
302     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
303     supported_events.insert(
304         EV_KEY,
305         virtio_input_bitmap::from_bits(&[BTN_TOOL_FINGER, BTN_TOUCH, BTN_LEFT, BTN_RIGHT]),
306     );
307     supported_events.insert(EV_ABS, virtio_input_bitmap::from_bits(&[ABS_X, ABS_Y]));
308     supported_events
309 }
310 
default_mouse_events() -> BTreeMap<u16, virtio_input_bitmap>311 fn default_mouse_events() -> BTreeMap<u16, virtio_input_bitmap> {
312     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
313     supported_events.insert(
314         EV_KEY,
315         virtio_input_bitmap::from_bits(&[BTN_LEFT, BTN_RIGHT, BTN_MIDDLE]),
316     );
317     supported_events.insert(
318         EV_REL,
319         virtio_input_bitmap::from_bits(&[REL_X, REL_Y, REL_WHEEL]),
320     );
321     supported_events
322 }
323 
default_keyboard_events() -> BTreeMap<u16, virtio_input_bitmap>324 fn default_keyboard_events() -> BTreeMap<u16, virtio_input_bitmap> {
325     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
326     supported_events.insert(
327         EV_KEY,
328         virtio_input_bitmap::from_bits(&[
329             KEY_ESC,
330             KEY_1,
331             KEY_2,
332             KEY_3,
333             KEY_4,
334             KEY_5,
335             KEY_6,
336             KEY_7,
337             KEY_8,
338             KEY_9,
339             KEY_0,
340             KEY_MINUS,
341             KEY_EQUAL,
342             KEY_BACKSPACE,
343             KEY_TAB,
344             KEY_Q,
345             KEY_W,
346             KEY_E,
347             KEY_R,
348             KEY_T,
349             KEY_Y,
350             KEY_U,
351             KEY_I,
352             KEY_O,
353             KEY_P,
354             KEY_LEFTBRACE,
355             KEY_RIGHTBRACE,
356             KEY_ENTER,
357             KEY_LEFTCTRL,
358             KEY_A,
359             KEY_S,
360             KEY_D,
361             KEY_F,
362             KEY_G,
363             KEY_H,
364             KEY_J,
365             KEY_K,
366             KEY_L,
367             KEY_SEMICOLON,
368             KEY_APOSTROPHE,
369             KEY_GRAVE,
370             KEY_LEFTSHIFT,
371             KEY_BACKSLASH,
372             KEY_Z,
373             KEY_X,
374             KEY_C,
375             KEY_V,
376             KEY_B,
377             KEY_N,
378             KEY_M,
379             KEY_COMMA,
380             KEY_DOT,
381             KEY_SLASH,
382             KEY_RIGHTSHIFT,
383             KEY_KPASTERISK,
384             KEY_LEFTALT,
385             KEY_SPACE,
386             KEY_CAPSLOCK,
387             KEY_F1,
388             KEY_F2,
389             KEY_F3,
390             KEY_F4,
391             KEY_F5,
392             KEY_F6,
393             KEY_F7,
394             KEY_F8,
395             KEY_F9,
396             KEY_F10,
397             KEY_NUMLOCK,
398             KEY_SCROLLLOCK,
399             KEY_KP7,
400             KEY_KP8,
401             KEY_KP9,
402             KEY_KPMINUS,
403             KEY_KP4,
404             KEY_KP5,
405             KEY_KP6,
406             KEY_KPPLUS,
407             KEY_KP1,
408             KEY_KP2,
409             KEY_KP3,
410             KEY_KP0,
411             KEY_KPDOT,
412             KEY_F11,
413             KEY_F12,
414             KEY_KPENTER,
415             KEY_RIGHTCTRL,
416             KEY_KPSLASH,
417             KEY_SYSRQ,
418             KEY_RIGHTALT,
419             KEY_HOME,
420             KEY_UP,
421             KEY_PAGEUP,
422             KEY_LEFT,
423             KEY_RIGHT,
424             KEY_END,
425             KEY_DOWN,
426             KEY_PAGEDOWN,
427             KEY_INSERT,
428             KEY_DELETE,
429             KEY_PAUSE,
430             KEY_MENU,
431             KEY_PRINT,
432             KEY_POWER,
433             KEY_HOMEPAGE,
434             KEY_MUTE,
435             KEY_VOLUMEDOWN,
436             KEY_VOLUMEUP,
437             KEY_BACK,
438         ]),
439     );
440     supported_events.insert(
441         EV_REP,
442         virtio_input_bitmap::from_bits(&[REP_DELAY, REP_PERIOD]),
443     );
444     supported_events.insert(
445         EV_LED,
446         virtio_input_bitmap::from_bits(&[LED_CAPSL, LED_NUML, LED_SCROLLL]),
447     );
448     supported_events
449 }
450 
default_switch_events() -> BTreeMap<u16, virtio_input_bitmap>451 fn default_switch_events() -> BTreeMap<u16, virtio_input_bitmap> {
452     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
453     supported_events.insert(
454         EV_SW,
455         virtio_input_bitmap::from_bits(&[
456             SW_LID,
457             SW_TABLET_MODE,
458             SW_HEADPHONE_INSERT,
459             SW_RFKILL_ALL,
460             SW_MICROPHONE_INSERT,
461             SW_DOCK,
462             SW_LINEOUT_INSERT,
463             SW_JACK_PHYSICAL_INSERT,
464             SW_VIDEOOUT_INSERT,
465             SW_CAMERA_LENS_COVER,
466             SW_KEYPAD_SLIDE,
467             SW_FRONT_PROXIMITY,
468             SW_ROTATE_LOCK,
469             SW_LINEIN_INSERT,
470             SW_MUTE_DEVICE,
471             SW_PEN_INSERTED,
472             SW_MACHINE_COVER,
473         ]),
474     );
475     supported_events
476 }
477 
default_rotary_events() -> BTreeMap<u16, virtio_input_bitmap>478 fn default_rotary_events() -> BTreeMap<u16, virtio_input_bitmap> {
479     let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
480     supported_events.insert(EV_REL, virtio_input_bitmap::from_bits(&[REL_WHEEL]));
481     supported_events
482 }
483 
484 #[cfg(test)]
485 mod tests {
486     use super::*;
487 
488     #[test]
test_new_switches_config()489     fn test_new_switches_config() {
490         let config = new_switches_config(0);
491         assert_eq!(config.serial_name, "virtio-switches-0");
492 
493         let events = config.supported_events;
494         assert_eq!(events.len(), 1);
495         assert_eq!(events.contains_key(&EV_SW), true);
496 
497         // The bitmap should contain SW_CNT=0x10+1=17 ones,
498         // where each one is packed into the u8 bitmap.
499         let mut expected_bitmap = [0_u8; 128];
500         expected_bitmap[0] = 0b11111111u8;
501         expected_bitmap[1] = 0b11111111u8;
502         expected_bitmap[2] = 0b1u8;
503         assert_eq!(events[&EV_SW].bitmap, expected_bitmap);
504     }
505 }
506