1use std::fmt;
2
3use bit_field::BitField as _;
4use ironrdp_core::{
5 cast_length, decode_cursor, ensure_fixed_part_size, ensure_size, invalid_field_err, read_padding, write_padding,
6 Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor,
7};
8use num_derive::{FromPrimitive, ToPrimitive};
9use num_traits::{FromPrimitive as _, ToPrimitive as _};
10
11use super::{CapabilitySet, Color, Point, RDP_GFX_HEADER_SIZE};
12use crate::gcc::Monitor;
13use crate::geometry::InclusiveRectangle;
14
15pub(crate) const RESET_GRAPHICS_PDU_SIZE: usize = 340;
16
17const MAX_RESET_GRAPHICS_WIDTH_HEIGHT: u32 = 32_766;
18const MONITOR_COUNT_MAX: u32 = 16;
19
20#[derive(Clone, PartialEq, Eq)]
21pub struct WireToSurface1Pdu {
22 pub surface_id: u16,
23 pub codec_id: Codec1Type,
24 pub pixel_format: PixelFormat,
25 pub destination_rectangle: InclusiveRectangle,
26 pub bitmap_data: Vec<u8>,
27}
28
29impl fmt::Debug for WireToSurface1Pdu {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 f.debug_struct("WireToSurface1Pdu")
32 .field("surface_id", &self.surface_id)
33 .field("codec_id", &self.codec_id)
34 .field("pixel_format", &self.pixel_format)
35 .field("destination_rectangle", &self.destination_rectangle)
36 .field("bitmap_data_length", &self.bitmap_data.len())
37 .finish()
38 }
39}
40
41impl WireToSurface1Pdu {
42 const NAME: &'static str = "WireToSurface1Pdu";
43
44 const FIXED_PART_SIZE: usize = 2 + 2 + 1 + InclusiveRectangle::FIXED_PART_SIZE + 4 ;
45}
46
47impl Encode for WireToSurface1Pdu {
48 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
49 ensure_size!(in: dst, size: self.size());
50
51 dst.write_u16(self.surface_id);
52 dst.write_u16(self.codec_id.to_u16().unwrap());
53 dst.write_u8(self.pixel_format.to_u8().unwrap());
54 self.destination_rectangle.encode(dst)?;
55 dst.write_u32(cast_length!("BitmapDataLen", self.bitmap_data.len())?);
56 dst.write_slice(&self.bitmap_data);
57 Ok(())
58 }
59
60 fn name(&self) -> &'static str {
61 Self::NAME
62 }
63
64 fn size(&self) -> usize {
65 Self::FIXED_PART_SIZE + self.bitmap_data.len()
66 }
67}
68
69impl<'a> Decode<'a> for WireToSurface1Pdu {
70 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
71 ensure_fixed_part_size!(in: src);
72
73 let surface_id = src.read_u16();
74 let codec_id =
75 Codec1Type::from_u16(src.read_u16()).ok_or_else(|| invalid_field_err!("CodecId", "invalid codec ID"))?;
76 let pixel_format = PixelFormat::from_u8(src.read_u8())
77 .ok_or_else(|| invalid_field_err!("PixelFormat", "invalid pixel format"))?;
78 let destination_rectangle = InclusiveRectangle::decode(src)?;
79 let bitmap_data_length = cast_length!("BitmapDataLen", src.read_u32())?;
80
81 ensure_size!(in: src, size: bitmap_data_length);
82 let bitmap_data = src.read_slice(bitmap_data_length).to_vec();
83
84 Ok(Self {
85 surface_id,
86 codec_id,
87 pixel_format,
88 destination_rectangle,
89 bitmap_data,
90 })
91 }
92}
93
94#[derive(Clone, PartialEq, Eq)]
95pub struct WireToSurface2Pdu {
96 pub surface_id: u16,
97 pub codec_id: Codec2Type,
98 pub codec_context_id: u32,
99 pub pixel_format: PixelFormat,
100 pub bitmap_data: Vec<u8>,
101}
102
103impl fmt::Debug for WireToSurface2Pdu {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 f.debug_struct("WireToSurface2Pdu")
106 .field("surface_id", &self.surface_id)
107 .field("codec_id", &self.codec_id)
108 .field("codec_context_id", &self.codec_context_id)
109 .field("pixel_format", &self.pixel_format)
110 .field("bitmap_data_length", &self.bitmap_data.len())
111 .finish()
112 }
113}
114
115impl WireToSurface2Pdu {
116 const NAME: &'static str = "WireToSurface2Pdu";
117
118 const FIXED_PART_SIZE: usize = 2 + 2 + 4 + 1 + 4 ;
119}
120
121impl Encode for WireToSurface2Pdu {
122 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
123 ensure_size!(in: dst, size: self.size());
124
125 dst.write_u16(self.surface_id);
126 dst.write_u16(self.codec_id.to_u16().unwrap());
127 dst.write_u32(self.codec_context_id);
128 dst.write_u8(self.pixel_format.to_u8().unwrap());
129 dst.write_u32(cast_length!("BitmapDataLen", self.bitmap_data.len())?);
130 dst.write_slice(&self.bitmap_data);
131
132 Ok(())
133 }
134
135 fn name(&self) -> &'static str {
136 Self::NAME
137 }
138
139 fn size(&self) -> usize {
140 Self::FIXED_PART_SIZE + self.bitmap_data.len()
141 }
142}
143
144impl<'a> Decode<'a> for WireToSurface2Pdu {
145 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
146 ensure_fixed_part_size!(in: src);
147
148 let surface_id = src.read_u16();
149 let codec_id =
150 Codec2Type::from_u16(src.read_u16()).ok_or_else(|| invalid_field_err!("CodecId", "invalid codec ID"))?;
151 let codec_context_id = src.read_u32();
152 let pixel_format = PixelFormat::from_u8(src.read_u8())
153 .ok_or_else(|| invalid_field_err!("PixelFormat", "invalid pixel format"))?;
154 let bitmap_data_length = cast_length!("BitmapDataLen", src.read_u32())?;
155
156 ensure_size!(in: src, size: bitmap_data_length);
157 let bitmap_data = src.read_slice(bitmap_data_length).to_vec();
158
159 Ok(Self {
160 surface_id,
161 codec_id,
162 codec_context_id,
163 pixel_format,
164 bitmap_data,
165 })
166 }
167}
168
169#[derive(Debug, Clone, PartialEq, Eq)]
170pub struct DeleteEncodingContextPdu {
171 pub surface_id: u16,
172 pub codec_context_id: u32,
173}
174
175impl DeleteEncodingContextPdu {
176 const NAME: &'static str = "DeleteEncodingContextPdu";
177
178 const FIXED_PART_SIZE: usize = 2 + 4 ;
179}
180
181impl Encode for DeleteEncodingContextPdu {
182 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
183 ensure_fixed_part_size!(in: dst);
184
185 dst.write_u16(self.surface_id);
186 dst.write_u32(self.codec_context_id);
187
188 Ok(())
189 }
190
191 fn name(&self) -> &'static str {
192 Self::NAME
193 }
194
195 fn size(&self) -> usize {
196 Self::FIXED_PART_SIZE
197 }
198}
199
200impl<'a> Decode<'a> for DeleteEncodingContextPdu {
201 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
202 ensure_fixed_part_size!(in: src);
203
204 let surface_id = src.read_u16();
205 let codec_context_id = src.read_u32();
206
207 Ok(Self {
208 surface_id,
209 codec_context_id,
210 })
211 }
212}
213
214#[derive(Debug, Clone, PartialEq, Eq)]
215pub struct SolidFillPdu {
216 pub surface_id: u16,
217 pub fill_pixel: Color,
218 pub rectangles: Vec<InclusiveRectangle>,
219}
220
221impl SolidFillPdu {
222 const NAME: &'static str = "CacheToSurfacePdu";
223
224 const FIXED_PART_SIZE: usize = 2 + Color::FIXED_PART_SIZE + 2 ;
225}
226
227impl Encode for SolidFillPdu {
228 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
229 ensure_size!(in: dst, size: self.size());
230
231 dst.write_u16(self.surface_id);
232 self.fill_pixel.encode(dst)?;
233 dst.write_u16(self.rectangles.len() as u16);
234
235 for rectangle in self.rectangles.iter() {
236 rectangle.encode(dst)?;
237 }
238
239 Ok(())
240 }
241
242 fn name(&self) -> &'static str {
243 Self::NAME
244 }
245
246 fn size(&self) -> usize {
247 Self::FIXED_PART_SIZE + self.rectangles.iter().map(|r| r.size()).sum::<usize>()
248 }
249}
250
251impl<'a> Decode<'a> for SolidFillPdu {
252 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
253 ensure_fixed_part_size!(in: src);
254
255 let surface_id = src.read_u16();
256 let fill_pixel = Color::decode(src)?;
257 let rectangles_count = src.read_u16();
258
259 ensure_size!(in: src, size: usize::from(rectangles_count) * InclusiveRectangle::FIXED_PART_SIZE);
260 let rectangles = (0..rectangles_count)
261 .map(|_| InclusiveRectangle::decode(src))
262 .collect::<Result<_, _>>()?;
263
264 Ok(Self {
265 surface_id,
266 fill_pixel,
267 rectangles,
268 })
269 }
270}
271
272#[derive(Debug, Clone, PartialEq, Eq)]
273pub struct SurfaceToSurfacePdu {
274 pub source_surface_id: u16,
275 pub destination_surface_id: u16,
276 pub source_rectangle: InclusiveRectangle,
277 pub destination_points: Vec<Point>,
278}
279
280impl SurfaceToSurfacePdu {
281 const NAME: &'static str = "SurfaceToSurfacePdu";
282
283 const FIXED_PART_SIZE: usize = 2 + 2 + InclusiveRectangle::FIXED_PART_SIZE + 2 ;
284}
285
286impl Encode for SurfaceToSurfacePdu {
287 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
288 ensure_size!(in: dst, size: self.size());
289
290 dst.write_u16(self.source_surface_id);
291 dst.write_u16(self.destination_surface_id);
292 self.source_rectangle.encode(dst)?;
293
294 dst.write_u16(cast_length!("DestinationPoints", self.destination_points.len())?);
295 for rectangle in self.destination_points.iter() {
296 rectangle.encode(dst)?;
297 }
298
299 Ok(())
300 }
301
302 fn name(&self) -> &'static str {
303 Self::NAME
304 }
305
306 fn size(&self) -> usize {
307 Self::FIXED_PART_SIZE + self.destination_points.iter().map(|r| r.size()).sum::<usize>()
308 }
309}
310
311impl<'a> Decode<'a> for SurfaceToSurfacePdu {
312 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
313 ensure_fixed_part_size!(in: src);
314
315 let source_surface_id = src.read_u16();
316 let destination_surface_id = src.read_u16();
317 let source_rectangle = InclusiveRectangle::decode(src)?;
318 let destination_points_count = src.read_u16();
319
320 let destination_points = (0..destination_points_count)
321 .map(|_| Point::decode(src))
322 .collect::<Result<_, _>>()?;
323
324 Ok(Self {
325 source_surface_id,
326 destination_surface_id,
327 source_rectangle,
328 destination_points,
329 })
330 }
331}
332
333#[derive(Debug, Clone, PartialEq, Eq)]
334pub struct SurfaceToCachePdu {
335 pub surface_id: u16,
336 pub cache_key: u64,
337 pub cache_slot: u16,
338 pub source_rectangle: InclusiveRectangle,
339}
340
341impl SurfaceToCachePdu {
342 const NAME: &'static str = "SurfaceToCachePdu";
343
344 const FIXED_PART_SIZE: usize = 2 + 8 + 2 + InclusiveRectangle::FIXED_PART_SIZE ;
345}
346
347impl Encode for SurfaceToCachePdu {
348 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
349 ensure_fixed_part_size!(in: dst);
350
351 dst.write_u16(self.surface_id);
352 dst.write_u64(self.cache_key);
353 dst.write_u16(self.cache_slot);
354 self.source_rectangle.encode(dst)?;
355
356 Ok(())
357 }
358
359 fn name(&self) -> &'static str {
360 Self::NAME
361 }
362
363 fn size(&self) -> usize {
364 Self::FIXED_PART_SIZE
365 }
366}
367
368impl<'a> Decode<'a> for SurfaceToCachePdu {
369 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
370 ensure_fixed_part_size!(in: src);
371
372 let surface_id = src.read_u16();
373 let cache_key = src.read_u64();
374 let cache_slot = src.read_u16();
375 let source_rectangle = InclusiveRectangle::decode(src)?;
376
377 Ok(Self {
378 surface_id,
379 cache_key,
380 cache_slot,
381 source_rectangle,
382 })
383 }
384}
385
386#[derive(Debug, Clone, PartialEq, Eq)]
387pub struct CacheToSurfacePdu {
388 pub cache_slot: u16,
389 pub surface_id: u16,
390 pub destination_points: Vec<Point>,
391}
392
393impl CacheToSurfacePdu {
394 const NAME: &'static str = "CacheToSurfacePdu";
395
396 const FIXED_PART_SIZE: usize = 2 + 2 + 2 ;
397}
398
399impl Encode for CacheToSurfacePdu {
400 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
401 ensure_size!(in: dst, size: self.size());
402
403 dst.write_u16(self.cache_slot);
404 dst.write_u16(self.surface_id);
405 dst.write_u16(cast_length!("npoints", self.destination_points.len())?);
406 for point in self.destination_points.iter() {
407 point.encode(dst)?;
408 }
409
410 Ok(())
411 }
412
413 fn name(&self) -> &'static str {
414 Self::NAME
415 }
416
417 fn size(&self) -> usize {
418 Self::FIXED_PART_SIZE + self.destination_points.iter().map(|p| p.size()).sum::<usize>()
419 }
420}
421
422impl<'de> Decode<'de> for CacheToSurfacePdu {
423 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
424 ensure_fixed_part_size!(in: src);
425
426 let cache_slot = src.read_u16();
427 let surface_id = src.read_u16();
428 let destination_points_count = src.read_u16();
429
430 let destination_points = (0..destination_points_count)
431 .map(|_| decode_cursor(src))
432 .collect::<Result<_, _>>()?;
433
434 Ok(Self {
435 cache_slot,
436 surface_id,
437 destination_points,
438 })
439 }
440}
441
442#[derive(Debug, Clone, PartialEq, Eq)]
443pub struct CreateSurfacePdu {
444 pub surface_id: u16,
445 pub width: u16,
446 pub height: u16,
447 pub pixel_format: PixelFormat,
448}
449
450impl CreateSurfacePdu {
451 const NAME: &'static str = "CreateSurfacePdu";
452
453 const FIXED_PART_SIZE: usize = 2 + 2 + 2 + 1 ;
454}
455
456impl Encode for CreateSurfacePdu {
457 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
458 ensure_fixed_part_size!(in: dst);
459
460 dst.write_u16(self.surface_id);
461 dst.write_u16(self.width);
462 dst.write_u16(self.height);
463 dst.write_u8(self.pixel_format.to_u8().unwrap());
464
465 Ok(())
466 }
467
468 fn name(&self) -> &'static str {
469 Self::NAME
470 }
471
472 fn size(&self) -> usize {
473 Self::FIXED_PART_SIZE
474 }
475}
476
477impl<'a> Decode<'a> for CreateSurfacePdu {
478 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
479 ensure_fixed_part_size!(in: src);
480
481 let surface_id = src.read_u16();
482 let width = src.read_u16();
483 let height = src.read_u16();
484 let pixel_format = PixelFormat::from_u8(src.read_u8())
485 .ok_or_else(|| invalid_field_err!("pixelFormat", "invalid pixel format"))?;
486
487 Ok(Self {
488 surface_id,
489 width,
490 height,
491 pixel_format,
492 })
493 }
494}
495
496#[derive(Debug, Clone, PartialEq, Eq)]
497pub struct DeleteSurfacePdu {
498 pub surface_id: u16,
499}
500
501impl DeleteSurfacePdu {
502 const NAME: &'static str = "DeleteSurfacePdu";
503
504 const FIXED_PART_SIZE: usize = 2 ;
505}
506
507impl Encode for DeleteSurfacePdu {
508 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
509 ensure_fixed_part_size!(in: dst);
510
511 dst.write_u16(self.surface_id);
512
513 Ok(())
514 }
515
516 fn name(&self) -> &'static str {
517 Self::NAME
518 }
519
520 fn size(&self) -> usize {
521 Self::FIXED_PART_SIZE
522 }
523}
524
525impl<'a> Decode<'a> for DeleteSurfacePdu {
526 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
527 ensure_fixed_part_size!(in: src);
528
529 let surface_id = src.read_u16();
530
531 Ok(Self { surface_id })
532 }
533}
534
535#[derive(Debug, Clone, PartialEq, Eq)]
536pub struct ResetGraphicsPdu {
537 pub width: u32,
538 pub height: u32,
539 pub monitors: Vec<Monitor>,
540}
541
542impl ResetGraphicsPdu {
543 const NAME: &'static str = "ResetGraphicsPdu";
544
545 const FIXED_PART_SIZE: usize = 4 + 4 ;
546}
547
548impl Encode for ResetGraphicsPdu {
549 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
550 ensure_size!(in: dst, size: self.size());
551
552 dst.write_u32(self.width);
553 dst.write_u32(self.height);
554 dst.write_u32(cast_length!("nMonitors", self.monitors.len())?);
555
556 for monitor in self.monitors.iter() {
557 monitor.encode(dst)?;
558 }
559
560 write_padding!(dst, self.padding_size());
561
562 Ok(())
563 }
564
565 fn name(&self) -> &'static str {
566 Self::NAME
567 }
568
569 fn size(&self) -> usize {
570 RESET_GRAPHICS_PDU_SIZE - RDP_GFX_HEADER_SIZE
571 }
572}
573
574impl<'a> Decode<'a> for ResetGraphicsPdu {
575 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
576 ensure_fixed_part_size!(in: src);
577
578 let width = src.read_u32();
579 if width > MAX_RESET_GRAPHICS_WIDTH_HEIGHT {
580 return Err(invalid_field_err!("width", "invalid reset graphics width"));
581 }
582
583 let height = src.read_u32();
584 if height > MAX_RESET_GRAPHICS_WIDTH_HEIGHT {
585 return Err(invalid_field_err!("height", "invalid reset graphics height"));
586 }
587
588 let monitor_count = src.read_u32();
589 if monitor_count > MONITOR_COUNT_MAX {
590 return Err(invalid_field_err!("height", "invalid reset graphics monitor count"));
591 }
592
593 let monitors = (0..monitor_count)
594 .map(|_| Monitor::decode(src))
595 .collect::<Result<Vec<_>, _>>()?;
596
597 let pdu = Self {
598 width,
599 height,
600 monitors,
601 };
602
603 read_padding!(src, pdu.padding_size());
604
605 Ok(pdu)
606 }
607}
608
609impl ResetGraphicsPdu {
610 fn padding_size(&self) -> usize {
611 RESET_GRAPHICS_PDU_SIZE - RDP_GFX_HEADER_SIZE - 12 - self.monitors.iter().map(|m| m.size()).sum::<usize>()
612 }
613}
614
615#[derive(Debug, Clone, PartialEq, Eq)]
616pub struct MapSurfaceToOutputPdu {
617 pub surface_id: u16,
618 pub output_origin_x: u32,
619 pub output_origin_y: u32,
620}
621
622impl MapSurfaceToOutputPdu {
623 const NAME: &'static str = "MapSurfaceToOutputPdu";
624
625 const FIXED_PART_SIZE: usize = 2 + 2 + 4 + 4 ;
626}
627
628impl Encode for MapSurfaceToOutputPdu {
629 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
630 ensure_fixed_part_size!(in: dst);
631
632 dst.write_u16(self.surface_id);
633 dst.write_u16(0); dst.write_u32(self.output_origin_x);
635 dst.write_u32(self.output_origin_y);
636
637 Ok(())
638 }
639
640 fn name(&self) -> &'static str {
641 Self::NAME
642 }
643
644 fn size(&self) -> usize {
645 Self::FIXED_PART_SIZE
646 }
647}
648
649impl<'a> Decode<'a> for MapSurfaceToOutputPdu {
650 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
651 ensure_fixed_part_size!(in: src);
652
653 let surface_id = src.read_u16();
654 let _reserved = src.read_u16();
655 let output_origin_x = src.read_u32();
656 let output_origin_y = src.read_u32();
657
658 Ok(Self {
659 surface_id,
660 output_origin_x,
661 output_origin_y,
662 })
663 }
664}
665
666#[derive(Debug, Clone, PartialEq, Eq)]
667pub struct MapSurfaceToScaledOutputPdu {
668 pub surface_id: u16,
669 pub output_origin_x: u32,
670 pub output_origin_y: u32,
671 pub target_width: u32,
672 pub target_height: u32,
673}
674
675impl MapSurfaceToScaledOutputPdu {
676 const NAME: &'static str = "MapSurfaceToScaledOutputPdu";
677
678 const FIXED_PART_SIZE: usize = 2 + 2 + 4 + 4 + 4 + 4 ;
679}
680
681impl Encode for MapSurfaceToScaledOutputPdu {
682 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
683 ensure_fixed_part_size!(in: dst);
684
685 dst.write_u16(self.surface_id);
686 dst.write_u16(0); dst.write_u32(self.output_origin_x);
688 dst.write_u32(self.output_origin_y);
689 dst.write_u32(self.target_width);
690 dst.write_u32(self.target_height);
691
692 Ok(())
693 }
694
695 fn name(&self) -> &'static str {
696 Self::NAME
697 }
698
699 fn size(&self) -> usize {
700 Self::FIXED_PART_SIZE
701 }
702}
703
704impl<'a> Decode<'a> for MapSurfaceToScaledOutputPdu {
705 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
706 ensure_fixed_part_size!(in: src);
707
708 let surface_id = src.read_u16();
709 let _reserved = src.read_u16();
710 let output_origin_x = src.read_u32();
711 let output_origin_y = src.read_u32();
712 let target_width = src.read_u32();
713 let target_height = src.read_u32();
714
715 Ok(Self {
716 surface_id,
717 output_origin_x,
718 output_origin_y,
719 target_width,
720 target_height,
721 })
722 }
723}
724
725#[derive(Debug, Clone, PartialEq, Eq)]
726pub struct MapSurfaceToScaledWindowPdu {
727 pub surface_id: u16,
728 pub window_id: u64,
729 pub mapped_width: u32,
730 pub mapped_height: u32,
731 pub target_width: u32,
732 pub target_height: u32,
733}
734
735impl MapSurfaceToScaledWindowPdu {
736 const NAME: &'static str = "MapSurfaceToScaledWindowPdu";
737
738 const FIXED_PART_SIZE: usize = 2 + 8 + 4 + 4 + 4 + 4 ;
739}
740
741impl Encode for MapSurfaceToScaledWindowPdu {
742 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
743 dst.write_u16(self.surface_id);
744 dst.write_u64(self.window_id); dst.write_u32(self.mapped_width);
746 dst.write_u32(self.mapped_height);
747 dst.write_u32(self.target_width);
748 dst.write_u32(self.target_height);
749
750 Ok(())
751 }
752
753 fn name(&self) -> &'static str {
754 Self::NAME
755 }
756
757 fn size(&self) -> usize {
758 Self::FIXED_PART_SIZE
759 }
760}
761
762impl<'a> Decode<'a> for MapSurfaceToScaledWindowPdu {
763 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
764 ensure_fixed_part_size!(in: src);
765
766 let surface_id = src.read_u16();
767 let window_id = src.read_u64();
768 let mapped_width = src.read_u32();
769 let mapped_height = src.read_u32();
770 let target_width = src.read_u32();
771 let target_height = src.read_u32();
772
773 Ok(Self {
774 surface_id,
775 window_id,
776 mapped_width,
777 mapped_height,
778 target_width,
779 target_height,
780 })
781 }
782}
783
784#[derive(Debug, Clone, PartialEq, Eq)]
785pub struct EvictCacheEntryPdu {
786 pub cache_slot: u16,
787}
788
789impl EvictCacheEntryPdu {
790 const NAME: &'static str = "EvictCacheEntryPdu";
791
792 const FIXED_PART_SIZE: usize = 2;
793}
794
795impl Encode for EvictCacheEntryPdu {
796 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
797 ensure_fixed_part_size!(in: dst);
798
799 dst.write_u16(self.cache_slot);
800
801 Ok(())
802 }
803
804 fn name(&self) -> &'static str {
805 Self::NAME
806 }
807
808 fn size(&self) -> usize {
809 Self::FIXED_PART_SIZE
810 }
811}
812
813impl<'a> Decode<'a> for EvictCacheEntryPdu {
814 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
815 ensure_fixed_part_size!(in: src);
816
817 let cache_slot = src.read_u16();
818
819 Ok(Self { cache_slot })
820 }
821}
822
823#[derive(Debug, Clone, PartialEq, Eq)]
824pub struct StartFramePdu {
825 pub timestamp: Timestamp,
826 pub frame_id: u32,
827}
828
829impl StartFramePdu {
830 const NAME: &'static str = "StartFramePdu";
831
832 const FIXED_PART_SIZE: usize = Timestamp::FIXED_PART_SIZE + 4 ;
833}
834
835impl Encode for StartFramePdu {
836 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
837 ensure_fixed_part_size!(in: dst);
838
839 self.timestamp.encode(dst)?;
840 dst.write_u32(self.frame_id);
841
842 Ok(())
843 }
844
845 fn name(&self) -> &'static str {
846 Self::NAME
847 }
848
849 fn size(&self) -> usize {
850 Self::FIXED_PART_SIZE
851 }
852}
853
854impl<'a> Decode<'a> for StartFramePdu {
855 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
856 ensure_fixed_part_size!(in: src);
857
858 let timestamp = Timestamp::decode(src)?;
859 let frame_id = src.read_u32();
860
861 Ok(Self { timestamp, frame_id })
862 }
863}
864
865#[derive(Debug, Clone, PartialEq, Eq)]
866pub struct EndFramePdu {
867 pub frame_id: u32,
868}
869
870impl EndFramePdu {
871 const NAME: &'static str = "EndFramePdu";
872
873 const FIXED_PART_SIZE: usize = 4;
874}
875
876impl Encode for EndFramePdu {
877 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
878 ensure_fixed_part_size!(in: dst);
879
880 dst.write_u32(self.frame_id);
881
882 Ok(())
883 }
884
885 fn name(&self) -> &'static str {
886 Self::NAME
887 }
888
889 fn size(&self) -> usize {
890 Self::FIXED_PART_SIZE
891 }
892}
893
894impl<'a> Decode<'a> for EndFramePdu {
895 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
896 ensure_fixed_part_size!(in: src);
897
898 let frame_id = src.read_u32();
899
900 Ok(Self { frame_id })
901 }
902}
903
904#[derive(Debug, Clone, PartialEq, Eq)]
905pub struct CapabilitiesConfirmPdu(pub CapabilitySet);
906
907impl CapabilitiesConfirmPdu {
908 const NAME: &'static str = "CapabilitiesConfirmPdu";
909}
910
911impl Encode for CapabilitiesConfirmPdu {
912 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
913 self.0.encode(dst)
914 }
915
916 fn name(&self) -> &'static str {
917 Self::NAME
918 }
919
920 fn size(&self) -> usize {
921 self.0.size()
922 }
923}
924
925impl<'a> Decode<'a> for CapabilitiesConfirmPdu {
926 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
927 let capability_set = CapabilitySet::decode(src)?;
928
929 Ok(Self(capability_set))
930 }
931}
932
933#[repr(u16)]
934#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
935pub enum Codec1Type {
936 Uncompressed = 0x0,
937 RemoteFx = 0x3,
938 ClearCodec = 0x8,
939 Planar = 0xa,
940 Avc420 = 0xb,
941 Alpha = 0xc,
942 Avc444 = 0xe,
943 Avc444v2 = 0xf,
944}
945
946#[repr(u16)]
947#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
948pub enum Codec2Type {
949 RemoteFxProgressive = 0x9,
950}
951
952#[repr(u8)]
953#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
954pub enum PixelFormat {
955 XRgb = 0x20,
956 ARgb = 0x21,
957}
958
959#[derive(Debug, Copy, Clone, PartialEq, Eq)]
960pub struct Timestamp {
961 pub milliseconds: u16,
962 pub seconds: u8,
963 pub minutes: u8,
964 pub hours: u16,
965}
966
967impl Timestamp {
968 const NAME: &'static str = "Timestamp";
969
970 const FIXED_PART_SIZE: usize = 4;
971}
972
973impl Encode for Timestamp {
974 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
975 ensure_fixed_part_size!(in: dst);
976
977 let mut timestamp: u32 = 0;
978
979 timestamp.set_bits(..10, u32::from(self.milliseconds));
980 timestamp.set_bits(10..16, u32::from(self.seconds));
981 timestamp.set_bits(16..22, u32::from(self.minutes));
982 timestamp.set_bits(22.., u32::from(self.hours));
983
984 dst.write_u32(timestamp);
985
986 Ok(())
987 }
988
989 fn name(&self) -> &'static str {
990 Self::NAME
991 }
992
993 fn size(&self) -> usize {
994 Self::FIXED_PART_SIZE
995 }
996}
997
998impl<'a> Decode<'a> for Timestamp {
999 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
1000 ensure_fixed_part_size!(in: src);
1001
1002 let timestamp = src.read_u32();
1003
1004 let milliseconds = timestamp.get_bits(..10) as u16;
1005 let seconds = timestamp.get_bits(10..16) as u8;
1006 let minutes = timestamp.get_bits(16..22) as u8;
1007 let hours = timestamp.get_bits(22..) as u16;
1008
1009 Ok(Self {
1010 milliseconds,
1011 seconds,
1012 minutes,
1013 hours,
1014 })
1015 }
1016}