use crate::{
container::{Bytes32, Vec8},
message::{common, Codec, SizeRect},
};
use num_derive::FromPrimitive;
#[derive(Encode, Decode, FromPrimitive, Debug, PartialEq, Clone, Copy)]
#[repr(u8)]
pub enum UpdateMessageType {
UpdateGraphics = 0x01,
UpdateRefresh = 0x02,
UpdateSuppress = 0x03,
}
__flags_struct! {
UpdateGraphicsFlags: u32 => {
frame_first = FRAME_FIRST = 0x0000_0001,
frame_last = FRAME_LAST = 0x0000_0002,
}
}
#[derive(Encode, Decode, FromPrimitive, Debug, PartialEq, Clone, Copy)]
#[repr(u8)]
pub enum UpdateRegionFlag {
Null = 0x01,
Full = 0x02,
}
#[derive(Decode, Encode, Debug, Clone)]
pub struct NowUpdateRegion {
pub surface_id: u16,
pub flags: UpdateRegionFlag,
pub rects: Vec8<SizeRect>,
}
#[derive(Debug, Clone, Encode, Decode)]
#[meta_enum = "UpdateMessageType"]
pub enum NowUpdateMsg<'a> {
UpdateGraphics(NowUpdateGraphicsMsg<'a>),
UpdateRefresh(NowUpdateRefreshMsg),
UpdateSuppress(NowUpdateSuppressMsg),
}
#[derive(Encode, Decode, Debug, Clone)]
pub struct NowUpdateGraphicsMsg<'a> {
pub subtype: UpdateMessageType,
flags: u8,
pub codec_id: Codec,
pub surface_id: u16,
pub frame_id: u16,
pub update_flags: UpdateGraphicsFlags,
pub update_rect: common::SizeRect,
pub update_data: Bytes32<'a>,
}
impl<'a> NowUpdateGraphicsMsg<'a> {
pub const REQUIRED_SIZE: usize = 24;
}
#[derive(Decode, Encode, Debug, Clone)]
pub struct NowUpdateRefreshMsg {
pub subtype: UpdateMessageType,
flags: u8,
reserved: u8,
pub regions: Vec8<NowUpdateRegion>,
}
#[derive(Decode, Encode, Debug, Clone)]
#[repr(C)]
pub struct NowUpdateSuppressMsg {
pub subtype: UpdateMessageType,
flags: u8,
reserved: u8,
pub regions: Vec8<NowUpdateRegion>,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
header::{AbstractNowHeader, NowHeader},
serialization::Decode,
};
#[rustfmt::skip]
const WAYK_NOW_UPDATE_GRAPHIC_MSG: [u8; 35] = [
0x1d, 0x03, 0x00, 0x00, 0x00, 0x42, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x60, 0x07, 0x24, 0x04, 0x0c, 0x00,
0x0c, 0x00,
0x05, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
];
#[test]
fn update_graphics_decoding() {
let header = NowHeader::decode(&WAYK_NOW_UPDATE_GRAPHIC_MSG).unwrap();
let update_graphic_payload = &WAYK_NOW_UPDATE_GRAPHIC_MSG[header.len()..];
let ugm = NowUpdateGraphicsMsg::decode(update_graphic_payload).unwrap();
assert_eq!(ugm.flags, 0x00);
assert_eq!(ugm.codec_id, Codec::JPEG);
assert_eq!(ugm.surface_id, 0x0000);
assert_eq!(ugm.frame_id, 0x0001);
assert_eq!(ugm.update_flags.value, 0x00000003);
assert_eq!(ugm.update_data.len(), 5);
assert_eq!(ugm.update_data[0], 0x01);
}
}