justshow/x11/
replies.rs

1use crate::x11::{
2    connection::XConnection,
3    error::Error,
4    requests::Timestamp,
5    requests::{opcodes, KeyCode},
6    utils::pad,
7    AtomId, ColormapId, ListOfStr, OrNone, ResourceId, VisualId, WindowId,
8};
9
10pub trait XReply: Sized {
11    fn from_reply(reply: SomeReply) -> Option<Self>;
12}
13
14macro_rules! impl_xreply_go {
15    ($inner:ty, $wrapper:path) => {
16        impl XReply for $inner {
17            fn from_reply(reply: SomeReply) -> Option<Self> {
18                match reply {
19                    $wrapper(r) => Some(r),
20                    _ => None,
21                }
22            }
23        }
24    };
25}
26
27macro_rules! impl_xreply {
28    ($t:tt) => {
29        impl_xreply_go!($t, SomeReply::$t);
30    };
31}
32
33/*
34     1                         family
35           0         Internet
36           1         DECnet
37           2         Chaos
38           5         ServerInterpreted
39           6         InternetV6
40     1                         unused
41     2      n                  length of address
42     n      LISTofBYTE         address
43     p                         unused, p=pad(n)
44
45*/
46#[derive(Debug, Clone)]
47pub enum HostFamily {
48    Internet = 0,
49    DECnet = 1,
50    Chaos = 2,
51    ServerImplemented = 5,
52    InternetV6 = 6,
53}
54
55impl HostFamily {
56    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
57        match conn.read_u8()? {
58            0 => Ok(Self::Internet),
59            1 => Ok(Self::DECnet),
60            2 => Ok(Self::Chaos),
61            5 => Ok(Self::ServerImplemented),
62            6 => Ok(Self::InternetV6),
63            _ => Err(Error::InvalidResponse),
64        }
65    }
66}
67
68#[derive(Debug, Clone)]
69pub struct Host {
70    pub family: HostFamily,
71    pub address: Vec<u8>,
72}
73
74impl Host {
75    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
76        let family = HostFamily::from_le_bytes(conn)?;
77        let _unused = conn.read_u8()?;
78        let address_length = conn.read_le_u16()?;
79        let address = conn.read_n_bytes(address_length as usize)?;
80        drop(conn.drain(pad(address_length as usize))?);
81        Ok(Self { family, address })
82    }
83}
84
85/*
86GetWindowAttributes
8788     1     1                               Reply
89     1                                     backing-store
90          0     NotUseful
91          1     WhenMapped
92          2     Always
93     2     CARD16                          sequence number
94     4     3                               reply length
95     4     VISUALID                        visual
96     2                                     class
97          1     InputOutput
98          2     InputOnly
99     1     BITGRAVITY                      bit-gravity
100     1     WINGRAVITY                      win-gravity
101     4     CARD32                          backing-planes
102     4     CARD32                          backing-pixel
103     1     BOOL                            save-under
104     1     BOOL                            map-is-installed
105     1                                     map-state
106          0     Unmapped
107          1     Unviewable
108          2     Viewable
109     1     BOOL                            override-redirect
110     4     COLORMAP                        colormap
111          0     None
112     4     SETofEVENT                      all-event-masks
113     4     SETofEVENT                      your-event-mask
114     2     SETofDEVICEEVENT                do-not-propagate-mask
115     2                                     unused
116*/
117
118#[derive(Debug, Clone)]
119pub struct GetWindowAttributes {
120    backing_store: u8,
121    visual_id: u32,
122    class: u16,
123    bit_gravity: u8,
124    win_gravity: u8,
125    backing_planes: u32,
126    backing_pixel: u32,
127    save_under: bool,
128    map_is_installed: bool,
129    map_state: u8,
130    override_redirect: bool,
131    colormap: u32,
132    all_even_masks: u32,
133    your_even_masks: u32,
134    do_not_propagate_mask: u16,
135}
136
137impl GetWindowAttributes {
138    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
139        let backing_store = conn.read_u8()?;
140        let _sequence_code = conn.read_le_u16()?;
141        let _reply_length = conn.read_le_u32()?;
142        let visual_id = conn.read_le_u32()?;
143        let class = conn.read_le_u16()?;
144        let bit_gravity = conn.read_u8()?;
145        let win_gravity = conn.read_u8()?;
146        let backing_planes = conn.read_le_u32()?;
147        let backing_pixel = conn.read_le_u32()?;
148        let save_under = conn.read_bool()?;
149        let map_is_installed = conn.read_bool()?;
150        let map_state = conn.read_u8()?;
151        let override_redirect = conn.read_bool()?;
152        let colormap = conn.read_le_u32()?;
153        let all_even_masks = conn.read_le_u32()?;
154        let your_even_masks = conn.read_le_u32()?;
155        let do_not_propagate_mask = conn.read_le_u16()?;
156        let _unused = conn.read_le_u16()?;
157
158        Ok(Self {
159            backing_store,
160            visual_id,
161            class,
162            bit_gravity,
163            win_gravity,
164            backing_planes,
165            backing_pixel,
166            save_under,
167            map_is_installed,
168            map_state,
169            override_redirect,
170            colormap,
171            all_even_masks,
172            your_even_masks,
173            do_not_propagate_mask,
174        })
175    }
176}
177
178impl_xreply!(GetWindowAttributes);
179
180/*
181GetGeometry
182183     1     1                               Reply
184     1     CARD8                           depth
185     2     CARD16                          sequence number
186     4     0                               reply length
187     4     WINDOW                          root
188     2     INT16                           x
189     2     INT16                           y
190     2     CARD16                          width
191     2     CARD16                          height
192     2     CARD16                          border-width
193     10                                    unused
194*/
195#[derive(Debug, Clone)]
196pub struct GetGeometry {
197    pub depth: u8,
198    pub root: WindowId,
199    pub x: i16,
200    pub y: i16,
201    pub width: u16,
202    pub height: u16,
203    pub border_width: u16,
204}
205
206impl GetGeometry {
207    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
208        let depth = conn.read_u8()?;
209        let _sequence_code = conn.read_le_u16()?;
210        let _reply_length = conn.read_le_u32()?;
211        let root = WindowId(ResourceId {
212            value: conn.read_le_u32()?,
213        });
214        let x = conn.read_le_i16()?;
215        let y = conn.read_le_i16()?;
216        let width = conn.read_le_u16()?;
217        let height = conn.read_le_u16()?;
218        let border_width = conn.read_le_u16()?;
219        conn.drain(10)?;
220
221        Ok(Self {
222            depth,
223            root,
224            x,
225            y,
226            width,
227            height,
228            border_width,
229        })
230    }
231}
232
233impl_xreply!(GetGeometry);
234
235/*
236QueryTree
237238     1     1                               Reply
239     1                                     unused
240     2     CARD16                          sequence number
241     4     n                               reply length
242     4     WINDOW                          root
243     4     WINDOW                          parent
244          0     None
245     2     n                               number of WINDOWs in children
246     14                                    unused
247     4n     LISTofWINDOW                   children
248*/
249
250#[derive(Debug, Clone)]
251pub struct QueryTree {
252    pub root: WindowId,
253    pub parent: OrNone<WindowId>,
254    pub children: Vec<WindowId>,
255}
256
257impl QueryTree {
258    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
259        let _unused = conn.read_u8()?;
260        let _sequence_code = conn.read_le_u16()?;
261        let _reply_length = conn.read_le_u32()?;
262        let root = WindowId(ResourceId {
263            value: conn.read_le_u32()?,
264        });
265        let parent = OrNone(WindowId(ResourceId {
266            value: conn.read_le_u32()?,
267        }));
268        let children_count = conn.read_le_u16()?;
269        drop(conn.drain(14)?);
270        let mut children = Vec::with_capacity(children_count as usize);
271        for _ in 0..children_count {
272            let child = WindowId(ResourceId {
273                value: conn.read_le_u32()?,
274            });
275            children.push(child);
276        }
277
278        Ok(Self {
279            root,
280            parent,
281            children,
282        })
283    }
284}
285
286impl_xreply!(QueryTree);
287
288/*
289InternAtom
290291     1     1                               Reply
292     1                                     unused
293     2     CARD16                          sequence number
294     4     0                               reply length
295     4     ATOM                            atom
296           0     None
297     20                                    unused
298*/
299
300#[derive(Debug, Clone)]
301pub struct InternAtom {
302    pub atom: AtomId,
303}
304
305impl InternAtom {
306    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
307        let _unused = conn.read_u8()?;
308        let _sequence_code = conn.read_le_u16()?;
309        let _reply_length = conn.read_le_u32()?;
310        let atom = AtomId::from(conn.read_le_u32()?);
311        drop(conn.drain(20)?);
312
313        Ok(Self { atom })
314    }
315}
316
317impl_xreply!(InternAtom);
318
319/*
320GetAtomName
321322     1     1                               Reply
323     1                                     unused
324     2     CARD16                          sequence number
325     4     (n+p)/4                         reply length
326     2     n                               length of name
327     22                                    unused
328     n     STRING8                         name
329     p                                     unused, p=pad(n)
330*/
331
332#[derive(Debug, Clone)]
333pub struct GetAtomName {
334    pub name: Vec<u8>,
335}
336
337impl GetAtomName {
338    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
339        let _unused = conn.read_u8()?;
340        let _sequence_code = conn.read_le_u16()?;
341        let _reply_length = conn.read_le_u32()?;
342        let name_length = conn.read_le_u16()? as usize;
343        drop(conn.drain(22)?);
344        let name = conn.read_n_bytes(name_length)?;
345        drop(conn.drain(pad(name_length))?);
346
347        Ok(Self { name })
348    }
349}
350
351impl_xreply!(GetAtomName);
352
353/*
354GetProperty
355356     1     1                               Reply
357     1     CARD8                           format
358     2     CARD16                          sequence number
359     4     (n+p)/4                         reply length
360     4     ATOM                            type
361          0     None
362     4     CARD32                          bytes-after
363     4     CARD32                          length of value in format units
364                    (= 0 for format = 0)
365                    (= n for format = 8)
366                    (= n/2 for format = 16)
367                    (= n/4 for format = 32)
368     12                                    unused
369     n     LISTofBYTE                      value
370                    (n is zero for format = 0)
371                    (n is a multiple of 2 for format = 16)
372                    (n is a multiple of 4 for format = 32)
373     p                                     unused, p=pad(n)
374*/
375
376#[derive(Debug, Clone)]
377pub struct GetProperty {
378    pub format: u8,
379    pub type_: AtomId,
380    pub bytes_after: u32,
381    pub length_of_value: u32,
382    pub value: Vec<u8>,
383}
384
385impl GetProperty {
386    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
387        let format = conn.read_u8()?;
388        let _sequence_code = conn.read_le_u16()?;
389        let _reply_length = conn.read_le_u32()?;
390        let type_ = AtomId::from(conn.read_le_u32()?);
391        let bytes_after = conn.read_le_u32()?;
392        let length_of_value = conn.read_le_u32()?;
393        drop(conn.drain(12)?);
394        let value_length = length_of_value as usize;
395        let value = conn.read_n_bytes(value_length)?;
396        drop(conn.drain(pad(value_length))?);
397
398        Ok(Self {
399            format,
400            type_,
401            bytes_after,
402            length_of_value,
403            value,
404        })
405    }
406}
407
408impl_xreply!(GetProperty);
409
410/*
411ListProperties
412413     1     1                               Reply
414     1                                     unused
415     2     CARD16                          sequence number
416     4     n                               reply length
417     2     n                               number of ATOMs in atoms
418     22                                    unused
419     4n     LISTofATOM                     atoms
420*/
421
422#[derive(Debug, Clone)]
423pub struct ListProperties {
424    pub atoms: Vec<AtomId>,
425}
426
427impl ListProperties {
428    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
429        let _unused = conn.read_u8()?;
430        let _sequence_code = conn.read_le_u16()?;
431        let _reply_length = conn.read_le_u32()?;
432        let atom_count = conn.read_le_u16()?;
433        drop(conn.drain(22)?);
434        let mut atoms = Vec::with_capacity(atom_count as usize);
435        for _ in 0..atom_count {
436            let atom = AtomId::from(conn.read_le_u32()?);
437            atoms.push(atom);
438        }
439
440        Ok(Self { atoms })
441    }
442}
443
444impl_xreply!(ListProperties);
445
446/*
447GetSelectionOwner
448449     1     1                               Reply
450     1                                     unused
451     2     CARD16                          sequence number
452     4     0                               reply length
453     4     WINDOW                          owner
454          0     None
455     20                                    unused
456*/
457
458#[derive(Debug, Clone)]
459pub struct GetSelectionOwner {
460    pub owner: WindowId,
461}
462
463impl GetSelectionOwner {
464    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
465        let _unused = conn.read_u8()?;
466        let _sequence_code = conn.read_le_u16()?;
467        let _reply_length = conn.read_le_u32()?;
468        let owner = WindowId(ResourceId {
469            value: conn.read_le_u32()?,
470        });
471        drop(conn.drain(20)?);
472
473        Ok(Self { owner })
474    }
475}
476
477impl_xreply!(GetSelectionOwner);
478
479/*
480GrabPointer
481482     1     1                               Reply
483     1                                     status
484          0     Success
485          1     AlreadyGrabbed
486          2     InvalidTime
487          3     NotViewable
488          4     Frozen
489     2     CARD16                          sequence number
490     4     0                               reply length
491     24                                    unused
492*/
493
494#[derive(Debug, Clone)]
495pub enum GrabPointerStatus {
496    Success,
497    AlreadyGrabbed,
498    InvalidTime,
499    NotViewable,
500    Frozen,
501}
502
503#[derive(Debug, Clone)]
504pub struct GrabPointer {
505    pub status: GrabPointerStatus,
506}
507
508impl GrabPointer {
509    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
510        let status_code = conn.read_u8()?;
511        let status = match status_code {
512            0 => GrabPointerStatus::Success,
513            1 => GrabPointerStatus::AlreadyGrabbed,
514            2 => GrabPointerStatus::InvalidTime,
515            3 => GrabPointerStatus::NotViewable,
516            4 => GrabPointerStatus::Frozen,
517            _ => return Err(Error::InvalidResponse),
518        };
519        let _sequence_number = conn.read_le_u16()?;
520        drop(conn.drain(4 + 24)?);
521
522        Ok(Self { status })
523    }
524}
525
526impl_xreply!(GrabPointer);
527
528/*
529GrabKeyboard
530531     1     1                               Reply
532     1                                     status
533          0     Success
534          1     AlreadyGrabbed
535          2     InvalidTime
536          3     NotViewable
537          4     Frozen
538     2     CARD16                          sequence number
539     4     0                               reply length
540     24                                    unused
541*/
542
543#[derive(Debug, Clone)]
544pub enum GrabKeyboardStatus {
545    Success,
546    AlreadyGrabbed,
547    InvalidTime,
548    NotViewable,
549    Frozen,
550}
551
552#[derive(Debug, Clone)]
553pub struct GrabKeyboard {
554    pub status: GrabKeyboardStatus,
555}
556
557impl GrabKeyboard {
558    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
559        let status_code = conn.read_u8()?;
560        let status = match status_code {
561            0 => GrabKeyboardStatus::Success,
562            1 => GrabKeyboardStatus::AlreadyGrabbed,
563            2 => GrabKeyboardStatus::InvalidTime,
564            3 => GrabKeyboardStatus::NotViewable,
565            4 => GrabKeyboardStatus::Frozen,
566            _ => return Err(Error::InvalidResponse),
567        };
568        let _sequence_number = conn.read_le_u16()?;
569        drop(conn.drain(4 + 24)?);
570
571        Ok(Self { status })
572    }
573}
574
575impl_xreply!(GrabKeyboard);
576
577/*
578QueryPointer
579580     1     1                               Reply
581     1     BOOL                            same-screen
582     2     CARD16                          sequence number
583     4     0                               reply length
584     4     WINDOW                          root
585     4     WINDOW                          child
586          0     None
587     2     INT16                           root-x
588     2     INT16                           root-y
589     2     INT16                           win-x
590     2     INT16                           win-y
591     2     SETofKEYBUTMASK                 mask
592     6                                     unused
593*/
594
595#[derive(Debug, Clone)]
596pub struct QueryPointer {
597    pub same_screen: bool,
598    pub root: WindowId,
599    pub child: OrNone<WindowId>,
600    pub root_x: i16,
601    pub root_y: i16,
602    pub win_x: i16,
603    pub win_y: i16,
604    pub mask: u16,
605}
606
607impl QueryPointer {
608    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
609        let same_screen = conn.read_bool()?;
610        let _sequence_number = conn.read_le_u16()?;
611        let _reply_length = conn.read_le_u32()?;
612        let root = WindowId(ResourceId {
613            value: conn.read_le_u32()?,
614        });
615        let child = OrNone(WindowId(ResourceId {
616            value: conn.read_le_u32()?,
617        }));
618        let root_x = conn.read_le_i16()?;
619        let root_y = conn.read_le_i16()?;
620        let win_x = conn.read_le_i16()?;
621        let win_y = conn.read_le_i16()?;
622        let mask = conn.read_le_u16()?;
623        drop(conn.drain(6)?);
624
625        Ok(Self {
626            same_screen,
627            root,
628            child,
629            root_x,
630            root_y,
631            win_x,
632            win_y,
633            mask,
634        })
635    }
636}
637
638impl_xreply!(QueryPointer);
639
640/*
641GetMotionEvents
642643     1     1                               Reply
644     1                                     unused
645     2     CARD16                          sequence number
646     4     2n                              reply length
647     4     n                               number of TIMECOORDs in events
648     20                                    unused
649     8n     LISTofTIMECOORD                events
650
651  TIMECOORD
652     4     TIMESTAMP                       time
653     2     INT16                           x
654     2     INT16                           y
655*/
656
657#[derive(Debug, Clone)]
658pub struct TimeCoord {
659    pub time: Timestamp,
660    pub x: i16,
661    pub y: i16,
662}
663
664#[derive(Debug, Clone)]
665pub struct GetMotionEvents {
666    pub events: Vec<TimeCoord>,
667}
668
669impl GetMotionEvents {
670    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
671        let _unused = conn.read_u8()?;
672        let _sequence_number = conn.read_le_u16()?;
673        let _reply_length = conn.read_le_u32()? as usize;
674        let event_count = conn.read_le_u32()? as usize;
675        drop(conn.drain(20)?);
676
677        let mut events = Vec::with_capacity(event_count);
678        for _ in 0..event_count {
679            let time = Timestamp(conn.read_le_u32()?);
680            let x = conn.read_le_i16()?;
681            let y = conn.read_le_i16()?;
682            events.push(TimeCoord { time, x, y });
683        }
684
685        Ok(Self { events })
686    }
687}
688
689impl_xreply!(GetMotionEvents);
690
691/*
692TranslateCoordinates
693694     1     1                               Reply
695     1     BOOL                            same-screen
696     2     CARD16                          sequence number
697     4     0                               reply length
698     4     WINDOW                          child
699          0     None
700     2     INT16                           dst-x
701     2     INT16                           dst-y
702     16                                    unused
703*/
704
705#[derive(Debug, Clone)]
706pub struct TranslateCoordinates {
707    pub same_screen: bool,
708    pub child: WindowId,
709    pub dst_x: i16,
710    pub dst_y: i16,
711}
712
713impl TranslateCoordinates {
714    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
715        let same_screen = conn.read_bool()?;
716        let _sequence_number = conn.read_le_u16()?;
717        let _reply_length = conn.read_le_u32()?;
718        let child = WindowId(ResourceId {
719            value: conn.read_le_u32()?,
720        });
721        let dst_x = conn.read_le_i16()?;
722        let dst_y = conn.read_le_i16()?;
723        drop(conn.drain(16)?);
724
725        Ok(Self {
726            same_screen,
727            child,
728            dst_x,
729            dst_y,
730        })
731    }
732}
733
734impl_xreply!(TranslateCoordinates);
735
736/*
737GetInputFocus
738739     1     1                               Reply
740     1                                     revert-to
741          0     None
742          1     PointerRoot
743          2     Parent
744     2     CARD16                          sequence number
745     4     0                               reply length
746     4     WINDOW                          focus
747          0     None
748          1     PointerRoot
749     20                                    unused
750*/
751
752#[derive(Debug, Clone)]
753pub enum Focus {
754    None,
755    PointerRoot,
756    Window(WindowId),
757}
758
759#[derive(Debug, Clone)]
760pub enum RevertTo {
761    None,
762    PointerRoot,
763    Parent,
764}
765
766#[derive(Debug, Clone)]
767pub struct GetInputFocus {
768    pub revert_to: RevertTo,
769    pub focus: Focus,
770}
771
772impl GetInputFocus {
773    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
774        let revert_to_code = conn.read_u8()?;
775        let revert_to = match revert_to_code {
776            0 => RevertTo::None,
777            1 => RevertTo::PointerRoot,
778            2 => RevertTo::Parent,
779            _ => return Err(Error::InvalidResponse),
780        };
781        let _sequence_number = conn.read_le_u16()?;
782        let _reply_length = conn.read_le_u32()?;
783        let focus_value = conn.read_le_u32()?;
784        let focus = match focus_value {
785            0 => Focus::None,
786            1 => Focus::PointerRoot,
787            wid => Focus::Window(WindowId::from(wid)),
788        };
789        drop(conn.drain(20)?);
790
791        Ok(Self { revert_to, focus })
792    }
793}
794
795impl_xreply!(GetInputFocus);
796
797/*
798QueryKeymap
799800     1     1                               Reply
801     1                                     unused
802     2     CARD16                          sequence number
803     4     2                               reply length
804     32     LISTofCARD8                    keys
805*/
806
807#[derive(Debug, Clone)]
808pub struct QueryKeymap {
809    pub keys: [u8; 32],
810}
811
812impl QueryKeymap {
813    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
814        let _unused = conn.read_u8()?;
815        let _sequence_number = conn.read_le_u16()?;
816        let _reply_length = conn.read_le_u32()?;
817        let mut keys = [0; 32];
818        conn.read_exact(&mut keys)?;
819
820        Ok(Self { keys })
821    }
822}
823
824impl_xreply!(QueryKeymap);
825
826/*
827QueryFont
828829     1     1                               Reply
830     1                                     unused
831     2     CARD16                          sequence number
832     4     7+2n+3m                         reply length
833     12     CHARINFO                       min-bounds
834     4                                     unused
835     12     CHARINFO                       max-bounds
836     4                                     unused
837     2     CARD16                          min-char-or-byte2
838     2     CARD16                          max-char-or-byte2
839     2     CARD16                          default-char
840     2     n                               number of FONTPROPs in properties
841     1                                     draw-direction
842          0     LeftToRight
843          1     RightToLeft
844     1     CARD8                           min-byte1
845     1     CARD8                           max-byte1
846     1     BOOL                            all-chars-exist
847     2     INT16                           font-ascent
848     2     INT16                           font-descent
849     4     m                               number of CHARINFOs in char-infos
850     8n     LISTofFONTPROP                 properties
851     12m     LISTofCHARINFO                char-infos
852
853  FONTPROP
854     4     ATOM                            name
855     4     <32-bits>                       value
856
857  CHARINFO
858     2     INT16                           left-side-bearing
859     2     INT16                           right-side-bearing
860     2     INT16                           character-width
861     2     INT16                           ascent
862     2     INT16                           descent
863     2     CARD16                          attributes
864*/
865
866#[derive(Debug, Clone)]
867pub enum DrawDirection {
868    LeftToRight,
869    RightToLeft,
870}
871
872#[derive(Debug, Clone)]
873pub struct FontProp {
874    pub name: AtomId,
875    pub value: u32,
876}
877
878impl FontProp {
879    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
880        let name = AtomId::from(conn.read_le_u32()?);
881        let value = conn.read_le_u32()?;
882        Ok(Self { name, value })
883    }
884}
885
886#[derive(Debug, Clone)]
887pub struct CharInfo {
888    left_side_bearing: i16,
889    right_side_bearing: i16,
890    character_width: i16,
891    ascent: i16,
892    descent: i16,
893    attributes: u16,
894}
895
896impl CharInfo {
897    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
898        let left_side_bearing = conn.read_le_i16()?;
899        let right_side_bearing = conn.read_le_i16()?;
900        let character_width = conn.read_le_i16()?;
901        let ascent = conn.read_le_i16()?;
902        let descent = conn.read_le_i16()?;
903        let attributes = conn.read_le_u16()?;
904
905        Ok(Self {
906            left_side_bearing,
907            right_side_bearing,
908            character_width,
909            ascent,
910            descent,
911            attributes,
912        })
913    }
914}
915
916#[derive(Debug, Clone)]
917pub struct QueryFont {
918    pub min_bounds: CharInfo,
919    pub max_bounds: CharInfo,
920    pub min_char_or_byte2: u16,
921    pub max_char_or_byte2: u16,
922    pub default_char: u16,
923    pub properties: Vec<FontProp>,
924    pub draw_direction: DrawDirection,
925    pub min_byte1: u8,
926    pub max_byte1: u8,
927    pub all_chars_exist: bool,
928    pub font_ascent: i16,
929    pub font_descent: i16,
930    pub char_infos: Vec<CharInfo>,
931}
932
933impl QueryFont {
934    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
935        let _unused = conn.read_u8()?;
936        let _sequence_number = conn.read_le_u16()?;
937        let _reply_length = conn.read_le_u32()? as usize;
938        let min_bounds = CharInfo::from_le_bytes(conn)?;
939        drop(conn.drain(4)?);
940        let max_bounds = CharInfo::from_le_bytes(conn)?;
941        drop(conn.drain(4)?);
942        let min_char_or_byte2 = conn.read_le_u16()?;
943        let max_char_or_byte2 = conn.read_le_u16()?;
944        let default_char = conn.read_le_u16()?;
945        let properties_count = conn.read_le_u16()?;
946        let draw_direction_code = conn.read_u8()?;
947        let draw_direction = match draw_direction_code {
948            0 => DrawDirection::LeftToRight,
949            1 => DrawDirection::RightToLeft,
950            _ => return Err(Error::InvalidResponse),
951        };
952        let min_byte1 = conn.read_u8()?;
953        let max_byte1 = conn.read_u8()?;
954        let all_chars_exist = conn.read_bool()?;
955        let font_ascent = conn.read_le_i16()?;
956        let font_descent = conn.read_le_i16()?;
957        let char_infos_count = conn.read_le_u32()?;
958
959        let mut properties = Vec::with_capacity(properties_count as usize);
960        for _ in 0..properties_count {
961            let property = FontProp::from_le_bytes(conn)?;
962            properties.push(property);
963        }
964
965        let mut char_infos = Vec::with_capacity(char_infos_count as usize);
966        for _ in 0..char_infos_count {
967            let char_info = CharInfo::from_le_bytes(conn)?;
968            char_infos.push(char_info);
969        }
970
971        Ok(Self {
972            min_bounds,
973            max_bounds,
974            min_char_or_byte2,
975            max_char_or_byte2,
976            default_char,
977            properties,
978            draw_direction,
979            min_byte1,
980            max_byte1,
981            all_chars_exist,
982            font_ascent,
983            font_descent,
984            char_infos,
985        })
986    }
987}
988
989impl_xreply!(QueryFont);
990
991/*
992QueryTextExtents
993994     1     1                               Reply
995     1                                     draw-direction
996          0     LeftToRight
997          1     RightToLeft
998     2     CARD16                          sequence number
999     4     0                               reply length
1000     2     INT16                           font-ascent
1001     2     INT16                           font-descent
1002     2     INT16                           overall-ascent
1003     2     INT16                           overall-descent
1004     4     INT32                           overall-width
1005     4     INT32                           overall-left
1006     4     INT32                           overall-right
1007     4                                     unused
1008*/
1009
1010#[derive(Debug, Clone)]
1011pub struct QueryTextExtents {
1012    pub draw_direction: DrawDirection,
1013    pub font_ascent: i16,
1014    pub font_descent: i16,
1015    pub overall_ascent: i16,
1016    pub overall_descent: i16,
1017    pub overall_width: i32,
1018    pub overall_left: i32,
1019    pub overall_right: i32,
1020}
1021
1022impl QueryTextExtents {
1023    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1024        let draw_direction_code = conn.read_u8()?;
1025        let draw_direction = match draw_direction_code {
1026            0 => DrawDirection::LeftToRight,
1027            1 => DrawDirection::RightToLeft,
1028            _ => return Err(Error::InvalidResponse),
1029        };
1030        let _sequence_number = conn.read_le_u16()?;
1031        let _reply_length = conn.read_le_u32()?;
1032        let font_ascent = conn.read_le_i16()?;
1033        let font_descent = conn.read_le_i16()?;
1034        let overall_ascent = conn.read_le_i16()?;
1035        let overall_descent = conn.read_le_i16()?;
1036        let overall_width = conn.read_le_i32()?;
1037        let overall_left = conn.read_le_i32()?;
1038        let overall_right = conn.read_le_i32()?;
1039        drop(conn.drain(4)?);
1040
1041        Ok(Self {
1042            draw_direction,
1043            font_ascent,
1044            font_descent,
1045            overall_ascent,
1046            overall_descent,
1047            overall_width,
1048            overall_left,
1049            overall_right,
1050        })
1051    }
1052}
1053
1054impl_xreply!(QueryTextExtents);
1055
1056/*
1057ListFonts
10581059     1     1                               Reply
1060     1                                     unused
1061     2     CARD16                          sequence number
1062     4     (n+p)/4                         reply length
1063     2     CARD16                          number of STRs in names
1064     22                                    unused
1065     n     LISTofSTR                       names
1066     p                                     unused, p=pad(n)
1067*/
1068
1069#[derive(Debug, Clone)]
1070pub struct ListFonts {
1071    pub names: ListOfStr,
1072}
1073
1074impl ListFonts {
1075    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1076        let _unused = conn.read_u8()?;
1077        let _sequence_number = conn.read_le_u16()?;
1078        let _reply_length = conn.read_le_u32()?;
1079        let names_count = conn.read_le_u16()?;
1080        drop(conn.drain(22)?);
1081        let names = ListOfStr::from_le_bytes(names_count as usize, conn)?;
1082        let n = names.encoded_len();
1083        drop(conn.drain(pad(n))?);
1084
1085        Ok(Self { names })
1086    }
1087}
1088
1089impl_xreply!(ListFonts);
1090
1091/*
1092ListFontsWithInfo
1093▶ (except for last in series)
1094     1     1                               Reply
1095     1     n                               length of name in bytes
1096     2     CARD16                          sequence number
1097     4     7+2m+(n+p)/4                    reply length
1098     12     CHARINFO                       min-bounds
1099     4                                     unused
1100     12     CHARINFO                       max-bounds
1101     4                                     unused
1102     2     CARD16                          min-char-or-byte2
1103     2     CARD16                          max-char-or-byte2
1104     2     CARD16                          default-char
1105     2     m                               number of FONTPROPs in properties
1106     1                                     draw-direction
1107          0     LeftToRight
1108          1     RightToLeft
1109     1     CARD8                           min-byte1
1110     1     CARD8                           max-byte1
1111     1     BOOL                            all-chars-exist
1112     2     INT16                           font-ascent
1113     2     INT16                           font-descent
1114     4     CARD32                          replies-hint
1115     8m     LISTofFONTPROP                 properties
1116     n     STRING8                         name
1117     p                                     unused, p=pad(n)
1118
1119  FONTPROP
1120     encodings are the same as for QueryFont
1121
1122  CHARINFO
1123     encodings are the same as for QueryFont
1124
1125▶ (last in series)
1126     1     1                               Reply
1127     1     0                               last-reply indicator
1128     2     CARD16                          sequence number
1129     4     7                               reply length
1130     52                                    unused
1131
1132*/
1133
1134#[derive(Debug, Clone)]
1135pub struct ListFontsWithInfoPiece {
1136    pub min_bounds: CharInfo,
1137    pub max_bounds: CharInfo,
1138    pub min_char_or_byte2: u16,
1139    pub max_char_or_byte2: u16,
1140    pub default_char: u16,
1141    pub properties: Vec<FontProp>,
1142    pub draw_direction: DrawDirection,
1143    pub min_byte1: u8,
1144    pub max_byte1: u8,
1145    pub all_chars_exist: bool,
1146    pub font_ascent: i16,
1147    pub font_descent: i16,
1148    pub name: Vec<u8>,
1149}
1150
1151#[derive(Debug, Clone)]
1152pub enum ListFontsWithInfoPartial {
1153    ListFontsWithInfoPiece(ListFontsWithInfoPiece),
1154    ListFontsWithInfoEnd,
1155}
1156
1157impl ListFontsWithInfoPartial {
1158    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1159        let name_length = conn.read_u8()?;
1160        let _sequence_number = conn.read_le_u16()?;
1161        let _reply_length = conn.read_le_u32()?;
1162
1163        if name_length == 0 {
1164            drop(conn.drain(52)?);
1165            Ok(Self::ListFontsWithInfoEnd)
1166        } else {
1167            let min_bounds = CharInfo::from_le_bytes(conn)?;
1168            drop(conn.drain(4)?);
1169            let max_bounds = CharInfo::from_le_bytes(conn)?;
1170            drop(conn.drain(4)?);
1171            let min_char_or_byte2 = conn.read_le_u16()?;
1172            let max_char_or_byte2 = conn.read_le_u16()?;
1173            let default_char = conn.read_le_u16()?;
1174            let properties_count = conn.read_le_u16()?;
1175            let draw_direction_code = conn.read_u8()?;
1176            let draw_direction = match draw_direction_code {
1177                0 => DrawDirection::LeftToRight,
1178                1 => DrawDirection::RightToLeft,
1179                _ => return Err(Error::InvalidResponse),
1180            };
1181            let min_byte1 = conn.read_u8()?;
1182            let max_byte1 = conn.read_u8()?;
1183            let all_chars_exist = conn.read_bool()?;
1184            let font_ascent = conn.read_le_i16()?;
1185            let font_descent = conn.read_le_i16()?;
1186            drop(conn.drain(4)?);
1187
1188            let mut properties = Vec::with_capacity(properties_count as usize);
1189            for _ in 0..properties_count {
1190                properties.push(FontProp::from_le_bytes(conn)?);
1191            }
1192
1193            let name = conn.read_n_bytes(name_length as usize)?;
1194            drop(conn.drain(pad(name_length as usize))?);
1195
1196            Ok(Self::ListFontsWithInfoPiece(ListFontsWithInfoPiece {
1197                min_bounds,
1198                max_bounds,
1199                min_char_or_byte2,
1200                max_char_or_byte2,
1201                default_char,
1202                properties,
1203                draw_direction,
1204                min_byte1,
1205                max_byte1,
1206                all_chars_exist,
1207                font_ascent,
1208                font_descent,
1209                name,
1210            }))
1211        }
1212    }
1213}
1214
1215#[derive(Debug, Clone)]
1216pub struct ListFontsWithInfo {
1217    pub replies: Vec<ListFontsWithInfoPiece>,
1218}
1219
1220impl_xreply!(ListFontsWithInfo);
1221
1222/*
1223GetFontPath
12241225     1     1                               Reply
1226     1                                     unused
1227     2     CARD16                          sequence number
1228     4     (n+p)/4                         reply length
1229     2     CARD16                          number of STRs in path
1230     22                                    unused
1231     n     LISTofSTR                       path
1232     p                                     unused, p=pad(n)
1233*/
1234
1235#[derive(Debug, Clone)]
1236pub struct GetFontPath {
1237    pub paths: ListOfStr,
1238}
1239
1240impl GetFontPath {
1241    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1242        let _unused = conn.read_u8()?;
1243        let _sequence_code = conn.read_le_u16()?;
1244        let _reply_length = conn.read_le_u32()?;
1245        let no_of_strs_in_path = conn.read_le_u16()?;
1246        drop(conn.drain(22)?); // unused
1247        let paths = ListOfStr::from_le_bytes(no_of_strs_in_path as usize, conn)?;
1248
1249        Ok(Self { paths })
1250    }
1251}
1252
1253impl_xreply!(GetFontPath);
1254
1255/*
1256GetImage
12571258     1     1                               Reply
1259     1     CARD8                           depth
1260     2     CARD16                          sequence number
1261     4     (n+p)/4                         reply length
1262     4     VISUALID                        visual
1263          0     None
1264     20                                    unused
1265     n     LISTofBYTE                      data
1266     p                                     unused, p=pad(n)
1267*/
1268
1269#[derive(Debug, Clone)]
1270pub struct GetImage {
1271    pub depth: u8,
1272    pub visual: OrNone<VisualId>,
1273    pub data: Vec<u8>,
1274}
1275
1276impl GetImage {
1277    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1278        let depth = conn.read_u8()?;
1279        let _sequence_number = conn.read_le_u16()?;
1280        let reply_length = conn.read_le_u32()?;
1281        let visual = OrNone::new(VisualId::from(conn.read_le_u32()?));
1282        drop(conn.drain(20)?);
1283        let data_length = reply_length * 4; // NOTE: Check this math
1284        let data = conn.read_n_bytes(data_length as usize)?;
1285        let _ = conn.drain(pad(data_length as usize))?;
1286
1287        Ok(Self {
1288            depth,
1289            visual,
1290            data,
1291        })
1292    }
1293}
1294
1295impl_xreply!(GetImage);
1296
1297/*
1298ListInstalledColormaps
12991300     1     1                               Reply
1301     1                                     unused
1302     2     CARD16                          sequence number
1303     4     n                               reply length
1304     2     n                               number of COLORMAPs in cmaps
1305     22                                    unused
1306     4n     LISTofCOLORMAP                 cmaps
1307*/
1308
1309#[derive(Debug, Clone)]
1310pub struct ListInstalledColormaps {
1311    pub cmaps: Vec<ColormapId>,
1312}
1313
1314impl ListInstalledColormaps {
1315    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1316        let _unused = conn.read_u8()?;
1317        let _sequence_number = conn.read_le_u16()?;
1318        let _reply_length = conn.read_le_u32()?;
1319        let cmaps_count = conn.read_le_u16()?;
1320        drop(conn.drain(22)?);
1321
1322        let mut cmaps = Vec::with_capacity(cmaps_count as usize);
1323        for _ in 0..cmaps_count {
1324            let colormap = ColormapId::from(conn.read_le_u32()?);
1325            cmaps.push(colormap);
1326        }
1327
1328        Ok(Self { cmaps })
1329    }
1330}
1331
1332impl_xreply!(ListInstalledColormaps);
1333
1334/*
1335AllocColor
13361337     1     1                               Reply
1338     1                                     unused
1339     2     CARD16                          sequence number
1340     4     0                               reply length
1341     2     CARD16                          red
1342     2     CARD16                          green
1343     2     CARD16                          blue
1344     2                                     unused
1345     4     CARD32                          pixel
1346     12                                    unused
1347*/
1348
1349#[derive(Debug, Clone)]
1350pub struct AllocColor {
1351    pub red: u16,
1352    pub green: u16,
1353    pub blue: u16,
1354    pub pixel: u32,
1355}
1356
1357impl AllocColor {
1358    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1359        let _unused = conn.read_u8()?;
1360        let _sequence_number = conn.read_le_u16()?;
1361        let _reply_length = conn.read_le_u32()?;
1362        let red = conn.read_le_u16()?;
1363        let green = conn.read_le_u16()?;
1364        let blue = conn.read_le_u16()?;
1365        drop(conn.drain(2)?);
1366        let pixel = conn.read_le_u32()?;
1367        drop(conn.drain(12)?);
1368
1369        Ok(Self {
1370            red,
1371            green,
1372            blue,
1373            pixel,
1374        })
1375    }
1376}
1377
1378impl_xreply!(AllocColor);
1379
1380/*
1381AllocNamedColor
13821383     1     1                               Reply
1384     1                                     unused
1385     2     CARD16                          sequence number
1386     4     0                               reply length
1387     4     CARD32                          pixel
1388     2     CARD16                          exact-red
1389     2     CARD16                          exact-green
1390     2     CARD16                          exact-blue
1391     2     CARD16                          visual-red
1392     2     CARD16                          visual-green
1393     2     CARD16                          visual-blue
1394     8                                     unused
1395*/
1396
1397#[derive(Debug, Clone)]
1398pub struct AllocNamedColor {
1399    pub pixel: u32,
1400    pub exact_red: u16,
1401    pub exact_green: u16,
1402    pub exact_blue: u16,
1403    pub visual_red: u16,
1404    pub visual_green: u16,
1405    pub visual_blue: u16,
1406}
1407
1408impl AllocNamedColor {
1409    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1410        let _unused = conn.read_u8()?;
1411        let _sequence_number = conn.read_le_u16()?;
1412        let _reply_length = conn.read_le_u32()?;
1413        let pixel = conn.read_le_u32()?;
1414        let exact_red = conn.read_le_u16()?;
1415        let exact_green = conn.read_le_u16()?;
1416        let exact_blue = conn.read_le_u16()?;
1417        let visual_red = conn.read_le_u16()?;
1418        let visual_green = conn.read_le_u16()?;
1419        let visual_blue = conn.read_le_u16()?;
1420        drop(conn.drain(8)?);
1421
1422        Ok(Self {
1423            pixel,
1424            exact_red,
1425            exact_green,
1426            exact_blue,
1427            visual_red,
1428            visual_green,
1429            visual_blue,
1430        })
1431    }
1432}
1433
1434impl_xreply!(AllocNamedColor);
1435
1436/*
1437AllocColorCells
14381439     1     1                               Reply
1440     1                                     unused
1441     2     CARD16                          sequence number
1442     4     n+m                             reply length
1443     2     n                               number of CARD32s in pixels
1444     2     m                               number of CARD32s in masks
1445     20                                    unused
1446     4n     LISTofCARD32                   pixels
1447     4m     LISTofCARD32                   masks
1448*/
1449
1450#[derive(Debug, Clone)]
1451pub struct AllocColorCells {
1452    pub pixels: Vec<u32>,
1453    pub masks: Vec<u32>,
1454}
1455
1456impl AllocColorCells {
1457    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1458        let _unused = conn.read_u8()?;
1459        let _sequence_number = conn.read_le_u16()?;
1460        let _reply_length = conn.read_le_u32()?;
1461        let pixels_count = conn.read_le_u16()?;
1462        let masks_count = conn.read_le_u16()?;
1463        drop(conn.drain(20)?);
1464
1465        let mut pixels = Vec::with_capacity(pixels_count as usize);
1466        for _ in 0..pixels_count {
1467            let pixel = conn.read_le_u32()?;
1468            pixels.push(pixel);
1469        }
1470
1471        let mut masks = Vec::with_capacity(masks_count as usize);
1472        for _ in 0..masks_count {
1473            let mask = conn.read_le_u32()?;
1474            masks.push(mask);
1475        }
1476
1477        Ok(Self { pixels, masks })
1478    }
1479}
1480
1481impl_xreply!(AllocColorCells);
1482
1483/*
1484AllocColorPlanes
14851486     1     1                               Reply
1487     1                                     unused
1488     2     CARD16                          sequence number
1489     4     n                               reply length
1490     2     n                               number of CARD32s in pixels
1491     2                                     unused
1492     4     CARD32                          red-mask
1493     4     CARD32                          green-mask
1494     4     CARD32                          blue-mask
1495     8                                     unused
1496     4n     LISTofCARD32                   pixels
1497*/
1498
1499#[derive(Debug, Clone)]
1500pub struct AllocColorPlanes {
1501    pub red_mask: u32,
1502    pub green_mask: u32,
1503    pub blue_mask: u32,
1504    pub pixels: Vec<u32>,
1505}
1506
1507impl AllocColorPlanes {
1508    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1509        let _unused = conn.read_u8()?;
1510        let _sequence_number = conn.read_le_u16()?;
1511        let _reply_length = conn.read_le_u32()?;
1512        let pixels_count = conn.read_le_u16()?;
1513        let _unused = conn.read_le_u16()?;
1514        let red_mask = conn.read_le_u32()?;
1515        let green_mask = conn.read_le_u32()?;
1516        let blue_mask = conn.read_le_u32()?;
1517        drop(conn.drain(8)?);
1518
1519        // TODO: Optimize it
1520        let mut pixels = Vec::with_capacity(pixels_count as usize);
1521        for _ in 0..pixels_count {
1522            let pixel = conn.read_le_u32()?;
1523            pixels.push(pixel);
1524        }
1525
1526        Ok(Self {
1527            red_mask,
1528            green_mask,
1529            blue_mask,
1530            pixels,
1531        })
1532    }
1533}
1534
1535impl_xreply!(AllocColorPlanes);
1536
1537/*
1538QueryColors
15391540     1     1                               Reply
1541     1                                     unused
1542     2     CARD16                          sequence number
1543     4     2n                              reply length
1544     2     n                               number of RGBs in colors
1545     22                                    unused
1546     8n     LISTofRGB                      colors
1547
1548  RGB
1549     2     CARD16                          red
1550     2     CARD16                          green
1551     2     CARD16                          blue
1552     2                                     unused
1553*/
1554
1555#[derive(Debug, Clone)]
1556pub struct Rgb {
1557    pub red: u16,
1558    pub green: u16,
1559    pub blue: u16,
1560}
1561
1562impl Rgb {
1563    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1564        let red = conn.read_le_u16()?;
1565        let green = conn.read_le_u16()?;
1566        let blue = conn.read_le_u16()?;
1567        let _unused = conn.read_le_u16()?;
1568        Ok(Rgb { red, green, blue })
1569    }
1570}
1571
1572#[derive(Debug, Clone)]
1573pub struct QueryColors {
1574    pub colors: Vec<Rgb>,
1575}
1576
1577impl QueryColors {
1578    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1579        let _unused = conn.read_u8()?;
1580        let _sequence_number = conn.read_le_u16()?;
1581        let _reply_length = conn.read_le_u32()? as usize;
1582        let colors_count = conn.read_le_u16()? as usize;
1583        drop(conn.drain(22)?);
1584
1585        let mut colors = Vec::with_capacity(colors_count);
1586        for _ in 0..colors_count {
1587            colors.push(Rgb::from_le_bytes(conn)?);
1588        }
1589
1590        Ok(Self { colors })
1591    }
1592}
1593
1594impl_xreply!(QueryColors);
1595
1596/*
1597LookupColor
15981599     1     1                               Reply
1600     1                                     unused
1601     2     CARD16                          sequence number
1602     4     0                               reply length
1603     2     CARD16                          exact-red
1604     2     CARD16                          exact-green
1605     2     CARD16                          exact-blue
1606     2     CARD16                          visual-red
1607     2     CARD16                          visual-green
1608     2     CARD16                          visual-blue
1609     12                                    unused
1610*/
1611
1612#[derive(Debug, Clone)]
1613pub struct LookupColor {
1614    pub exact_red: u16,
1615    pub exact_green: u16,
1616    pub exact_blue: u16,
1617    pub visual_red: u16,
1618    pub visual_green: u16,
1619    pub visual_blue: u16,
1620}
1621
1622impl LookupColor {
1623    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1624        let _unused = conn.read_u8()?;
1625        let _sequence_number = conn.read_le_u16()?;
1626        let _reply_length = conn.read_le_u32()?;
1627        let exact_red = conn.read_le_u16()?;
1628        let exact_green = conn.read_le_u16()?;
1629        let exact_blue = conn.read_le_u16()?;
1630        let visual_red = conn.read_le_u16()?;
1631        let visual_green = conn.read_le_u16()?;
1632        let visual_blue = conn.read_le_u16()?;
1633        drop(conn.drain(12)?);
1634
1635        Ok(Self {
1636            exact_red,
1637            exact_green,
1638            exact_blue,
1639            visual_red,
1640            visual_green,
1641            visual_blue,
1642        })
1643    }
1644}
1645
1646impl_xreply!(LookupColor);
1647
1648/*
1649QueryBestSize
16501651     1     1                               Reply
1652     1                                     unused
1653     2     CARD16                          sequence number
1654     4     0                               reply length
1655     2     CARD16                          width
1656     2     CARD16                          height
1657     20                                    unused
1658*/
1659
1660#[derive(Debug, Clone)]
1661pub struct QueryBestSize {
1662    pub width: u16,
1663    pub height: u16,
1664}
1665
1666impl QueryBestSize {
1667    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1668        let _unused = conn.read_u8()?;
1669        let _sequence_number = conn.read_le_u16()?;
1670        let _reply_length = conn.read_le_u32()?;
1671        let width = conn.read_le_u16()?;
1672        let height = conn.read_le_u16()?;
1673        drop(conn.drain(20)?);
1674
1675        Ok(Self { width, height })
1676    }
1677}
1678
1679impl_xreply!(QueryBestSize);
1680
1681/*
1682QueryExtension
16831684     1     1                               Reply
1685     1                                     unused
1686     2     CARD16                          sequence number
1687     4     0                               reply length
1688     1     BOOL                            present
1689     1     CARD8                           major-opcode
1690     1     CARD8                           first-event
1691     1     CARD8                           first-error
1692     20                                    unused
1693*/
1694
1695#[derive(Debug, Clone)]
1696pub struct QueryExtension {
1697    pub present: bool,
1698    pub major_opcode: u8,
1699    pub first_event: u8,
1700    pub first_error: u8,
1701}
1702
1703impl QueryExtension {
1704    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1705        let _unused = conn.read_u8()?;
1706        let _sequence_number = conn.read_le_u16()?;
1707        let _reply_length = conn.read_le_u32()?;
1708        let present = conn.read_bool()?;
1709        let major_opcode = conn.read_u8()?;
1710        let first_event = conn.read_u8()?;
1711        let first_error = conn.read_u8()?;
1712        drop(conn.drain(20)?);
1713
1714        Ok(Self {
1715            present,
1716            major_opcode,
1717            first_event,
1718            first_error,
1719        })
1720    }
1721}
1722
1723impl_xreply!(QueryExtension);
1724
1725/*
1726ListExtensions
17271728     1     1                               Reply
1729     1     CARD8                           number of STRs in names
1730     2     CARD16                          sequence number
1731     4     (n+p)/4                         reply length
1732     24                                    unused
1733     n     LISTofSTR                       names
1734     p                                     unused, p=pad(n)
1735*/
1736
1737#[derive(Debug, Clone)]
1738pub struct ListExtensions {
1739    pub names: ListOfStr,
1740}
1741
1742impl ListExtensions {
1743    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1744        let number_of_names = conn.read_u8()?;
1745        let _sequence_number = conn.read_le_u16()?;
1746        let _reply_length = conn.read_le_u32()? as usize;
1747        drop(conn.drain(24)?);
1748        let names = ListOfStr::from_le_bytes(number_of_names as usize, conn)?;
1749
1750        Ok(Self { names })
1751    }
1752}
1753
1754impl_xreply!(ListExtensions);
1755
1756/*
1757GetKeyboardMapping
17581759     1     1                               Reply
1760     1     n                               keysyms-per-keycode
1761     2     CARD16                          sequence number
1762     4     nm                              reply length (m = count field
1763                                           from the request)
1764     24                                    unused
1765     4nm     LISTofKEYSYM                  keysyms
1766*/
1767
1768// TODO:  Read KeySym decoding section
1769#[derive(Debug, Clone)]
1770pub struct KeySym {
1771    inner: u32,
1772}
1773
1774impl KeySym {
1775    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1776        let inner = conn.read_le_u32()?;
1777        Ok(Self { inner })
1778    }
1779}
1780
1781#[derive(Debug, Clone)]
1782pub struct GetKeyboardMapping {
1783    pub keysyms_per_keycode: u8,
1784    pub keysyms: Vec<KeySym>,
1785}
1786
1787impl GetKeyboardMapping {
1788    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1789        let keysyms_per_keycode = conn.read_u8()?;
1790        let _sequence_number = conn.read_le_u16()?;
1791        let reply_length = conn.read_le_u32()?;
1792        drop(conn.drain(24)?);
1793
1794        let m = reply_length as usize / 4;
1795        let mut keysyms = Vec::with_capacity(m);
1796        for _ in 0..m {
1797            let keysym = KeySym::from_le_bytes(conn)?;
1798            keysyms.push(keysym);
1799        }
1800
1801        Ok(Self {
1802            keysyms_per_keycode,
1803            keysyms,
1804        })
1805    }
1806}
1807
1808impl_xreply!(GetKeyboardMapping);
1809
1810/*
1811GetKeyboardControl
18121813     1     1                               Reply
1814     1                                     global-auto-repeat
1815          0     Off
1816          1     On
1817     2     CARD16                          sequence number
1818     4     5                               reply length
1819     4     CARD32                          led-mask
1820     1     CARD8                           key-click-percent
1821     1     CARD8                           bell-percent
1822     2     CARD16                          bell-pitch
1823     2     CARD16                          bell-duration
1824     2                                     unused
1825     32     LISTofCARD8                    auto-repeats
1826*/
1827
1828#[derive(Debug, Clone)]
1829pub struct GetKeyboardControl {
1830    pub global_auto_repeat: bool,
1831    pub led_mask: u32,
1832    pub key_click_percent: u8,
1833    pub bell_percent: u8,
1834    pub bell_pitch: u16,
1835    pub bell_duration: u16,
1836    pub auto_repeats: Vec<u8>,
1837}
1838
1839impl GetKeyboardControl {
1840    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1841        let global_auto_repeat_byte = conn.read_u8()?;
1842        let global_auto_repeat = global_auto_repeat_byte != 0;
1843        let _sequence_number = conn.read_le_u16()?;
1844        let _reply_length = conn.read_le_u32()?;
1845        let led_mask = conn.read_le_u32()?;
1846        let key_click_percent = conn.read_u8()?;
1847        let bell_percent = conn.read_u8()?;
1848        let bell_pitch = conn.read_le_u16()?;
1849        let bell_duration = conn.read_le_u16()?;
1850        drop(conn.drain(2)?);
1851        let auto_repeats = conn.read_n_bytes(32)?;
1852
1853        Ok(Self {
1854            global_auto_repeat,
1855            led_mask,
1856            key_click_percent,
1857            bell_percent,
1858            bell_pitch,
1859            bell_duration,
1860            auto_repeats,
1861        })
1862    }
1863}
1864
1865impl_xreply!(GetKeyboardControl);
1866
1867/*
1868GetPointerControl
18691870     1     1                               Reply
1871     1                                     unused
1872     2     CARD16                          sequence number
1873     4     0                               reply length
1874     2     CARD16                          acceleration-numerator
1875     2     CARD16                          acceleration-denominator
1876     2     CARD16                          threshold
1877     18                                    unused
1878*/
1879
1880#[derive(Debug, Clone)]
1881pub struct GetPointerControl {
1882    pub acceleration_numerator: u16,
1883    pub acceleration_denominator: u16,
1884    pub threshold: u16,
1885}
1886
1887impl GetPointerControl {
1888    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1889        let _unused = conn.read_u8()?;
1890        let _sequence_code = conn.read_le_u16()?;
1891        let _reply_length = conn.read_le_u32()?;
1892        let acceleration_numerator = conn.read_le_u16()?;
1893        let acceleration_denominator = conn.read_le_u16()?;
1894        let threshold = conn.read_le_u16()?;
1895        drop(conn.drain(18)?);
1896
1897        Ok(Self {
1898            acceleration_numerator,
1899            acceleration_denominator,
1900            threshold,
1901        })
1902    }
1903}
1904
1905impl_xreply!(GetPointerControl);
1906
1907/*
1908GetScreenSaver
19091910     1     1                               Reply
1911     1                                     unused
1912     2     CARD16                          sequence number
1913     4     0                               reply length
1914     2     CARD16                          timeout
1915     2     CARD16                          interval
1916     1                                     prefer-blanking
1917          0     No
1918          1     Yes
1919     1                                     allow-exposures
1920          0     No
1921          1     Yes
1922     18                                    unused
1923*/
1924
1925#[derive(Debug, Clone)]
1926pub struct GetScreenSaver {
1927    pub timeout: u16,
1928    pub interval: u16,
1929    pub prefer_blanking: bool,
1930    pub allow_exposures: bool,
1931}
1932
1933impl GetScreenSaver {
1934    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1935        let _unused = conn.read_u8()?;
1936        let _sequence_number = conn.read_le_u16()?;
1937        let _reply_length = conn.read_le_u32()?;
1938        let timeout = conn.read_le_u16()?;
1939        let interval = conn.read_le_u16()?;
1940        let prefer_blanking_byte = conn.read_u8()?;
1941        let prefer_blanking = prefer_blanking_byte != 0;
1942        let allow_exposures_byte = conn.read_u8()?;
1943        let allow_exposures = allow_exposures_byte != 0;
1944        let _unused = conn.drain(18)?;
1945
1946        Ok(Self {
1947            timeout,
1948            interval,
1949            prefer_blanking,
1950            allow_exposures,
1951        })
1952    }
1953}
1954
1955impl_xreply!(GetScreenSaver);
1956
1957/*
1958ListHosts
19591960     1     1                               Reply
1961     1                                     mode
1962          0     Disabled
1963          1     Enabled
1964     2     CARD16                          sequence number
1965     4     n/4                             reply length
1966     2     CARD16                          number of HOSTs in hosts
1967     22                                    unused
1968     n     LISTofHOST                      hosts (n always a multiple of 4)
1969*/
1970
1971#[derive(Debug, Clone)]
1972pub enum HostMode {
1973    Disabled,
1974    Enabled,
1975}
1976
1977#[derive(Debug, Clone)]
1978pub struct ListHosts {
1979    pub mode: HostMode,
1980    pub hosts: Vec<Host>,
1981}
1982
1983impl ListHosts {
1984    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
1985        let mode_byte = conn.read_u8()?;
1986        let mode = match mode_byte {
1987            0 => HostMode::Disabled,
1988            1 => HostMode::Enabled,
1989            _ => return Err(Error::InvalidResponse),
1990        };
1991        let _sequence_number = conn.read_le_u16()?;
1992        let _reply_length = conn.read_le_u32()? as usize;
1993        let num_hosts = conn.read_le_u16()? as usize;
1994        drop(conn.drain(22)?);
1995
1996        // Read the hosts
1997        let mut hosts = Vec::with_capacity(num_hosts);
1998        for _ in 0..num_hosts {
1999            hosts.push(Host::from_le_bytes(conn)?);
2000        }
2001
2002        Ok(Self { mode, hosts })
2003    }
2004}
2005
2006impl_xreply!(ListHosts);
2007
2008/*
2009SetPointerMapping
20102011     1     1                               Reply
2012     1                                     status
2013          0     Success
2014          1     Busy
2015     2     CARD16                          sequence number
2016     4     0                               reply length
2017     24                                    unused
2018*/
2019
2020#[derive(Debug, Clone)]
2021pub enum SetPointerMappingStatus {
2022    Success,
2023    Busy,
2024}
2025
2026#[derive(Debug, Clone)]
2027pub struct SetPointerMapping {
2028    pub status: SetPointerMappingStatus,
2029}
2030
2031impl SetPointerMapping {
2032    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
2033        let status_byte = conn.read_u8()?;
2034        let status = match status_byte {
2035            0 => SetPointerMappingStatus::Success,
2036            1 => SetPointerMappingStatus::Busy,
2037            _ => return Err(Error::InvalidResponse),
2038        };
2039        let _sequence_number = conn.read_le_u16()?;
2040        let _reply_length = conn.read_le_u32()?;
2041        drop(conn.drain(24)?);
2042
2043        Ok(Self { status })
2044    }
2045}
2046
2047impl_xreply!(SetPointerMapping);
2048
2049/*
2050GetPointerMapping
20512052     1     1                               Reply
2053     1     n                               length of map
2054     2     CARD16                          sequence number
2055     4     (n+p)/4                         reply length
2056     24                                    unused
2057     n     LISTofCARD8                     map
2058     p                                     unused, p=pad(n)
2059*/
2060
2061#[derive(Debug, Clone)]
2062pub struct GetPointerMapping {
2063    pub map: Vec<u8>,
2064}
2065
2066impl GetPointerMapping {
2067    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
2068        let length_of_map = conn.read_u8()?;
2069        let _sequence_number = conn.read_le_u16()?;
2070        let _reply_length = conn.read_le_u32()? as usize;
2071        drop(conn.drain(24)?);
2072        let map = conn.read_n_bytes(length_of_map as usize)?;
2073        drop(conn.drain(pad(length_of_map as usize))?);
2074
2075        Ok(Self { map })
2076    }
2077}
2078
2079impl_xreply!(GetPointerMapping);
2080
2081/*
2082SetModifierMapping
20832084     1     1                               Reply
2085     1                                     status
2086          0     Success
2087          1     Busy
2088          2     Failed
2089     2     CARD16                          sequence number
2090     4     0                               reply length
2091     24                                    unused
2092*/
2093
2094#[derive(Debug, Clone)]
2095pub enum SetModifierMappingStatus {
2096    Success,
2097    Busy,
2098    Failed,
2099}
2100
2101#[derive(Debug, Clone)]
2102pub struct SetModifierMapping {
2103    pub status: SetModifierMappingStatus,
2104}
2105
2106impl SetModifierMapping {
2107    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
2108        let status_byte = conn.read_u8()?;
2109        let status = match status_byte {
2110            0 => SetModifierMappingStatus::Success,
2111            1 => SetModifierMappingStatus::Busy,
2112            2 => SetModifierMappingStatus::Failed,
2113            _ => return Err(Error::InvalidResponse),
2114        };
2115        let _sequence_number = conn.read_le_u16()?;
2116        let _reply_length = conn.read_le_u32()?;
2117        drop(conn.drain(24)?);
2118
2119        Ok(Self { status })
2120    }
2121}
2122
2123impl_xreply!(SetModifierMapping);
2124
2125/*
2126GetModifierMapping
21272128     1     1                               Reply
2129     1     n                               keycodes-per-modifier
2130     2     CARD16                          sequence number
2131     4     2n                              reply length
2132     24                                    unused
2133     8n     LISTofKEYCODE                  keycodes
2134*/
2135
2136#[derive(Debug, Clone)]
2137pub struct GetModifierMapping {
2138    pub keycodes_per_modifier: u8,
2139    pub keycodes: Vec<[KeyCode; 8]>,
2140}
2141
2142impl GetModifierMapping {
2143    pub(crate) fn from_le_bytes(conn: &mut XConnection) -> Result<Self, Error> {
2144        let keycodes_per_modifier = conn.read_u8()?;
2145        let _sequence_number = conn.read_le_u16()?;
2146        let _reply_length = conn.read_le_u32()? as usize;
2147        drop(conn.drain(24)?);
2148
2149        let num_keycodes = keycodes_per_modifier as usize;
2150        let mut keycodes = Vec::with_capacity(num_keycodes);
2151        for _ in 0..num_keycodes {
2152            let mut key_code = [0u8; 8];
2153            conn.read_exact(&mut key_code)?;
2154            keycodes.push(key_code.map(KeyCode::from));
2155        }
2156
2157        Ok(Self {
2158            keycodes_per_modifier,
2159            keycodes,
2160        })
2161    }
2162}
2163
2164impl_xreply!(GetModifierMapping);
2165
2166// Wrappers
2167
2168#[derive(Debug, Clone)]
2169pub enum SomeReply {
2170    GetWindowAttributes(GetWindowAttributes),
2171    GetGeometry(GetGeometry),
2172    QueryTree(QueryTree),
2173    InternAtom(InternAtom),
2174    GetAtomName(GetAtomName),
2175    GetProperty(GetProperty),
2176    ListProperties(ListProperties),
2177    GetSelectionOwner(GetSelectionOwner),
2178    GrabPointer(GrabPointer),
2179    GrabKeyboard(GrabKeyboard),
2180    QueryPointer(QueryPointer),
2181    GetMotionEvents(GetMotionEvents),
2182    TranslateCoordinates(TranslateCoordinates),
2183    GetInputFocus(GetInputFocus),
2184    QueryKeymap(QueryKeymap),
2185    QueryFont(QueryFont),
2186    QueryTextExtents(QueryTextExtents),
2187    ListFonts(ListFonts),
2188    ListFontsWithInfo(ListFontsWithInfo),
2189    // NOTE: Fake reply type because `ListFontsWithInfo` comes in multiple replies for each font
2190    ListFontsWithInfoPartial(ListFontsWithInfoPartial),
2191    GetFontPath(GetFontPath),
2192    GetImage(GetImage),
2193    ListInstalledColormaps(ListInstalledColormaps),
2194    AllocColor(AllocColor),
2195    AllocNamedColor(AllocNamedColor),
2196    AllocColorCells(AllocColorCells),
2197    AllocColorPlanes(AllocColorPlanes),
2198    QueryColors(QueryColors),
2199    LookupColor(LookupColor),
2200    QueryBestSize(QueryBestSize),
2201    QueryExtension(QueryExtension),
2202    ListExtensions(ListExtensions),
2203    GetKeyboardMapping(GetKeyboardMapping),
2204    GetKeyboardControl(GetKeyboardControl),
2205    GetPointerControl(GetPointerControl),
2206    GetScreenSaver(GetScreenSaver),
2207    ListHosts(ListHosts),
2208    SetPointerMapping(SetPointerMapping),
2209    GetPointerMapping(GetPointerMapping),
2210    SetModifierMapping(SetModifierMapping),
2211    GetModifierMapping(GetModifierMapping),
2212}
2213
2214#[derive(Debug, Clone, Copy)]
2215#[repr(u8)]
2216pub enum ReplyType {
2217    GetWindowAttributes = opcodes::GET_WINDOW_ATTRIBUTES,
2218    GetGeometry = opcodes::GET_GEOMETRY,
2219    QueryTree = opcodes::QUERY_TREE,
2220    InternAtom = opcodes::INTERN_ATOM,
2221    GetAtomName = opcodes::GET_ATOM_NAME,
2222    GetProperty = opcodes::GET_PROPERTY,
2223    ListProperties = opcodes::LIST_PROPERTIES,
2224    GetSelectionOwner = opcodes::GET_SELECTION_OWNER,
2225    GrabPointer = opcodes::GRAB_POINTER,
2226    GrabKeyboard = opcodes::GRAB_KEYBOARD,
2227    QueryPointer = opcodes::QUERY_POINTER,
2228    GetMotionEvents = opcodes::GET_MOTION_EVENTS,
2229    TranslateCoordinates = opcodes::TRANSLATE_COORDINATES,
2230    GetInputFocus = opcodes::GET_INPUT_FOCUS,
2231    QueryKeymap = opcodes::QUERY_KEYMAP,
2232    QueryFont = opcodes::QUERY_FONT,
2233    QueryTextExtents = opcodes::QUERY_TEXT_EXTENTS,
2234    ListFonts = opcodes::LIST_FONTS,
2235    ListFontsWithInfo = opcodes::LIST_FONTS_WITH_INFO,
2236    GetFontPath = opcodes::GET_FONT_PATH,
2237    GetImage = opcodes::GET_IMAGE,
2238    ListInstalledColormaps = opcodes::LIST_INSTALLED_COLORMAPS,
2239    AllocColor = opcodes::ALLOC_COLOR,
2240    AllocNamedColor = opcodes::ALLOC_NAMED_COLOR,
2241    AllocColorCells = opcodes::ALLOC_COLOR_CELLS,
2242    AllocColorPlanes = opcodes::ALLOC_COLOR_PLANES,
2243    QueryColors = opcodes::QUERY_COLORS,
2244    LookupColor = opcodes::LOOKUP_COLOR,
2245    QueryBestSize = opcodes::QUERY_BEST_SIZE,
2246    QueryExtension = opcodes::QUERY_EXTENSION,
2247    ListExtensions = opcodes::LIST_EXTENSIONS,
2248    GetKeyboardMapping = opcodes::GET_KEYBOARD_MAPPING,
2249    GetKeyboardControl = opcodes::GET_KEYBOARD_CONTROL,
2250    GetPointerControl = opcodes::GET_POINTER_CONTROL,
2251    GetScreenSaver = opcodes::GET_SCREEN_SAVER,
2252    ListHosts = opcodes::LIST_HOSTS,
2253    SetPointerMapping = opcodes::SET_POINTER_MAPPING,
2254    GetPointerMapping = opcodes::GET_POINTER_MAPPING,
2255    SetModifierMapping = opcodes::SET_MODIFIER_MAPPING,
2256    GetModifierMapping = opcodes::GET_MODIFIER_MAPPING,
2257}
2258
2259#[derive(Debug, Clone)]
2260pub(crate) struct ReceivedReply {
2261    pub(crate) reply_type: ReplyType,
2262    pub(crate) reply: SomeReply,
2263    pub(crate) done_receiving: bool,
2264}
2265
2266impl ReceivedReply {
2267    pub(crate) fn append_reply(&mut self, reply: SomeReply) -> bool {
2268        if self.done_receiving {
2269            return false;
2270        }
2271
2272        match &mut self.reply {
2273            SomeReply::ListFontsWithInfo(list_fonts) => match reply {
2274                SomeReply::ListFontsWithInfoPartial(
2275                    ListFontsWithInfoPartial::ListFontsWithInfoEnd,
2276                ) => {
2277                    self.done_receiving = true;
2278                }
2279                SomeReply::ListFontsWithInfoPartial(
2280                    ListFontsWithInfoPartial::ListFontsWithInfoPiece(piece),
2281                ) => {
2282                    list_fonts.replies.push(piece);
2283                }
2284                _ => return false,
2285            },
2286            _ => return false,
2287        }
2288
2289        true
2290    }
2291}
2292
2293#[derive(Debug, Clone)]
2294pub(crate) enum AwaitingReply {
2295    /// Response not received yet, but when received will be inserted to the map of responses
2296    NotReceived(ReplyType),
2297
2298    /// Response not received yet, but when received will be discared
2299    Discarded(ReplyType),
2300
2301    /// Response already received and waiting to be used or discarded or for more information to finalize
2302    Received(ReceivedReply),
2303}
2304
2305impl AwaitingReply {
2306    pub(crate) fn reply_type(&self) -> ReplyType {
2307        match self {
2308            &AwaitingReply::NotReceived(reply_type) | &AwaitingReply::Discarded(reply_type) => {
2309                reply_type
2310            }
2311            AwaitingReply::Received(received) => received.reply_type,
2312        }
2313    }
2314}