1 use x11rb::errors::ParseError;
2 use x11rb::protocol::xproto::{Setup, VisualClass};
3 use x11rb::x11_utils::TryParse;
4 
get_setup_data() -> Vec<u8>5 fn get_setup_data() -> Vec<u8> {
6     let mut s = Vec::new();
7 
8     let vendor_len: u16 = 2;
9     let num_pixmap_formats: u8 = 1;
10     let roots_len: u8 = 18;
11     let header: u16 = 10;
12     let length: u16 =
13         header + vendor_len + 2 * u16::from(num_pixmap_formats) + u16::from(roots_len);
14 
15     s.extend(&[1, 0]); // Status "success" and padding
16     s.extend(&11u16.to_ne_bytes()); // major version
17     s.extend(&0u16.to_ne_bytes()); // minor version
18     s.extend(&length.to_ne_bytes()); // length
19     s.extend(&0x1234_5678u32.to_ne_bytes()); // release number
20     s.extend(&0x1000_0000u32.to_ne_bytes()); // resource id base
21     s.extend(&0x0000_00ffu32.to_ne_bytes()); // resource id mask
22     s.extend(&0u32.to_ne_bytes()); // motion buffer size
23     s.extend(&6u16.to_ne_bytes()); // vendor length
24     s.extend(&0x100u16.to_ne_bytes()); // maximum request length
25     s.push(1); // roots length
26     s.push(num_pixmap_formats); // pixmap formats length
27     s.push(1); // image byte order: MSB first
28     s.push(1); // bitmap format bit order: MSB first
29     s.push(0); // scanline unit
30     s.push(0); // scanline pad
31     s.push(0); // min keycode
32     s.push(0xff); // max keycode
33     s.extend(&[0, 0, 0, 0]); // padding
34     assert_eq!(s.len(), usize::from(header) * 4);
35 
36     s.extend("Vendor  ".bytes()); // vendor + padding
37     assert_eq!(s.len(), usize::from(header + vendor_len) * 4);
38 
39     // Pixmap formats, we said above there is one entry
40     s.push(15); // depth
41     s.push(42); // bits per pixel
42     s.push(21); // scanline pad
43     s.extend(&[0, 0, 0, 0, 0]); // padding
44     assert_eq!(
45         s.len(),
46         4 * usize::from(header + vendor_len + 2 * u16::from(num_pixmap_formats))
47     );
48 
49     // Screens, we said above there is one entry
50     s.extend(&1u32.to_ne_bytes()); // root window
51     s.extend(&2u32.to_ne_bytes()); // default colormap
52     s.extend(&3u32.to_ne_bytes()); // white pixel
53     s.extend(&4u32.to_ne_bytes()); // black pixel
54     s.extend(&0u32.to_ne_bytes()); // current input masks
55     s.extend(&0u16.to_ne_bytes()); // width in pixels
56     s.extend(&0u16.to_ne_bytes()); // height in pixels
57     s.extend(&0u16.to_ne_bytes()); // width in mm
58     s.extend(&0u16.to_ne_bytes()); // height in mm
59     s.extend(&0u16.to_ne_bytes()); // min installed maps
60     s.extend(&0u16.to_ne_bytes()); // max installed maps
61     s.extend(&0u32.to_ne_bytes()); // root visual
62     s.extend(&[0, 0, 0, 1]); // backing stores, save unders, root depths, allowed depths len
63 
64     // one depth entry
65     s.extend(&[99, 0]); // depth and padding
66     s.extend(&1u16.to_ne_bytes()); // width visuals len
67     s.extend(&[0, 0, 0, 0]); // padding
68 
69     // one visualtype entry
70     s.extend(&80u32.to_ne_bytes()); // visualid
71     s.extend(&[2, 4]); // class and bits per rgb value
72     s.extend(&81u16.to_ne_bytes()); // colormap entries
73     s.extend(&82u32.to_ne_bytes()); // red mask
74     s.extend(&83u32.to_ne_bytes()); // green mask
75     s.extend(&84u32.to_ne_bytes()); // blue mask
76     s.extend(&[0, 0, 0, 0]); // padding
77 
78     assert_eq!(s.len(), usize::from(length) * 4);
79 
80     s
81 }
82 
83 #[test]
parse_setup() -> Result<(), ParseError>84 fn parse_setup() -> Result<(), ParseError> {
85     let setup = get_setup_data();
86     let (setup, remaining) = Setup::try_parse(&*setup)?;
87 
88     assert_eq!(remaining.len(), 0);
89 
90     assert_eq!(
91         (1, 11, 0),
92         (
93             setup.status,
94             setup.protocol_major_version,
95             setup.protocol_minor_version
96         )
97     );
98     assert_eq!(0x1234_5678, setup.release_number);
99     assert_eq!((0, 0xff), (setup.min_keycode, setup.max_keycode));
100     assert_eq!(b"Vendor", &setup.vendor[..]);
101 
102     assert_eq!(1, setup.pixmap_formats.len());
103     let format = &setup.pixmap_formats[0];
104     assert_eq!(15, format.depth);
105     assert_eq!(42, format.bits_per_pixel);
106     assert_eq!(21, format.scanline_pad);
107 
108     assert_eq!(1, setup.roots.len());
109     let root = &setup.roots[0];
110     assert_eq!(
111         (1, 2, 3, 4),
112         (
113             root.root,
114             root.default_colormap,
115             root.white_pixel,
116             root.black_pixel
117         )
118     );
119 
120     assert_eq!(1, root.allowed_depths.len());
121     let depth = &root.allowed_depths[0];
122     assert_eq!(99, depth.depth);
123 
124     assert_eq!(1, depth.visuals.len());
125     let visual = &depth.visuals[0];
126     assert_eq!(80, visual.visual_id);
127     assert_eq!(VisualClass::STATIC_COLOR, visual.class);
128     assert_eq!(4, visual.bits_per_rgb_value);
129     assert_eq!(81, visual.colormap_entries);
130     assert_eq!(82, visual.red_mask);
131     assert_eq!(83, visual.green_mask);
132     assert_eq!(84, visual.blue_mask);
133 
134     Ok(())
135 }
136 
137 #[cfg(feature = "xinput")]
138 #[test]
parse_xi_get_property_reply_format_0()139 fn parse_xi_get_property_reply_format_0() {
140     let mut s = vec![
141         1, // response_type
142         0, // pad
143     ];
144     s.extend(&0u16.to_ne_bytes()); // sequence
145     s.extend(&0u32.to_ne_bytes()); // length
146     s.extend(&0u32.to_ne_bytes()); // type
147     s.extend(&0u32.to_ne_bytes()); // bytes_after
148     s.extend(&0u32.to_ne_bytes()); // num_items
149     s.push(0); // format
150     s.extend(&[0; 11]); // pad
151 
152     use x11rb::protocol::xinput::{XIGetPropertyItems, XIGetPropertyReply};
153     let empty: &[u8] = &[];
154     assert_eq!(
155         XIGetPropertyReply::try_parse(&s),
156         Ok((
157             XIGetPropertyReply {
158                 sequence: 0,
159                 length: 0,
160                 type_: 0,
161                 bytes_after: 0,
162                 num_items: 0,
163                 items: XIGetPropertyItems::InvalidValue(0),
164             },
165             empty,
166         )),
167     );
168 }
169