ironrdp_pdu/rdp/vc/dvc/gfx/graphics_messages/
server.rs

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 /* SurfaceId */ + 2 /* CodecId */ + 1 /* PixelFormat */ + InclusiveRectangle::FIXED_PART_SIZE /* Dest */ + 4 /* BitmapDataLen */;
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 /* SurfaceId */ + 2 /* CodecId */ + 4 /* ContextId */ + 1 /* PixelFormat */ + 4 /* BitmapDataLen */;
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 /* SurfaceId */ + 4 /* CodecContextId */;
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 /* SurfaceId */ + Color::FIXED_PART_SIZE /* Color */ + 2 /* RectCount */;
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 /* SourceId */ + 2 /* DestId */ + InclusiveRectangle::FIXED_PART_SIZE /* SourceRect */ + 2 /* DestPointsCount */;
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 /* SurfaceId */ + 8 /* CacheKey */ + 2 /* CacheSlot */ + InclusiveRectangle::FIXED_PART_SIZE /* SourceRect */;
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 /* cache_slot */ + 2 /* surface_id */ + 2 /* npoints */;
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 /* SurfaceId */ + 2 /* Width */ + 2 /* Height */ + 1 /* PixelFormat */;
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 /* SurfaceId */;
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 /* Width */ + 4 /* Height */;
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 /* surfaceId */ + 2 /* reserved */ + 4 /* OutOriginX */ + 4 /* OutOriginY */;
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); // reserved
634        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 /* SurfaceId */ + 2 /* reserved */ + 4 /* OutOriginX */ + 4 /* OutOriginY */ + 4 /* TargetWidth */ + 4 /* TargetHeight */;
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); // reserved
687        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 /* SurfaceId */ + 8 /* WindowId */ + 4 /* MappedWidth */ + 4 /* MappedHeight */ + 4 /* TargetWidth */ + 4 /* TargetHeight */;
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); // reserved
745        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 /* FrameId */;
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}