1#![allow(clippy::too_many_arguments)]
7#![allow(clippy::useless_conversion)]
9
10#[allow(unused_imports)]
11use alloc::borrow::Cow;
12#[allow(unused_imports)]
13use core::convert::TryInto;
14use alloc::vec;
15use alloc::vec::Vec;
16use core::convert::TryFrom;
17use crate::errors::ParseError;
18#[allow(unused_imports)]
19use crate::x11_utils::TryIntoUSize;
20use crate::BufWithFds;
21#[allow(unused_imports)]
22use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum};
23#[allow(unused_imports)]
24use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd};
25#[allow(unused_imports)]
26use super::xproto;
27
28pub const X11_EXTENSION_NAME: &str = "XTEST";
30
31pub const X11_XML_VERSION: (u32, u32) = (2, 2);
38
39pub const GET_VERSION_REQUEST: u8 = 0;
41#[derive(Clone, Copy, Default)]
42#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))]
43#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
44pub struct GetVersionRequest {
45 pub major_version: u8,
46 pub minor_version: u16,
47}
48impl_debug_if_no_extra_traits!(GetVersionRequest, "GetVersionRequest");
49impl GetVersionRequest {
50 pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> {
52 let length_so_far = 0;
53 let major_version_bytes = self.major_version.serialize();
54 let minor_version_bytes = self.minor_version.serialize();
55 let mut request0 = vec![
56 major_opcode,
57 GET_VERSION_REQUEST,
58 0,
59 0,
60 major_version_bytes[0],
61 0,
62 minor_version_bytes[0],
63 minor_version_bytes[1],
64 ];
65 let length_so_far = length_so_far + request0.len();
66 assert_eq!(length_so_far % 4, 0);
67 let length = u16::try_from(length_so_far / 4).unwrap_or(0);
68 request0[2..4].copy_from_slice(&length.to_ne_bytes());
69 ([request0.into()], vec![])
70 }
71 #[cfg(feature = "request-parsing")]
73 pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result<Self, ParseError> {
74 if header.minor_opcode != GET_VERSION_REQUEST {
75 return Err(ParseError::InvalidValue);
76 }
77 let (major_version, remaining) = u8::try_parse(value)?;
78 let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?;
79 let (minor_version, remaining) = u16::try_parse(remaining)?;
80 let _ = remaining;
81 Ok(GetVersionRequest {
82 major_version,
83 minor_version,
84 })
85 }
86}
87impl Request for GetVersionRequest {
88 const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME);
89
90 fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> {
91 let (bufs, fds) = self.serialize(major_opcode);
92 let buf = bufs.iter().flat_map(|buf| buf.iter().copied()).collect();
94 (buf, fds)
95 }
96}
97impl crate::x11_utils::ReplyRequest for GetVersionRequest {
98 type Reply = GetVersionReply;
99}
100
101#[derive(Clone, Copy, Default)]
102#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))]
103#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
104pub struct GetVersionReply {
105 pub major_version: u8,
106 pub sequence: u16,
107 pub length: u32,
108 pub minor_version: u16,
109}
110impl_debug_if_no_extra_traits!(GetVersionReply, "GetVersionReply");
111impl TryParse for GetVersionReply {
112 fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> {
113 let remaining = initial_value;
114 let (response_type, remaining) = u8::try_parse(remaining)?;
115 let (major_version, remaining) = u8::try_parse(remaining)?;
116 let (sequence, remaining) = u16::try_parse(remaining)?;
117 let (length, remaining) = u32::try_parse(remaining)?;
118 let (minor_version, remaining) = u16::try_parse(remaining)?;
119 if response_type != 1 {
120 return Err(ParseError::InvalidValue);
121 }
122 let result = GetVersionReply { major_version, sequence, length, minor_version };
123 let _ = remaining;
124 let remaining = initial_value.get(32 + length as usize * 4..)
125 .ok_or(ParseError::InsufficientData)?;
126 Ok((result, remaining))
127 }
128}
129impl Serialize for GetVersionReply {
130 type Bytes = [u8; 10];
131 fn serialize(&self) -> [u8; 10] {
132 let response_type_bytes = &[1];
133 let major_version_bytes = self.major_version.serialize();
134 let sequence_bytes = self.sequence.serialize();
135 let length_bytes = self.length.serialize();
136 let minor_version_bytes = self.minor_version.serialize();
137 [
138 response_type_bytes[0],
139 major_version_bytes[0],
140 sequence_bytes[0],
141 sequence_bytes[1],
142 length_bytes[0],
143 length_bytes[1],
144 length_bytes[2],
145 length_bytes[3],
146 minor_version_bytes[0],
147 minor_version_bytes[1],
148 ]
149 }
150 fn serialize_into(&self, bytes: &mut Vec<u8>) {
151 bytes.reserve(10);
152 let response_type_bytes = &[1];
153 bytes.push(response_type_bytes[0]);
154 self.major_version.serialize_into(bytes);
155 self.sequence.serialize_into(bytes);
156 self.length.serialize_into(bytes);
157 self.minor_version.serialize_into(bytes);
158 }
159}
160
161#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
162#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
163pub struct Cursor(bool);
164impl Cursor {
165 pub const NONE: Self = Self(false);
166 pub const CURRENT: Self = Self(true);
167}
168impl From<Cursor> for bool {
169 #[inline]
170 fn from(input: Cursor) -> Self {
171 input.0
172 }
173}
174impl From<Cursor> for Option<bool> {
175 #[inline]
176 fn from(input: Cursor) -> Self {
177 Some(input.0)
178 }
179}
180impl From<Cursor> for u8 {
181 #[inline]
182 fn from(input: Cursor) -> Self {
183 u8::from(input.0)
184 }
185}
186impl From<Cursor> for Option<u8> {
187 #[inline]
188 fn from(input: Cursor) -> Self {
189 Some(u8::from(input.0))
190 }
191}
192impl From<Cursor> for u16 {
193 #[inline]
194 fn from(input: Cursor) -> Self {
195 u16::from(input.0)
196 }
197}
198impl From<Cursor> for Option<u16> {
199 #[inline]
200 fn from(input: Cursor) -> Self {
201 Some(u16::from(input.0))
202 }
203}
204impl From<Cursor> for u32 {
205 #[inline]
206 fn from(input: Cursor) -> Self {
207 u32::from(input.0)
208 }
209}
210impl From<Cursor> for Option<u32> {
211 #[inline]
212 fn from(input: Cursor) -> Self {
213 Some(u32::from(input.0))
214 }
215}
216impl From<bool> for Cursor {
217 #[inline]
218 fn from(value: bool) -> Self {
219 Self(value)
220 }
221}
222impl core::fmt::Debug for Cursor {
223 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
224 let variants = [
225 (Self::NONE.0.into(), "NONE", "None"),
226 (Self::CURRENT.0.into(), "CURRENT", "Current"),
227 ];
228 pretty_print_enum(fmt, self.0.into(), &variants)
229 }
230}
231
232pub const COMPARE_CURSOR_REQUEST: u8 = 1;
234#[derive(Clone, Copy, Default)]
235#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))]
236#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
237pub struct CompareCursorRequest {
238 pub window: xproto::Window,
239 pub cursor: xproto::Cursor,
240}
241impl_debug_if_no_extra_traits!(CompareCursorRequest, "CompareCursorRequest");
242impl CompareCursorRequest {
243 pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> {
245 let length_so_far = 0;
246 let window_bytes = self.window.serialize();
247 let cursor_bytes = self.cursor.serialize();
248 let mut request0 = vec![
249 major_opcode,
250 COMPARE_CURSOR_REQUEST,
251 0,
252 0,
253 window_bytes[0],
254 window_bytes[1],
255 window_bytes[2],
256 window_bytes[3],
257 cursor_bytes[0],
258 cursor_bytes[1],
259 cursor_bytes[2],
260 cursor_bytes[3],
261 ];
262 let length_so_far = length_so_far + request0.len();
263 assert_eq!(length_so_far % 4, 0);
264 let length = u16::try_from(length_so_far / 4).unwrap_or(0);
265 request0[2..4].copy_from_slice(&length.to_ne_bytes());
266 ([request0.into()], vec![])
267 }
268 #[cfg(feature = "request-parsing")]
270 pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result<Self, ParseError> {
271 if header.minor_opcode != COMPARE_CURSOR_REQUEST {
272 return Err(ParseError::InvalidValue);
273 }
274 let (window, remaining) = xproto::Window::try_parse(value)?;
275 let (cursor, remaining) = xproto::Cursor::try_parse(remaining)?;
276 let _ = remaining;
277 Ok(CompareCursorRequest {
278 window,
279 cursor,
280 })
281 }
282}
283impl Request for CompareCursorRequest {
284 const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME);
285
286 fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> {
287 let (bufs, fds) = self.serialize(major_opcode);
288 let buf = bufs.iter().flat_map(|buf| buf.iter().copied()).collect();
290 (buf, fds)
291 }
292}
293impl crate::x11_utils::ReplyRequest for CompareCursorRequest {
294 type Reply = CompareCursorReply;
295}
296
297#[derive(Clone, Copy, Default)]
298#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))]
299#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
300pub struct CompareCursorReply {
301 pub same: bool,
302 pub sequence: u16,
303 pub length: u32,
304}
305impl_debug_if_no_extra_traits!(CompareCursorReply, "CompareCursorReply");
306impl TryParse for CompareCursorReply {
307 fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> {
308 let remaining = initial_value;
309 let (response_type, remaining) = u8::try_parse(remaining)?;
310 let (same, remaining) = bool::try_parse(remaining)?;
311 let (sequence, remaining) = u16::try_parse(remaining)?;
312 let (length, remaining) = u32::try_parse(remaining)?;
313 if response_type != 1 {
314 return Err(ParseError::InvalidValue);
315 }
316 let result = CompareCursorReply { same, sequence, length };
317 let _ = remaining;
318 let remaining = initial_value.get(32 + length as usize * 4..)
319 .ok_or(ParseError::InsufficientData)?;
320 Ok((result, remaining))
321 }
322}
323impl Serialize for CompareCursorReply {
324 type Bytes = [u8; 8];
325 fn serialize(&self) -> [u8; 8] {
326 let response_type_bytes = &[1];
327 let same_bytes = self.same.serialize();
328 let sequence_bytes = self.sequence.serialize();
329 let length_bytes = self.length.serialize();
330 [
331 response_type_bytes[0],
332 same_bytes[0],
333 sequence_bytes[0],
334 sequence_bytes[1],
335 length_bytes[0],
336 length_bytes[1],
337 length_bytes[2],
338 length_bytes[3],
339 ]
340 }
341 fn serialize_into(&self, bytes: &mut Vec<u8>) {
342 bytes.reserve(8);
343 let response_type_bytes = &[1];
344 bytes.push(response_type_bytes[0]);
345 self.same.serialize_into(bytes);
346 self.sequence.serialize_into(bytes);
347 self.length.serialize_into(bytes);
348 }
349}
350
351pub const FAKE_INPUT_REQUEST: u8 = 2;
353#[derive(Clone, Copy, Default)]
354#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))]
355#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
356pub struct FakeInputRequest {
357 pub type_: u8,
358 pub detail: u8,
359 pub time: u32,
360 pub root: xproto::Window,
361 pub root_x: i16,
362 pub root_y: i16,
363 pub deviceid: u8,
364}
365impl_debug_if_no_extra_traits!(FakeInputRequest, "FakeInputRequest");
366impl FakeInputRequest {
367 pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> {
369 let length_so_far = 0;
370 let type_bytes = self.type_.serialize();
371 let detail_bytes = self.detail.serialize();
372 let time_bytes = self.time.serialize();
373 let root_bytes = self.root.serialize();
374 let root_x_bytes = self.root_x.serialize();
375 let root_y_bytes = self.root_y.serialize();
376 let deviceid_bytes = self.deviceid.serialize();
377 let mut request0 = vec![
378 major_opcode,
379 FAKE_INPUT_REQUEST,
380 0,
381 0,
382 type_bytes[0],
383 detail_bytes[0],
384 0,
385 0,
386 time_bytes[0],
387 time_bytes[1],
388 time_bytes[2],
389 time_bytes[3],
390 root_bytes[0],
391 root_bytes[1],
392 root_bytes[2],
393 root_bytes[3],
394 0,
395 0,
396 0,
397 0,
398 0,
399 0,
400 0,
401 0,
402 root_x_bytes[0],
403 root_x_bytes[1],
404 root_y_bytes[0],
405 root_y_bytes[1],
406 0,
407 0,
408 0,
409 0,
410 0,
411 0,
412 0,
413 deviceid_bytes[0],
414 ];
415 let length_so_far = length_so_far + request0.len();
416 assert_eq!(length_so_far % 4, 0);
417 let length = u16::try_from(length_so_far / 4).unwrap_or(0);
418 request0[2..4].copy_from_slice(&length.to_ne_bytes());
419 ([request0.into()], vec![])
420 }
421 #[cfg(feature = "request-parsing")]
423 pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result<Self, ParseError> {
424 if header.minor_opcode != FAKE_INPUT_REQUEST {
425 return Err(ParseError::InvalidValue);
426 }
427 let (type_, remaining) = u8::try_parse(value)?;
428 let (detail, remaining) = u8::try_parse(remaining)?;
429 let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?;
430 let (time, remaining) = u32::try_parse(remaining)?;
431 let (root, remaining) = xproto::Window::try_parse(remaining)?;
432 let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?;
433 let (root_x, remaining) = i16::try_parse(remaining)?;
434 let (root_y, remaining) = i16::try_parse(remaining)?;
435 let remaining = remaining.get(7..).ok_or(ParseError::InsufficientData)?;
436 let (deviceid, remaining) = u8::try_parse(remaining)?;
437 let _ = remaining;
438 Ok(FakeInputRequest {
439 type_,
440 detail,
441 time,
442 root,
443 root_x,
444 root_y,
445 deviceid,
446 })
447 }
448}
449impl Request for FakeInputRequest {
450 const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME);
451
452 fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> {
453 let (bufs, fds) = self.serialize(major_opcode);
454 let buf = bufs.iter().flat_map(|buf| buf.iter().copied()).collect();
456 (buf, fds)
457 }
458}
459impl crate::x11_utils::VoidRequest for FakeInputRequest {
460}
461
462pub const GRAB_CONTROL_REQUEST: u8 = 3;
464#[derive(Clone, Copy, Default)]
465#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))]
466#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
467pub struct GrabControlRequest {
468 pub impervious: bool,
469}
470impl_debug_if_no_extra_traits!(GrabControlRequest, "GrabControlRequest");
471impl GrabControlRequest {
472 pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> {
474 let length_so_far = 0;
475 let impervious_bytes = self.impervious.serialize();
476 let mut request0 = vec![
477 major_opcode,
478 GRAB_CONTROL_REQUEST,
479 0,
480 0,
481 impervious_bytes[0],
482 0,
483 0,
484 0,
485 ];
486 let length_so_far = length_so_far + request0.len();
487 assert_eq!(length_so_far % 4, 0);
488 let length = u16::try_from(length_so_far / 4).unwrap_or(0);
489 request0[2..4].copy_from_slice(&length.to_ne_bytes());
490 ([request0.into()], vec![])
491 }
492 #[cfg(feature = "request-parsing")]
494 pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result<Self, ParseError> {
495 if header.minor_opcode != GRAB_CONTROL_REQUEST {
496 return Err(ParseError::InvalidValue);
497 }
498 let (impervious, remaining) = bool::try_parse(value)?;
499 let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?;
500 let _ = remaining;
501 Ok(GrabControlRequest {
502 impervious,
503 })
504 }
505}
506impl Request for GrabControlRequest {
507 const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME);
508
509 fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> {
510 let (bufs, fds) = self.serialize(major_opcode);
511 let buf = bufs.iter().flat_map(|buf| buf.iter().copied()).collect();
513 (buf, fds)
514 }
515}
516impl crate::x11_utils::VoidRequest for GrabControlRequest {
517}
518