1 | // This file contains generated code. Do not edit directly. |
2 | // To regenerate this, run 'make'. |
3 | |
4 | //! Bindings to the `Shm` X11 extension. |
5 | |
6 | #![allow (clippy::too_many_arguments)] |
7 | // The code generator is simpler if it can always use conversions |
8 | #![allow (clippy::useless_conversion)] |
9 | |
10 | #[allow (unused_imports)] |
11 | use alloc::borrow::Cow; |
12 | #[allow (unused_imports)] |
13 | use core::convert::TryInto; |
14 | use alloc::vec; |
15 | use alloc::vec::Vec; |
16 | use core::convert::TryFrom; |
17 | use crate::errors::ParseError; |
18 | #[allow (unused_imports)] |
19 | use crate::x11_utils::TryIntoUSize; |
20 | use crate::BufWithFds; |
21 | #[allow (unused_imports)] |
22 | use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; |
23 | #[allow (unused_imports)] |
24 | use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd}; |
25 | #[allow (unused_imports)] |
26 | use super::xproto; |
27 | |
28 | /// The X11 name of the extension for QueryExtension |
29 | pub const X11_EXTENSION_NAME: &str = "MIT-SHM" ; |
30 | |
31 | /// The version number of this extension that this client library supports. |
32 | /// |
33 | /// This constant contains the version number of this extension that is supported |
34 | /// by this build of x11rb. For most things, it does not make sense to use this |
35 | /// information. If you need to send a `QueryVersion`, it is recommended to instead |
36 | /// send the maximum version of the extension that you need. |
37 | pub const X11_XML_VERSION: (u32, u32) = (1, 2); |
38 | |
39 | pub type Seg = u32; |
40 | |
41 | /// Opcode for the Completion event |
42 | pub const COMPLETION_EVENT: u8 = 0; |
43 | /// Report that an XCB_SHM_PUT_IMAGE request has completed. |
44 | /// |
45 | /// This is generated by the X server to report that an XCB_SHM_PUT_IMAGE request |
46 | /// has been successfully processed. |
47 | /// |
48 | /// # Fields |
49 | /// |
50 | /// * `drawable` - The drawable used in the XCB_SHM_PUT_IMAGE request. |
51 | /// * `minor_event` - The minor opcode used in the request. Always XCB_SHM_PUT_IMAGE. |
52 | /// * `major_event` - The major opcode used in the request. Always the opcode of the MIT-SHM |
53 | /// extension. |
54 | /// * `shmseg` - The shared memory segment used in the request. |
55 | /// * `offset` - The offset in the shared memory segment used in the request. |
56 | #[derive (Clone, Copy, Default)] |
57 | #[cfg_attr (feature = "extra-traits" , derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))] |
58 | #[cfg_attr (feature = "serde" , derive(serde::Serialize, serde::Deserialize))] |
59 | pub struct CompletionEvent { |
60 | pub response_type: u8, |
61 | pub sequence: u16, |
62 | pub drawable: xproto::Drawable, |
63 | pub minor_event: u16, |
64 | pub major_event: u8, |
65 | pub shmseg: Seg, |
66 | pub offset: u32, |
67 | } |
68 | impl_debug_if_no_extra_traits!(CompletionEvent, "CompletionEvent" ); |
69 | impl TryParse for CompletionEvent { |
70 | fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { |
71 | let remaining: &[u8] = initial_value; |
72 | let (response_type: u8, remaining: &[u8]) = u8::try_parse(remaining)?; |
73 | let remaining: &[u8] = remaining.get(1..).ok_or(err:ParseError::InsufficientData)?; |
74 | let (sequence: u16, remaining: &[u8]) = u16::try_parse(remaining)?; |
75 | let (drawable: u32, remaining: &[u8]) = xproto::Drawable::try_parse(remaining)?; |
76 | let (minor_event: u16, remaining: &[u8]) = u16::try_parse(remaining)?; |
77 | let (major_event: u8, remaining: &[u8]) = u8::try_parse(remaining)?; |
78 | let remaining: &[u8] = remaining.get(1..).ok_or(err:ParseError::InsufficientData)?; |
79 | let (shmseg: u32, remaining: &[u8]) = Seg::try_parse(remaining)?; |
80 | let (offset: u32, remaining: &[u8]) = u32::try_parse(remaining)?; |
81 | let result: CompletionEvent = CompletionEvent { response_type, sequence, drawable, minor_event, major_event, shmseg, offset }; |
82 | let _ = remaining; |
83 | let remaining: &[u8] = initial_value.get(32..) |
84 | .ok_or(err:ParseError::InsufficientData)?; |
85 | Ok((result, remaining)) |
86 | } |
87 | } |
88 | impl Serialize for CompletionEvent { |
89 | type Bytes = [u8; 20]; |
90 | fn serialize(&self) -> [u8; 20] { |
91 | let response_type_bytes = self.response_type.serialize(); |
92 | let sequence_bytes = self.sequence.serialize(); |
93 | let drawable_bytes = self.drawable.serialize(); |
94 | let minor_event_bytes = self.minor_event.serialize(); |
95 | let major_event_bytes = self.major_event.serialize(); |
96 | let shmseg_bytes = self.shmseg.serialize(); |
97 | let offset_bytes = self.offset.serialize(); |
98 | [ |
99 | response_type_bytes[0], |
100 | 0, |
101 | sequence_bytes[0], |
102 | sequence_bytes[1], |
103 | drawable_bytes[0], |
104 | drawable_bytes[1], |
105 | drawable_bytes[2], |
106 | drawable_bytes[3], |
107 | minor_event_bytes[0], |
108 | minor_event_bytes[1], |
109 | major_event_bytes[0], |
110 | 0, |
111 | shmseg_bytes[0], |
112 | shmseg_bytes[1], |
113 | shmseg_bytes[2], |
114 | shmseg_bytes[3], |
115 | offset_bytes[0], |
116 | offset_bytes[1], |
117 | offset_bytes[2], |
118 | offset_bytes[3], |
119 | ] |
120 | } |
121 | fn serialize_into(&self, bytes: &mut Vec<u8>) { |
122 | bytes.reserve(20); |
123 | self.response_type.serialize_into(bytes); |
124 | bytes.extend_from_slice(&[0; 1]); |
125 | self.sequence.serialize_into(bytes); |
126 | self.drawable.serialize_into(bytes); |
127 | self.minor_event.serialize_into(bytes); |
128 | self.major_event.serialize_into(bytes); |
129 | bytes.extend_from_slice(&[0; 1]); |
130 | self.shmseg.serialize_into(bytes); |
131 | self.offset.serialize_into(bytes); |
132 | } |
133 | } |
134 | impl From<&CompletionEvent> for [u8; 32] { |
135 | fn from(input: &CompletionEvent) -> Self { |
136 | let response_type_bytes = input.response_type.serialize(); |
137 | let sequence_bytes = input.sequence.serialize(); |
138 | let drawable_bytes = input.drawable.serialize(); |
139 | let minor_event_bytes = input.minor_event.serialize(); |
140 | let major_event_bytes = input.major_event.serialize(); |
141 | let shmseg_bytes = input.shmseg.serialize(); |
142 | let offset_bytes = input.offset.serialize(); |
143 | [ |
144 | response_type_bytes[0], |
145 | 0, |
146 | sequence_bytes[0], |
147 | sequence_bytes[1], |
148 | drawable_bytes[0], |
149 | drawable_bytes[1], |
150 | drawable_bytes[2], |
151 | drawable_bytes[3], |
152 | minor_event_bytes[0], |
153 | minor_event_bytes[1], |
154 | major_event_bytes[0], |
155 | 0, |
156 | shmseg_bytes[0], |
157 | shmseg_bytes[1], |
158 | shmseg_bytes[2], |
159 | shmseg_bytes[3], |
160 | offset_bytes[0], |
161 | offset_bytes[1], |
162 | offset_bytes[2], |
163 | offset_bytes[3], |
164 | // trailing padding |
165 | 0, |
166 | 0, |
167 | 0, |
168 | 0, |
169 | 0, |
170 | 0, |
171 | 0, |
172 | 0, |
173 | 0, |
174 | 0, |
175 | 0, |
176 | 0, |
177 | ] |
178 | } |
179 | } |
180 | impl From<CompletionEvent> for [u8; 32] { |
181 | fn from(input: CompletionEvent) -> Self { |
182 | Self::from(&input) |
183 | } |
184 | } |
185 | |
186 | /// Opcode for the BadSeg error |
187 | pub const BAD_SEG_ERROR: u8 = 0; |
188 | |
189 | /// Opcode for the QueryVersion request |
190 | pub const QUERY_VERSION_REQUEST: u8 = 0; |
191 | /// Query the version of the MIT-SHM extension.. |
192 | /// |
193 | /// This is used to determine the version of the MIT-SHM extension supported by the |
194 | /// X server. Clients MUST NOT make other requests in this extension until a reply |
195 | /// to this requests indicates the X server supports them. |
196 | #[derive (Clone, Copy, Default)] |
197 | #[cfg_attr (feature = "extra-traits" , derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))] |
198 | #[cfg_attr (feature = "serde" , derive(serde::Serialize, serde::Deserialize))] |
199 | pub struct QueryVersionRequest; |
200 | impl_debug_if_no_extra_traits!(QueryVersionRequest, "QueryVersionRequest" ); |
201 | impl QueryVersionRequest { |
202 | /// Serialize this request into bytes for the provided connection |
203 | pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> { |
204 | let length_so_far = 0; |
205 | let mut request0 = vec![ |
206 | major_opcode, |
207 | QUERY_VERSION_REQUEST, |
208 | 0, |
209 | 0, |
210 | ]; |
211 | let length_so_far = length_so_far + request0.len(); |
212 | assert_eq!(length_so_far % 4, 0); |
213 | let length = u16::try_from(length_so_far / 4).unwrap_or(0); |
214 | request0[2..4].copy_from_slice(&length.to_ne_bytes()); |
215 | ([request0.into()], vec![]) |
216 | } |
217 | /// Parse this request given its header, its body, and any fds that go along with it |
218 | #[cfg (feature = "request-parsing" )] |
219 | pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result<Self, ParseError> { |
220 | if header.minor_opcode != QUERY_VERSION_REQUEST { |
221 | return Err(ParseError::InvalidValue); |
222 | } |
223 | let _ = value; |
224 | Ok(QueryVersionRequest |
225 | ) |
226 | } |
227 | } |
228 | impl Request for QueryVersionRequest { |
229 | const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME); |
230 | |
231 | fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> { |
232 | let (bufs: [Cow<'static, [u8]>; 1], fds: Vec) = self.serialize(major_opcode); |
233 | // Flatten the buffers into a single vector |
234 | let buf: Vec = bufs.iter().flat_map(|buf: &Cow<'_, [u8]>| buf.iter().copied()).collect(); |
235 | (buf, fds) |
236 | } |
237 | } |
238 | impl crate::x11_utils::ReplyRequest for QueryVersionRequest { |
239 | type Reply = QueryVersionReply; |
240 | } |
241 | |
242 | /// The version of the MIT-SHM extension supported by the server. |
243 | /// |
244 | /// This contains the version of the MIT-SHM extension supported by the server, as |
245 | /// well as the server’s UID and GID. Clients MUST obtain the version supproted by |
246 | /// the server before making other requests from this extension. To prevent local |
247 | /// privilege escalation and local information leak security vulnerabilities, |
248 | /// clients MUST ensure that System V shared memory objects they use with this |
249 | /// extension can only be accessed by the client and the X server. If this is not |
250 | /// possible, the requests in this extension that use System V shared memory MUST |
251 | /// NOT be used. The file descriptor-passing versions provide an alternative. |
252 | /// |
253 | /// # Fields |
254 | /// |
255 | /// * `shared_pixmaps` - True if the server supports shared pixmaps, otherwise false. |
256 | /// * `major_version` - The major version of the extension supported. |
257 | /// * `minor_version` - The minor version of the extension supported. |
258 | /// * `uid` - The UID of the server. |
259 | /// * `gid` - The GID of the server. |
260 | #[derive (Clone, Copy, Default)] |
261 | #[cfg_attr (feature = "extra-traits" , derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))] |
262 | #[cfg_attr (feature = "serde" , derive(serde::Serialize, serde::Deserialize))] |
263 | pub struct QueryVersionReply { |
264 | pub shared_pixmaps: bool, |
265 | pub sequence: u16, |
266 | pub length: u32, |
267 | pub major_version: u16, |
268 | pub minor_version: u16, |
269 | pub uid: u16, |
270 | pub gid: u16, |
271 | pub pixmap_format: u8, |
272 | } |
273 | impl_debug_if_no_extra_traits!(QueryVersionReply, "QueryVersionReply" ); |
274 | impl TryParse for QueryVersionReply { |
275 | fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { |
276 | let remaining: &[u8] = initial_value; |
277 | let (response_type: u8, remaining: &[u8]) = u8::try_parse(remaining)?; |
278 | let (shared_pixmaps: bool, remaining: &[u8]) = bool::try_parse(remaining)?; |
279 | let (sequence: u16, remaining: &[u8]) = u16::try_parse(remaining)?; |
280 | let (length: u32, remaining: &[u8]) = u32::try_parse(remaining)?; |
281 | let (major_version: u16, remaining: &[u8]) = u16::try_parse(remaining)?; |
282 | let (minor_version: u16, remaining: &[u8]) = u16::try_parse(remaining)?; |
283 | let (uid: u16, remaining: &[u8]) = u16::try_parse(remaining)?; |
284 | let (gid: u16, remaining: &[u8]) = u16::try_parse(remaining)?; |
285 | let (pixmap_format: u8, remaining: &[u8]) = u8::try_parse(remaining)?; |
286 | let remaining: &[u8] = remaining.get(15..).ok_or(err:ParseError::InsufficientData)?; |
287 | if response_type != 1 { |
288 | return Err(ParseError::InvalidValue); |
289 | } |
290 | let result: QueryVersionReply = QueryVersionReply { shared_pixmaps, sequence, length, major_version, minor_version, uid, gid, pixmap_format }; |
291 | let _ = remaining; |
292 | let remaining: &[u8] = initial_value.get(32 + length as usize * 4..) |
293 | .ok_or(err:ParseError::InsufficientData)?; |
294 | Ok((result, remaining)) |
295 | } |
296 | } |
297 | impl Serialize for QueryVersionReply { |
298 | type Bytes = [u8; 32]; |
299 | fn serialize(&self) -> [u8; 32] { |
300 | let response_type_bytes = &[1]; |
301 | let shared_pixmaps_bytes = self.shared_pixmaps.serialize(); |
302 | let sequence_bytes = self.sequence.serialize(); |
303 | let length_bytes = self.length.serialize(); |
304 | let major_version_bytes = self.major_version.serialize(); |
305 | let minor_version_bytes = self.minor_version.serialize(); |
306 | let uid_bytes = self.uid.serialize(); |
307 | let gid_bytes = self.gid.serialize(); |
308 | let pixmap_format_bytes = self.pixmap_format.serialize(); |
309 | [ |
310 | response_type_bytes[0], |
311 | shared_pixmaps_bytes[0], |
312 | sequence_bytes[0], |
313 | sequence_bytes[1], |
314 | length_bytes[0], |
315 | length_bytes[1], |
316 | length_bytes[2], |
317 | length_bytes[3], |
318 | major_version_bytes[0], |
319 | major_version_bytes[1], |
320 | minor_version_bytes[0], |
321 | minor_version_bytes[1], |
322 | uid_bytes[0], |
323 | uid_bytes[1], |
324 | gid_bytes[0], |
325 | gid_bytes[1], |
326 | pixmap_format_bytes[0], |
327 | 0, |
328 | 0, |
329 | 0, |
330 | 0, |
331 | 0, |
332 | 0, |
333 | 0, |
334 | 0, |
335 | 0, |
336 | 0, |
337 | 0, |
338 | 0, |
339 | 0, |
340 | 0, |
341 | 0, |
342 | ] |
343 | } |
344 | fn serialize_into(&self, bytes: &mut Vec<u8>) { |
345 | bytes.reserve(32); |
346 | let response_type_bytes = &[1]; |
347 | bytes.push(response_type_bytes[0]); |
348 | self.shared_pixmaps.serialize_into(bytes); |
349 | self.sequence.serialize_into(bytes); |
350 | self.length.serialize_into(bytes); |
351 | self.major_version.serialize_into(bytes); |
352 | self.minor_version.serialize_into(bytes); |
353 | self.uid.serialize_into(bytes); |
354 | self.gid.serialize_into(bytes); |
355 | self.pixmap_format.serialize_into(bytes); |
356 | bytes.extend_from_slice(&[0; 15]); |
357 | } |
358 | } |
359 | |
360 | /// Opcode for the Attach request |
361 | pub const ATTACH_REQUEST: u8 = 1; |
362 | /// Attach a System V shared memory segment.. |
363 | /// |
364 | /// Attach a System V shared memory segment to the server. This will fail unless |
365 | /// the server has permission to map the segment. The client may destroy the segment |
366 | /// as soon as it receives a XCB_SHM_COMPLETION event with the shmseg value in this |
367 | /// request and with the appropriate serial number. |
368 | /// |
369 | /// # Fields |
370 | /// |
371 | /// * `shmseg` - A shared memory segment ID created with xcb_generate_id(). |
372 | /// * `shmid` - The System V shared memory segment the server should map. |
373 | /// * `read_only` - True if the segment shall be mapped read only by the X11 server, otherwise false. |
374 | #[derive (Clone, Copy, Default)] |
375 | #[cfg_attr (feature = "extra-traits" , derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))] |
376 | #[cfg_attr (feature = "serde" , derive(serde::Serialize, serde::Deserialize))] |
377 | pub struct AttachRequest { |
378 | pub shmseg: Seg, |
379 | pub shmid: u32, |
380 | pub read_only: bool, |
381 | } |
382 | impl_debug_if_no_extra_traits!(AttachRequest, "AttachRequest" ); |
383 | impl AttachRequest { |
384 | /// Serialize this request into bytes for the provided connection |
385 | pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> { |
386 | let length_so_far = 0; |
387 | let shmseg_bytes = self.shmseg.serialize(); |
388 | let shmid_bytes = self.shmid.serialize(); |
389 | let read_only_bytes = self.read_only.serialize(); |
390 | let mut request0 = vec![ |
391 | major_opcode, |
392 | ATTACH_REQUEST, |
393 | 0, |
394 | 0, |
395 | shmseg_bytes[0], |
396 | shmseg_bytes[1], |
397 | shmseg_bytes[2], |
398 | shmseg_bytes[3], |
399 | shmid_bytes[0], |
400 | shmid_bytes[1], |
401 | shmid_bytes[2], |
402 | shmid_bytes[3], |
403 | read_only_bytes[0], |
404 | 0, |
405 | 0, |
406 | 0, |
407 | ]; |
408 | let length_so_far = length_so_far + request0.len(); |
409 | assert_eq!(length_so_far % 4, 0); |
410 | let length = u16::try_from(length_so_far / 4).unwrap_or(0); |
411 | request0[2..4].copy_from_slice(&length.to_ne_bytes()); |
412 | ([request0.into()], vec![]) |
413 | } |
414 | /// Parse this request given its header, its body, and any fds that go along with it |
415 | #[cfg (feature = "request-parsing" )] |
416 | pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result<Self, ParseError> { |
417 | if header.minor_opcode != ATTACH_REQUEST { |
418 | return Err(ParseError::InvalidValue); |
419 | } |
420 | let (shmseg, remaining) = Seg::try_parse(value)?; |
421 | let (shmid, remaining) = u32::try_parse(remaining)?; |
422 | let (read_only, remaining) = bool::try_parse(remaining)?; |
423 | let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; |
424 | let _ = remaining; |
425 | Ok(AttachRequest { |
426 | shmseg, |
427 | shmid, |
428 | read_only, |
429 | }) |
430 | } |
431 | } |
432 | impl Request for AttachRequest { |
433 | const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME); |
434 | |
435 | fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> { |
436 | let (bufs: [Cow<'static, [u8]>; 1], fds: Vec) = self.serialize(major_opcode); |
437 | // Flatten the buffers into a single vector |
438 | let buf: Vec = bufs.iter().flat_map(|buf: &Cow<'_, [u8]>| buf.iter().copied()).collect(); |
439 | (buf, fds) |
440 | } |
441 | } |
442 | impl crate::x11_utils::VoidRequest for AttachRequest { |
443 | } |
444 | |
445 | /// Opcode for the Detach request |
446 | pub const DETACH_REQUEST: u8 = 2; |
447 | /// Destroys the specified shared memory segment.. |
448 | /// |
449 | /// Destroys the specified shared memory segment. This will never fail unless the |
450 | /// segment number is incorrect. |
451 | /// |
452 | /// # Fields |
453 | /// |
454 | /// * `shmseg` - The segment to be destroyed. |
455 | #[derive (Clone, Copy, Default)] |
456 | #[cfg_attr (feature = "extra-traits" , derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))] |
457 | #[cfg_attr (feature = "serde" , derive(serde::Serialize, serde::Deserialize))] |
458 | pub struct DetachRequest { |
459 | pub shmseg: Seg, |
460 | } |
461 | impl_debug_if_no_extra_traits!(DetachRequest, "DetachRequest" ); |
462 | impl DetachRequest { |
463 | /// Serialize this request into bytes for the provided connection |
464 | pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> { |
465 | let length_so_far = 0; |
466 | let shmseg_bytes = self.shmseg.serialize(); |
467 | let mut request0 = vec![ |
468 | major_opcode, |
469 | DETACH_REQUEST, |
470 | 0, |
471 | 0, |
472 | shmseg_bytes[0], |
473 | shmseg_bytes[1], |
474 | shmseg_bytes[2], |
475 | shmseg_bytes[3], |
476 | ]; |
477 | let length_so_far = length_so_far + request0.len(); |
478 | assert_eq!(length_so_far % 4, 0); |
479 | let length = u16::try_from(length_so_far / 4).unwrap_or(0); |
480 | request0[2..4].copy_from_slice(&length.to_ne_bytes()); |
481 | ([request0.into()], vec![]) |
482 | } |
483 | /// Parse this request given its header, its body, and any fds that go along with it |
484 | #[cfg (feature = "request-parsing" )] |
485 | pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result<Self, ParseError> { |
486 | if header.minor_opcode != DETACH_REQUEST { |
487 | return Err(ParseError::InvalidValue); |
488 | } |
489 | let (shmseg, remaining) = Seg::try_parse(value)?; |
490 | let _ = remaining; |
491 | Ok(DetachRequest { |
492 | shmseg, |
493 | }) |
494 | } |
495 | } |
496 | impl Request for DetachRequest { |
497 | const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME); |
498 | |
499 | fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> { |
500 | let (bufs: [Cow<'static, [u8]>; 1], fds: Vec) = self.serialize(major_opcode); |
501 | // Flatten the buffers into a single vector |
502 | let buf: Vec = bufs.iter().flat_map(|buf: &Cow<'_, [u8]>| buf.iter().copied()).collect(); |
503 | (buf, fds) |
504 | } |
505 | } |
506 | impl crate::x11_utils::VoidRequest for DetachRequest { |
507 | } |
508 | |
509 | /// Opcode for the PutImage request |
510 | pub const PUT_IMAGE_REQUEST: u8 = 3; |
511 | /// Copy data from the shared memory to the specified drawable.. |
512 | /// |
513 | /// Copy data from the shared memory to the specified drawable. The amount of bytes |
514 | /// written to the destination image is always equal to the number of bytes read |
515 | /// from the shared memory segment. |
516 | /// |
517 | /// # Fields |
518 | /// |
519 | /// * `drawable` - The drawable to draw to. |
520 | /// * `gc` - The graphics context to use. |
521 | /// * `total_width` - The total width of the source image. |
522 | /// * `total_height` - The total height of the source image. |
523 | /// * `src_x` - The source X coordinate of the sub-image to copy. |
524 | /// * `src_y` - The source Y coordinate of the sub-image to copy. |
525 | /// * `src_width` - The width, in source image coordinates, of the data to copy from the source. |
526 | /// The X server will use this to determine the amount of data to copy. The amount |
527 | /// of the destination image that is overwritten is determined automatically. |
528 | /// * `src_height` - The height, in source image coordinates, of the data to copy from the source. |
529 | /// The X server will use this to determine the amount of data to copy. The amount |
530 | /// of the destination image that is overwritten is determined automatically. |
531 | /// * `dst_x` - The X coordinate on the destination drawable to copy to. |
532 | /// * `dst_y` - The Y coordinate on the destination drawable to copy to. |
533 | /// * `depth` - The depth to use. |
534 | /// * `format` - The format of the image being drawn. If it is XYBitmap, depth must be 1, or a |
535 | /// "BadMatch" error results. The foreground pixel in the GC determines the source |
536 | /// for the one bits in the image, and the background pixel determines the source |
537 | /// for the zero bits. For XYPixmap and ZPixmap, the depth must match the depth of |
538 | /// the drawable, or a "BadMatch" error results. |
539 | /// * `send_event` - True if the server should send an XCB_SHM_COMPLETION event when the blit |
540 | /// completes. |
541 | /// * `offset` - The offset that the source image starts at. |
542 | #[derive (Clone, Copy, Default)] |
543 | #[cfg_attr (feature = "extra-traits" , derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))] |
544 | #[cfg_attr (feature = "serde" , derive(serde::Serialize, serde::Deserialize))] |
545 | pub struct PutImageRequest { |
546 | pub drawable: xproto::Drawable, |
547 | pub gc: xproto::Gcontext, |
548 | pub total_width: u16, |
549 | pub total_height: u16, |
550 | pub src_x: u16, |
551 | pub src_y: u16, |
552 | pub src_width: u16, |
553 | pub src_height: u16, |
554 | pub dst_x: i16, |
555 | pub dst_y: i16, |
556 | pub depth: u8, |
557 | pub format: u8, |
558 | pub send_event: bool, |
559 | pub shmseg: Seg, |
560 | pub offset: u32, |
561 | } |
562 | impl_debug_if_no_extra_traits!(PutImageRequest, "PutImageRequest" ); |
563 | impl PutImageRequest { |
564 | /// Serialize this request into bytes for the provided connection |
565 | pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> { |
566 | let length_so_far = 0; |
567 | let drawable_bytes = self.drawable.serialize(); |
568 | let gc_bytes = self.gc.serialize(); |
569 | let total_width_bytes = self.total_width.serialize(); |
570 | let total_height_bytes = self.total_height.serialize(); |
571 | let src_x_bytes = self.src_x.serialize(); |
572 | let src_y_bytes = self.src_y.serialize(); |
573 | let src_width_bytes = self.src_width.serialize(); |
574 | let src_height_bytes = self.src_height.serialize(); |
575 | let dst_x_bytes = self.dst_x.serialize(); |
576 | let dst_y_bytes = self.dst_y.serialize(); |
577 | let depth_bytes = self.depth.serialize(); |
578 | let format_bytes = self.format.serialize(); |
579 | let send_event_bytes = self.send_event.serialize(); |
580 | let shmseg_bytes = self.shmseg.serialize(); |
581 | let offset_bytes = self.offset.serialize(); |
582 | let mut request0 = vec![ |
583 | major_opcode, |
584 | PUT_IMAGE_REQUEST, |
585 | 0, |
586 | 0, |
587 | drawable_bytes[0], |
588 | drawable_bytes[1], |
589 | drawable_bytes[2], |
590 | drawable_bytes[3], |
591 | gc_bytes[0], |
592 | gc_bytes[1], |
593 | gc_bytes[2], |
594 | gc_bytes[3], |
595 | total_width_bytes[0], |
596 | total_width_bytes[1], |
597 | total_height_bytes[0], |
598 | total_height_bytes[1], |
599 | src_x_bytes[0], |
600 | src_x_bytes[1], |
601 | src_y_bytes[0], |
602 | src_y_bytes[1], |
603 | src_width_bytes[0], |
604 | src_width_bytes[1], |
605 | src_height_bytes[0], |
606 | src_height_bytes[1], |
607 | dst_x_bytes[0], |
608 | dst_x_bytes[1], |
609 | dst_y_bytes[0], |
610 | dst_y_bytes[1], |
611 | depth_bytes[0], |
612 | format_bytes[0], |
613 | send_event_bytes[0], |
614 | 0, |
615 | shmseg_bytes[0], |
616 | shmseg_bytes[1], |
617 | shmseg_bytes[2], |
618 | shmseg_bytes[3], |
619 | offset_bytes[0], |
620 | offset_bytes[1], |
621 | offset_bytes[2], |
622 | offset_bytes[3], |
623 | ]; |
624 | let length_so_far = length_so_far + request0.len(); |
625 | assert_eq!(length_so_far % 4, 0); |
626 | let length = u16::try_from(length_so_far / 4).unwrap_or(0); |
627 | request0[2..4].copy_from_slice(&length.to_ne_bytes()); |
628 | ([request0.into()], vec![]) |
629 | } |
630 | /// Parse this request given its header, its body, and any fds that go along with it |
631 | #[cfg (feature = "request-parsing" )] |
632 | pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result<Self, ParseError> { |
633 | if header.minor_opcode != PUT_IMAGE_REQUEST { |
634 | return Err(ParseError::InvalidValue); |
635 | } |
636 | let (drawable, remaining) = xproto::Drawable::try_parse(value)?; |
637 | let (gc, remaining) = xproto::Gcontext::try_parse(remaining)?; |
638 | let (total_width, remaining) = u16::try_parse(remaining)?; |
639 | let (total_height, remaining) = u16::try_parse(remaining)?; |
640 | let (src_x, remaining) = u16::try_parse(remaining)?; |
641 | let (src_y, remaining) = u16::try_parse(remaining)?; |
642 | let (src_width, remaining) = u16::try_parse(remaining)?; |
643 | let (src_height, remaining) = u16::try_parse(remaining)?; |
644 | let (dst_x, remaining) = i16::try_parse(remaining)?; |
645 | let (dst_y, remaining) = i16::try_parse(remaining)?; |
646 | let (depth, remaining) = u8::try_parse(remaining)?; |
647 | let (format, remaining) = u8::try_parse(remaining)?; |
648 | let (send_event, remaining) = bool::try_parse(remaining)?; |
649 | let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; |
650 | let (shmseg, remaining) = Seg::try_parse(remaining)?; |
651 | let (offset, remaining) = u32::try_parse(remaining)?; |
652 | let _ = remaining; |
653 | Ok(PutImageRequest { |
654 | drawable, |
655 | gc, |
656 | total_width, |
657 | total_height, |
658 | src_x, |
659 | src_y, |
660 | src_width, |
661 | src_height, |
662 | dst_x, |
663 | dst_y, |
664 | depth, |
665 | format, |
666 | send_event, |
667 | shmseg, |
668 | offset, |
669 | }) |
670 | } |
671 | } |
672 | impl Request for PutImageRequest { |
673 | const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME); |
674 | |
675 | fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> { |
676 | let (bufs: [Cow<'static, [u8]>; 1], fds: Vec) = self.serialize(major_opcode); |
677 | // Flatten the buffers into a single vector |
678 | let buf: Vec = bufs.iter().flat_map(|buf: &Cow<'_, [u8]>| buf.iter().copied()).collect(); |
679 | (buf, fds) |
680 | } |
681 | } |
682 | impl crate::x11_utils::VoidRequest for PutImageRequest { |
683 | } |
684 | |
685 | /// Opcode for the GetImage request |
686 | pub const GET_IMAGE_REQUEST: u8 = 4; |
687 | /// Copies data from the specified drawable to the shared memory segment.. |
688 | /// |
689 | /// Copy data from the specified drawable to the shared memory segment. The amount |
690 | /// of bytes written to the destination image is always equal to the number of bytes |
691 | /// read from the shared memory segment. |
692 | /// |
693 | /// # Fields |
694 | /// |
695 | /// * `drawable` - The drawable to copy the image out of. |
696 | /// * `x` - The X coordinate in the drawable to begin copying at. |
697 | /// * `y` - The Y coordinate in the drawable to begin copying at. |
698 | /// * `width` - The width of the image to copy. |
699 | /// * `height` - The height of the image to copy. |
700 | /// * `plane_mask` - A mask that determines which planes are used. |
701 | /// * `format` - The format to use for the copy (???). |
702 | /// * `shmseg` - The destination shared memory segment. |
703 | /// * `offset` - The offset in the shared memory segment to copy data to. |
704 | #[derive (Clone, Copy, Default)] |
705 | #[cfg_attr (feature = "extra-traits" , derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))] |
706 | #[cfg_attr (feature = "serde" , derive(serde::Serialize, serde::Deserialize))] |
707 | pub struct GetImageRequest { |
708 | pub drawable: xproto::Drawable, |
709 | pub x: i16, |
710 | pub y: i16, |
711 | pub width: u16, |
712 | pub height: u16, |
713 | pub plane_mask: u32, |
714 | pub format: u8, |
715 | pub shmseg: Seg, |
716 | pub offset: u32, |
717 | } |
718 | impl_debug_if_no_extra_traits!(GetImageRequest, "GetImageRequest" ); |
719 | impl GetImageRequest { |
720 | /// Serialize this request into bytes for the provided connection |
721 | pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> { |
722 | let length_so_far = 0; |
723 | let drawable_bytes = self.drawable.serialize(); |
724 | let x_bytes = self.x.serialize(); |
725 | let y_bytes = self.y.serialize(); |
726 | let width_bytes = self.width.serialize(); |
727 | let height_bytes = self.height.serialize(); |
728 | let plane_mask_bytes = self.plane_mask.serialize(); |
729 | let format_bytes = self.format.serialize(); |
730 | let shmseg_bytes = self.shmseg.serialize(); |
731 | let offset_bytes = self.offset.serialize(); |
732 | let mut request0 = vec![ |
733 | major_opcode, |
734 | GET_IMAGE_REQUEST, |
735 | 0, |
736 | 0, |
737 | drawable_bytes[0], |
738 | drawable_bytes[1], |
739 | drawable_bytes[2], |
740 | drawable_bytes[3], |
741 | x_bytes[0], |
742 | x_bytes[1], |
743 | y_bytes[0], |
744 | y_bytes[1], |
745 | width_bytes[0], |
746 | width_bytes[1], |
747 | height_bytes[0], |
748 | height_bytes[1], |
749 | plane_mask_bytes[0], |
750 | plane_mask_bytes[1], |
751 | plane_mask_bytes[2], |
752 | plane_mask_bytes[3], |
753 | format_bytes[0], |
754 | 0, |
755 | 0, |
756 | 0, |
757 | shmseg_bytes[0], |
758 | shmseg_bytes[1], |
759 | shmseg_bytes[2], |
760 | shmseg_bytes[3], |
761 | offset_bytes[0], |
762 | offset_bytes[1], |
763 | offset_bytes[2], |
764 | offset_bytes[3], |
765 | ]; |
766 | let length_so_far = length_so_far + request0.len(); |
767 | assert_eq!(length_so_far % 4, 0); |
768 | let length = u16::try_from(length_so_far / 4).unwrap_or(0); |
769 | request0[2..4].copy_from_slice(&length.to_ne_bytes()); |
770 | ([request0.into()], vec![]) |
771 | } |
772 | /// Parse this request given its header, its body, and any fds that go along with it |
773 | #[cfg (feature = "request-parsing" )] |
774 | pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result<Self, ParseError> { |
775 | if header.minor_opcode != GET_IMAGE_REQUEST { |
776 | return Err(ParseError::InvalidValue); |
777 | } |
778 | let (drawable, remaining) = xproto::Drawable::try_parse(value)?; |
779 | let (x, remaining) = i16::try_parse(remaining)?; |
780 | let (y, remaining) = i16::try_parse(remaining)?; |
781 | let (width, remaining) = u16::try_parse(remaining)?; |
782 | let (height, remaining) = u16::try_parse(remaining)?; |
783 | let (plane_mask, remaining) = u32::try_parse(remaining)?; |
784 | let (format, remaining) = u8::try_parse(remaining)?; |
785 | let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; |
786 | let (shmseg, remaining) = Seg::try_parse(remaining)?; |
787 | let (offset, remaining) = u32::try_parse(remaining)?; |
788 | let _ = remaining; |
789 | Ok(GetImageRequest { |
790 | drawable, |
791 | x, |
792 | y, |
793 | width, |
794 | height, |
795 | plane_mask, |
796 | format, |
797 | shmseg, |
798 | offset, |
799 | }) |
800 | } |
801 | } |
802 | impl Request for GetImageRequest { |
803 | const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME); |
804 | |
805 | fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> { |
806 | let (bufs: [Cow<'static, [u8]>; 1], fds: Vec) = self.serialize(major_opcode); |
807 | // Flatten the buffers into a single vector |
808 | let buf: Vec = bufs.iter().flat_map(|buf: &Cow<'_, [u8]>| buf.iter().copied()).collect(); |
809 | (buf, fds) |
810 | } |
811 | } |
812 | impl crate::x11_utils::ReplyRequest for GetImageRequest { |
813 | type Reply = GetImageReply; |
814 | } |
815 | |
816 | /// Indicates the result of the copy.. |
817 | /// |
818 | /// The result of the copy. |
819 | /// |
820 | /// # Fields |
821 | /// |
822 | /// * `depth` - The depth of the source drawable. |
823 | /// * `visual` - The visual ID of the source drawable. |
824 | /// * `size` - The number of bytes copied. |
825 | #[derive (Clone, Copy, Default)] |
826 | #[cfg_attr (feature = "extra-traits" , derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))] |
827 | #[cfg_attr (feature = "serde" , derive(serde::Serialize, serde::Deserialize))] |
828 | pub struct GetImageReply { |
829 | pub depth: u8, |
830 | pub sequence: u16, |
831 | pub length: u32, |
832 | pub visual: xproto::Visualid, |
833 | pub size: u32, |
834 | } |
835 | impl_debug_if_no_extra_traits!(GetImageReply, "GetImageReply" ); |
836 | impl TryParse for GetImageReply { |
837 | fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { |
838 | let remaining: &[u8] = initial_value; |
839 | let (response_type: u8, remaining: &[u8]) = u8::try_parse(remaining)?; |
840 | let (depth: u8, remaining: &[u8]) = u8::try_parse(remaining)?; |
841 | let (sequence: u16, remaining: &[u8]) = u16::try_parse(remaining)?; |
842 | let (length: u32, remaining: &[u8]) = u32::try_parse(remaining)?; |
843 | let (visual: u32, remaining: &[u8]) = xproto::Visualid::try_parse(remaining)?; |
844 | let (size: u32, remaining: &[u8]) = u32::try_parse(remaining)?; |
845 | if response_type != 1 { |
846 | return Err(ParseError::InvalidValue); |
847 | } |
848 | let result: GetImageReply = GetImageReply { depth, sequence, length, visual, size }; |
849 | let _ = remaining; |
850 | let remaining: &[u8] = initial_value.get(32 + length as usize * 4..) |
851 | .ok_or(err:ParseError::InsufficientData)?; |
852 | Ok((result, remaining)) |
853 | } |
854 | } |
855 | impl Serialize for GetImageReply { |
856 | type Bytes = [u8; 16]; |
857 | fn serialize(&self) -> [u8; 16] { |
858 | let response_type_bytes = &[1]; |
859 | let depth_bytes = self.depth.serialize(); |
860 | let sequence_bytes = self.sequence.serialize(); |
861 | let length_bytes = self.length.serialize(); |
862 | let visual_bytes = self.visual.serialize(); |
863 | let size_bytes = self.size.serialize(); |
864 | [ |
865 | response_type_bytes[0], |
866 | depth_bytes[0], |
867 | sequence_bytes[0], |
868 | sequence_bytes[1], |
869 | length_bytes[0], |
870 | length_bytes[1], |
871 | length_bytes[2], |
872 | length_bytes[3], |
873 | visual_bytes[0], |
874 | visual_bytes[1], |
875 | visual_bytes[2], |
876 | visual_bytes[3], |
877 | size_bytes[0], |
878 | size_bytes[1], |
879 | size_bytes[2], |
880 | size_bytes[3], |
881 | ] |
882 | } |
883 | fn serialize_into(&self, bytes: &mut Vec<u8>) { |
884 | bytes.reserve(16); |
885 | let response_type_bytes = &[1]; |
886 | bytes.push(response_type_bytes[0]); |
887 | self.depth.serialize_into(bytes); |
888 | self.sequence.serialize_into(bytes); |
889 | self.length.serialize_into(bytes); |
890 | self.visual.serialize_into(bytes); |
891 | self.size.serialize_into(bytes); |
892 | } |
893 | } |
894 | |
895 | /// Opcode for the CreatePixmap request |
896 | pub const CREATE_PIXMAP_REQUEST: u8 = 5; |
897 | /// Create a pixmap backed by shared memory.. |
898 | /// |
899 | /// Create a pixmap backed by shared memory. Writes to the shared memory will be |
900 | /// reflected in the contents of the pixmap, and writes to the pixmap will be |
901 | /// reflected in the contents of the shared memory. |
902 | /// |
903 | /// # Fields |
904 | /// |
905 | /// * `pid` - A pixmap ID created with xcb_generate_id(). |
906 | /// * `drawable` - The drawable to create the pixmap in. |
907 | /// * `width` - The width of the pixmap to create. Must be nonzero, or a Value error results. |
908 | /// * `height` - The height of the pixmap to create. Must be nonzero, or a Value error results. |
909 | /// * `depth` - The depth of the pixmap to create. Must be nonzero, or a Value error results. |
910 | /// * `shmseg` - The shared memory segment to use to create the pixmap. |
911 | /// * `offset` - The offset in the segment to create the pixmap at. |
912 | #[derive (Clone, Copy, Default)] |
913 | #[cfg_attr (feature = "extra-traits" , derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))] |
914 | #[cfg_attr (feature = "serde" , derive(serde::Serialize, serde::Deserialize))] |
915 | pub struct CreatePixmapRequest { |
916 | pub pid: xproto::Pixmap, |
917 | pub drawable: xproto::Drawable, |
918 | pub width: u16, |
919 | pub height: u16, |
920 | pub depth: u8, |
921 | pub shmseg: Seg, |
922 | pub offset: u32, |
923 | } |
924 | impl_debug_if_no_extra_traits!(CreatePixmapRequest, "CreatePixmapRequest" ); |
925 | impl CreatePixmapRequest { |
926 | /// Serialize this request into bytes for the provided connection |
927 | pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> { |
928 | let length_so_far = 0; |
929 | let pid_bytes = self.pid.serialize(); |
930 | let drawable_bytes = self.drawable.serialize(); |
931 | let width_bytes = self.width.serialize(); |
932 | let height_bytes = self.height.serialize(); |
933 | let depth_bytes = self.depth.serialize(); |
934 | let shmseg_bytes = self.shmseg.serialize(); |
935 | let offset_bytes = self.offset.serialize(); |
936 | let mut request0 = vec![ |
937 | major_opcode, |
938 | CREATE_PIXMAP_REQUEST, |
939 | 0, |
940 | 0, |
941 | pid_bytes[0], |
942 | pid_bytes[1], |
943 | pid_bytes[2], |
944 | pid_bytes[3], |
945 | drawable_bytes[0], |
946 | drawable_bytes[1], |
947 | drawable_bytes[2], |
948 | drawable_bytes[3], |
949 | width_bytes[0], |
950 | width_bytes[1], |
951 | height_bytes[0], |
952 | height_bytes[1], |
953 | depth_bytes[0], |
954 | 0, |
955 | 0, |
956 | 0, |
957 | shmseg_bytes[0], |
958 | shmseg_bytes[1], |
959 | shmseg_bytes[2], |
960 | shmseg_bytes[3], |
961 | offset_bytes[0], |
962 | offset_bytes[1], |
963 | offset_bytes[2], |
964 | offset_bytes[3], |
965 | ]; |
966 | let length_so_far = length_so_far + request0.len(); |
967 | assert_eq!(length_so_far % 4, 0); |
968 | let length = u16::try_from(length_so_far / 4).unwrap_or(0); |
969 | request0[2..4].copy_from_slice(&length.to_ne_bytes()); |
970 | ([request0.into()], vec![]) |
971 | } |
972 | /// Parse this request given its header, its body, and any fds that go along with it |
973 | #[cfg (feature = "request-parsing" )] |
974 | pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result<Self, ParseError> { |
975 | if header.minor_opcode != CREATE_PIXMAP_REQUEST { |
976 | return Err(ParseError::InvalidValue); |
977 | } |
978 | let (pid, remaining) = xproto::Pixmap::try_parse(value)?; |
979 | let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; |
980 | let (width, remaining) = u16::try_parse(remaining)?; |
981 | let (height, remaining) = u16::try_parse(remaining)?; |
982 | let (depth, remaining) = u8::try_parse(remaining)?; |
983 | let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; |
984 | let (shmseg, remaining) = Seg::try_parse(remaining)?; |
985 | let (offset, remaining) = u32::try_parse(remaining)?; |
986 | let _ = remaining; |
987 | Ok(CreatePixmapRequest { |
988 | pid, |
989 | drawable, |
990 | width, |
991 | height, |
992 | depth, |
993 | shmseg, |
994 | offset, |
995 | }) |
996 | } |
997 | } |
998 | impl Request for CreatePixmapRequest { |
999 | const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME); |
1000 | |
1001 | fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> { |
1002 | let (bufs: [Cow<'static, [u8]>; 1], fds: Vec) = self.serialize(major_opcode); |
1003 | // Flatten the buffers into a single vector |
1004 | let buf: Vec = bufs.iter().flat_map(|buf: &Cow<'_, [u8]>| buf.iter().copied()).collect(); |
1005 | (buf, fds) |
1006 | } |
1007 | } |
1008 | impl crate::x11_utils::VoidRequest for CreatePixmapRequest { |
1009 | } |
1010 | |
1011 | /// Opcode for the AttachFd request |
1012 | pub const ATTACH_FD_REQUEST: u8 = 6; |
1013 | /// Create a shared memory segment. |
1014 | /// |
1015 | /// Create a shared memory segment. The file descriptor will be mapped at offset |
1016 | /// zero, and the size will be obtained using fstat(). A zero size will result in a |
1017 | /// Value error. |
1018 | /// |
1019 | /// # Fields |
1020 | /// |
1021 | /// * `shmseg` - A shared memory segment ID created with xcb_generate_id(). |
1022 | /// * `shm_fd` - The file descriptor the server should mmap(). |
1023 | /// * `read_only` - True if the segment shall be mapped read only by the X11 server, otherwise false. |
1024 | #[cfg_attr (feature = "extra-traits" , derive(Debug))] |
1025 | pub struct AttachFdRequest { |
1026 | pub shmseg: Seg, |
1027 | pub shm_fd: RawFdContainer, |
1028 | pub read_only: bool, |
1029 | } |
1030 | impl_debug_if_no_extra_traits!(AttachFdRequest, "AttachFdRequest" ); |
1031 | impl AttachFdRequest { |
1032 | /// Serialize this request into bytes for the provided connection |
1033 | pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> { |
1034 | let length_so_far = 0; |
1035 | let shmseg_bytes = self.shmseg.serialize(); |
1036 | let read_only_bytes = self.read_only.serialize(); |
1037 | let mut request0 = vec![ |
1038 | major_opcode, |
1039 | ATTACH_FD_REQUEST, |
1040 | 0, |
1041 | 0, |
1042 | shmseg_bytes[0], |
1043 | shmseg_bytes[1], |
1044 | shmseg_bytes[2], |
1045 | shmseg_bytes[3], |
1046 | read_only_bytes[0], |
1047 | 0, |
1048 | 0, |
1049 | 0, |
1050 | ]; |
1051 | let length_so_far = length_so_far + request0.len(); |
1052 | assert_eq!(length_so_far % 4, 0); |
1053 | let length = u16::try_from(length_so_far / 4).unwrap_or(0); |
1054 | request0[2..4].copy_from_slice(&length.to_ne_bytes()); |
1055 | ([request0.into()], vec![self.shm_fd]) |
1056 | } |
1057 | /// Parse this request given its header, its body, and any fds that go along with it |
1058 | #[cfg (feature = "request-parsing" )] |
1059 | pub fn try_parse_request_fd(header: RequestHeader, value: &[u8], fds: &mut Vec<RawFdContainer>) -> Result<Self, ParseError> { |
1060 | if header.minor_opcode != ATTACH_FD_REQUEST { |
1061 | return Err(ParseError::InvalidValue); |
1062 | } |
1063 | let (shmseg, remaining) = Seg::try_parse(value)?; |
1064 | if fds.is_empty() { return Err(ParseError::MissingFileDescriptors) } |
1065 | let shm_fd = fds.remove(0); |
1066 | let (read_only, remaining) = bool::try_parse(remaining)?; |
1067 | let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; |
1068 | let _ = remaining; |
1069 | Ok(AttachFdRequest { |
1070 | shmseg, |
1071 | shm_fd, |
1072 | read_only, |
1073 | }) |
1074 | } |
1075 | } |
1076 | impl Request for AttachFdRequest { |
1077 | const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME); |
1078 | |
1079 | fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> { |
1080 | let (bufs: [Cow<'static, [u8]>; 1], fds: Vec) = self.serialize(major_opcode); |
1081 | // Flatten the buffers into a single vector |
1082 | let buf: Vec = bufs.iter().flat_map(|buf: &Cow<'_, [u8]>| buf.iter().copied()).collect(); |
1083 | (buf, fds) |
1084 | } |
1085 | } |
1086 | impl crate::x11_utils::VoidRequest for AttachFdRequest { |
1087 | } |
1088 | |
1089 | /// Opcode for the CreateSegment request |
1090 | pub const CREATE_SEGMENT_REQUEST: u8 = 7; |
1091 | /// Asks the server to allocate a shared memory segment.. |
1092 | /// |
1093 | /// Asks the server to allocate a shared memory segment. The server’s reply will |
1094 | /// include a file descriptor for the client to pass to mmap(). |
1095 | /// |
1096 | /// # Fields |
1097 | /// |
1098 | /// * `shmseg` - A shared memory segment ID created with xcb_generate_id(). |
1099 | /// * `size` - The size of the segment to create. |
1100 | /// * `read_only` - True if the server should map the segment read-only; otherwise false. |
1101 | #[derive (Clone, Copy, Default)] |
1102 | #[cfg_attr (feature = "extra-traits" , derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))] |
1103 | #[cfg_attr (feature = "serde" , derive(serde::Serialize, serde::Deserialize))] |
1104 | pub struct CreateSegmentRequest { |
1105 | pub shmseg: Seg, |
1106 | pub size: u32, |
1107 | pub read_only: bool, |
1108 | } |
1109 | impl_debug_if_no_extra_traits!(CreateSegmentRequest, "CreateSegmentRequest" ); |
1110 | impl CreateSegmentRequest { |
1111 | /// Serialize this request into bytes for the provided connection |
1112 | pub fn serialize(self, major_opcode: u8) -> BufWithFds<[Cow<'static, [u8]>; 1]> { |
1113 | let length_so_far = 0; |
1114 | let shmseg_bytes = self.shmseg.serialize(); |
1115 | let size_bytes = self.size.serialize(); |
1116 | let read_only_bytes = self.read_only.serialize(); |
1117 | let mut request0 = vec![ |
1118 | major_opcode, |
1119 | CREATE_SEGMENT_REQUEST, |
1120 | 0, |
1121 | 0, |
1122 | shmseg_bytes[0], |
1123 | shmseg_bytes[1], |
1124 | shmseg_bytes[2], |
1125 | shmseg_bytes[3], |
1126 | size_bytes[0], |
1127 | size_bytes[1], |
1128 | size_bytes[2], |
1129 | size_bytes[3], |
1130 | read_only_bytes[0], |
1131 | 0, |
1132 | 0, |
1133 | 0, |
1134 | ]; |
1135 | let length_so_far = length_so_far + request0.len(); |
1136 | assert_eq!(length_so_far % 4, 0); |
1137 | let length = u16::try_from(length_so_far / 4).unwrap_or(0); |
1138 | request0[2..4].copy_from_slice(&length.to_ne_bytes()); |
1139 | ([request0.into()], vec![]) |
1140 | } |
1141 | /// Parse this request given its header, its body, and any fds that go along with it |
1142 | #[cfg (feature = "request-parsing" )] |
1143 | pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result<Self, ParseError> { |
1144 | if header.minor_opcode != CREATE_SEGMENT_REQUEST { |
1145 | return Err(ParseError::InvalidValue); |
1146 | } |
1147 | let (shmseg, remaining) = Seg::try_parse(value)?; |
1148 | let (size, remaining) = u32::try_parse(remaining)?; |
1149 | let (read_only, remaining) = bool::try_parse(remaining)?; |
1150 | let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; |
1151 | let _ = remaining; |
1152 | Ok(CreateSegmentRequest { |
1153 | shmseg, |
1154 | size, |
1155 | read_only, |
1156 | }) |
1157 | } |
1158 | } |
1159 | impl Request for CreateSegmentRequest { |
1160 | const EXTENSION_NAME: Option<&'static str> = Some(X11_EXTENSION_NAME); |
1161 | |
1162 | fn serialize(self, major_opcode: u8) -> BufWithFds<Vec<u8>> { |
1163 | let (bufs: [Cow<'static, [u8]>; 1], fds: Vec) = self.serialize(major_opcode); |
1164 | // Flatten the buffers into a single vector |
1165 | let buf: Vec = bufs.iter().flat_map(|buf: &Cow<'_, [u8]>| buf.iter().copied()).collect(); |
1166 | (buf, fds) |
1167 | } |
1168 | } |
1169 | impl crate::x11_utils::ReplyFDsRequest for CreateSegmentRequest { |
1170 | type Reply = CreateSegmentReply; |
1171 | } |
1172 | |
1173 | /// The returned file descriptor.. |
1174 | /// |
1175 | /// The file descriptor returned by the server. The client may call mmap() on it to |
1176 | /// map the memory allocated by the server. |
1177 | /// |
1178 | /// # Fields |
1179 | /// |
1180 | /// * `nfd` - The number of file descriptors sent by the server. Will always be 1. |
1181 | #[cfg_attr (feature = "extra-traits" , derive(Debug))] |
1182 | pub struct CreateSegmentReply { |
1183 | pub nfd: u8, |
1184 | pub sequence: u16, |
1185 | pub length: u32, |
1186 | pub shm_fd: RawFdContainer, |
1187 | } |
1188 | impl_debug_if_no_extra_traits!(CreateSegmentReply, "CreateSegmentReply" ); |
1189 | impl TryParseFd for CreateSegmentReply { |
1190 | fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec<RawFdContainer>) -> Result<(Self, &'a [u8]), ParseError> { |
1191 | let remaining: &'a [u8] = initial_value; |
1192 | let (response_type: u8, remaining: &[u8]) = u8::try_parse(remaining)?; |
1193 | let (nfd: u8, remaining: &[u8]) = u8::try_parse(remaining)?; |
1194 | let (sequence: u16, remaining: &[u8]) = u16::try_parse(remaining)?; |
1195 | let (length: u32, remaining: &[u8]) = u32::try_parse(remaining)?; |
1196 | if fds.is_empty() { return Err(ParseError::MissingFileDescriptors) } |
1197 | let shm_fd: OwnedFd = fds.remove(index:0); |
1198 | let remaining: &[u8] = remaining.get(24..).ok_or(err:ParseError::InsufficientData)?; |
1199 | if response_type != 1 { |
1200 | return Err(ParseError::InvalidValue); |
1201 | } |
1202 | let result: CreateSegmentReply = CreateSegmentReply { nfd, sequence, length, shm_fd }; |
1203 | let _ = remaining; |
1204 | let remaining: &[u8] = initial_value.get(32 + length as usize * 4..) |
1205 | .ok_or(err:ParseError::InsufficientData)?; |
1206 | Ok((result, remaining)) |
1207 | } |
1208 | } |
1209 | impl Serialize for CreateSegmentReply { |
1210 | type Bytes = [u8; 32]; |
1211 | fn serialize(&self) -> [u8; 32] { |
1212 | let response_type_bytes = &[1]; |
1213 | let nfd_bytes = self.nfd.serialize(); |
1214 | let sequence_bytes = self.sequence.serialize(); |
1215 | let length_bytes = self.length.serialize(); |
1216 | [ |
1217 | response_type_bytes[0], |
1218 | nfd_bytes[0], |
1219 | sequence_bytes[0], |
1220 | sequence_bytes[1], |
1221 | length_bytes[0], |
1222 | length_bytes[1], |
1223 | length_bytes[2], |
1224 | length_bytes[3], |
1225 | 0, |
1226 | 0, |
1227 | 0, |
1228 | 0, |
1229 | 0, |
1230 | 0, |
1231 | 0, |
1232 | 0, |
1233 | 0, |
1234 | 0, |
1235 | 0, |
1236 | 0, |
1237 | 0, |
1238 | 0, |
1239 | 0, |
1240 | 0, |
1241 | 0, |
1242 | 0, |
1243 | 0, |
1244 | 0, |
1245 | 0, |
1246 | 0, |
1247 | 0, |
1248 | 0, |
1249 | ] |
1250 | } |
1251 | fn serialize_into(&self, bytes: &mut Vec<u8>) { |
1252 | bytes.reserve(32); |
1253 | let response_type_bytes = &[1]; |
1254 | bytes.push(response_type_bytes[0]); |
1255 | self.nfd.serialize_into(bytes); |
1256 | self.sequence.serialize_into(bytes); |
1257 | self.length.serialize_into(bytes); |
1258 | bytes.extend_from_slice(&[0; 24]); |
1259 | } |
1260 | } |
1261 | |
1262 | |