1
0
Fork 0
forked from wry/wry

autocommit 2022-01-03 18:56:52 CET

This commit is contained in:
Julian Orth 2022-01-03 18:56:52 +01:00
parent fc887b339e
commit 30376c595c
39 changed files with 3157 additions and 309 deletions

View file

@ -0,0 +1,269 @@
mod types;
use crate::client::{AddObj, Client};
use crate::object::{Interface, Object, ObjectId};
use crate::utils::buffd::MsgParser;
use bitflags::bitflags;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use std::cell::RefCell;
use std::rc::Rc;
pub use types::*;
const DESTROY: u32 = 0;
const SET_SIZE: u32 = 1;
const SET_ANCHOR_RECT: u32 = 2;
const SET_ANCHOR: u32 = 3;
const SET_GRAVITY: u32 = 4;
const SET_CONSTRAINT_ADJUSTMENT: u32 = 5;
const SET_OFFSET: u32 = 6;
const SET_REACTIVE: u32 = 7;
const SET_PARENT_SIZE: u32 = 8;
const SET_PARENT_CONFIGURE: u32 = 9;
const INVALID_INPUT: u32 = 0;
#[derive(Debug, Eq, PartialEq, Copy, Clone, FromPrimitive)]
pub enum Anchor {
None = 0,
Top = 1,
Bottom = 2,
Left = 3,
Right = 4,
TopLeft = 5,
BottomLeft = 6,
TopRight = 7,
BottomRight = 8,
}
impl Default for Anchor {
fn default() -> Self {
Self::None
}
}
#[derive(Debug, Eq, PartialEq, Copy, Clone, FromPrimitive)]
pub enum Gravity {
None = 0,
Top = 1,
Bottom = 2,
Left = 3,
Right = 4,
TopLeft = 5,
BottomLeft = 6,
TopRight = 7,
BottomRight = 8,
}
impl Default for Gravity {
fn default() -> Self {
Self::None
}
}
bitflags! {
#[derive(Default)]
pub struct CA: u32 {
const NONE = 0;
const SLIDE_X = 1;
const SLIDE_Y = 2;
const FLIP_X = 4;
const FLIP_Y = 8;
const RESIZE_X = 16;
const RESIZE_Y = 32;
}
}
pub struct XdgPositioner {
id: ObjectId,
client: Rc<Client>,
version: u32,
position: RefCell<XdgPositioned>,
}
#[derive(Copy, Clone, Debug, Default)]
pub struct XdgPositioned {
pub size_width: u32,
pub size_height: u32,
pub ar_x: i32,
pub ar_y: i32,
pub ar_width: u32,
pub ar_height: u32,
pub anchor: Anchor,
pub gravity: Gravity,
pub ca: CA,
pub off_x: i32,
pub off_y: i32,
pub reactive: bool,
pub parent_width: u32,
pub parent_height: u32,
pub parent_serial: u32,
}
impl XdgPositioner {
pub fn new(id: ObjectId, client: &Rc<Client>, version: u32) -> Self {
Self {
id,
client: client.clone(),
version,
position: RefCell::new(Default::default()),
}
}
pub fn clone(&self) -> Box<XdgPositioned> {
Box::new(*self.position.borrow())
}
async fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
let _req: Destroy = self.client.parse(self, parser)?;
self.client.remove_obj(self).await?;
Ok(())
}
async fn set_size(&self, parser: MsgParser<'_, '_>) -> Result<(), SetSizeError> {
let req: SetSize = self.client.parse(self, parser)?;
if req.width <= 0 || req.height <= 0 {
self.client.protocol_error(
self,
INVALID_INPUT,
format!("Cannot set a non-positive size"),
);
return Err(SetSizeError::NonPositiveSize);
}
let mut position = self.position.borrow_mut();
position.size_width = req.width as u32;
position.size_height = req.height as u32;
Ok(())
}
async fn set_anchor_rect(&self, parser: MsgParser<'_, '_>) -> Result<(), SetAnchorRectError> {
let req: SetAnchorRect = self.client.parse(self, parser)?;
if req.width < 0 || req.height < 0 {
self.client.protocol_error(
self,
INVALID_INPUT,
format!("Cannot set an anchor rect with negative size"),
);
return Err(SetAnchorRectError::NegativeAnchorRect);
}
let mut position = self.position.borrow_mut();
position.ar_x = req.x;
position.ar_y = req.y;
position.ar_width = req.width as u32;
position.ar_height = req.height as u32;
Ok(())
}
async fn set_anchor(&self, parser: MsgParser<'_, '_>) -> Result<(), SetAnchorError> {
let req: SetAnchor = self.client.parse(self, parser)?;
let anchor = match Anchor::from_u32(req.anchor) {
Some(a) => a,
_ => return Err(SetAnchorError::UnknownAnchor(req.anchor)),
};
self.position.borrow_mut().anchor = anchor;
Ok(())
}
async fn set_gravity(&self, parser: MsgParser<'_, '_>) -> Result<(), SetGravityError> {
let req: SetGravity = self.client.parse(self, parser)?;
let gravity = match Gravity::from_u32(req.gravity) {
Some(a) => a,
_ => return Err(SetGravityError::UnknownGravity(req.gravity)),
};
self.position.borrow_mut().gravity = gravity;
Ok(())
}
async fn set_constraint_adjustment(
&self,
parser: MsgParser<'_, '_>,
) -> Result<(), SetConstraintAdjustmentError> {
let req: SetConstraintAdjustment = self.client.parse(self, parser)?;
let ca = match CA::from_bits(req.constraint_adjustment) {
Some(c) => c,
_ => {
return Err(SetConstraintAdjustmentError::UnknownCa(
req.constraint_adjustment,
))
}
};
self.position.borrow_mut().ca = ca;
Ok(())
}
async fn set_offset(&self, parser: MsgParser<'_, '_>) -> Result<(), SetOffsetError> {
let req: SetOffset = self.client.parse(self, parser)?;
let mut position = self.position.borrow_mut();
position.off_x = req.x;
position.off_y = req.y;
Ok(())
}
async fn set_reactive(&self, parser: MsgParser<'_, '_>) -> Result<(), SetReactiveError> {
let _req: SetReactive = self.client.parse(self, parser)?;
self.position.borrow_mut().reactive = true;
Ok(())
}
async fn set_parent_size(&self, parser: MsgParser<'_, '_>) -> Result<(), SetParentSizeError> {
let req: SetParentSize = self.client.parse(self, parser)?;
if req.parent_width < 0 || req.parent_height < 0 {
self.client.protocol_error(
self,
INVALID_INPUT,
format!("Cannot set a negative parent size"),
);
return Err(SetParentSizeError::NegativeParentSize);
}
let mut position = self.position.borrow_mut();
position.parent_width = req.parent_width as u32;
position.parent_height = req.parent_height as u32;
Ok(())
}
async fn set_parent_configure(
&self,
parser: MsgParser<'_, '_>,
) -> Result<(), SetParentConfigureError> {
let req: SetParentConfigure = self.client.parse(self, parser)?;
self.position.borrow_mut().parent_serial = req.serial;
Ok(())
}
async fn handle_request_(
&self,
request: u32,
parser: MsgParser<'_, '_>,
) -> Result<(), XdgPositionerError> {
match request {
DESTROY => self.destroy(parser).await?,
SET_SIZE => self.set_size(parser).await?,
SET_ANCHOR_RECT => self.set_anchor_rect(parser).await?,
SET_ANCHOR => self.set_anchor(parser).await?,
SET_GRAVITY => self.set_gravity(parser).await?,
SET_CONSTRAINT_ADJUSTMENT => self.set_constraint_adjustment(parser).await?,
SET_OFFSET => self.set_offset(parser).await?,
SET_REACTIVE => self.set_reactive(parser).await?,
SET_PARENT_SIZE => self.set_parent_size(parser).await?,
SET_PARENT_CONFIGURE => self.set_parent_configure(parser).await?,
_ => unreachable!(),
}
Ok(())
}
}
handle_request!(XdgPositioner);
impl Object for XdgPositioner {
fn id(&self) -> ObjectId {
self.id
}
fn interface(&self) -> Interface {
Interface::XdgPositioner
}
fn num_requests(&self) -> u32 {
SET_PARENT_CONFIGURE + 1
}
}

View file

@ -0,0 +1,293 @@
use crate::client::{ClientError, RequestParser};
use crate::utils::buffd::{MsgParser, MsgParserError};
use std::fmt::{Debug, Formatter};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum XdgPositionerError {
#[error("Could not process a `destroy` request")]
DestroyError(#[from] DestroyError),
#[error("Could not process a `set_size` request")]
SetSizeError(#[from] SetSizeError),
#[error("Could not process a `set_anchor_rect` request")]
SetAnchorRectError(#[from] SetAnchorRectError),
#[error("Could not process a `set_anchor` request")]
SetAnchorError(#[from] SetAnchorError),
#[error("Could not process a `set_gravity` request")]
SetGravityError(#[from] SetGravityError),
#[error("Could not process a `set_constraint_adjustment` request")]
SetConstraintAdjustmentError(#[from] SetConstraintAdjustmentError),
#[error("Could not process a `set_offset` request")]
SetOffsetError(#[from] SetOffsetError),
#[error("Could not process a `set_reactive` request")]
SetReactiveError(#[from] SetReactiveError),
#[error("Could not process a `set_parent_size` request")]
SetParentSizeError(#[from] SetParentSizeError),
#[error("Could not process a `set_parent_configure` request")]
SetParentConfigureError(#[from] SetParentConfigureError),
}
#[derive(Debug, Error)]
pub enum DestroyError {
#[error("Parsing failed")]
ParseError(#[source] Box<MsgParserError>),
#[error(transparent)]
ClientError(Box<ClientError>),
}
efrom!(DestroyError, ParseError, MsgParserError);
efrom!(DestroyError, ClientError, ClientError);
#[derive(Debug, Error)]
pub enum SetSizeError {
#[error("Parsing failed")]
ParseError(#[source] Box<MsgParserError>),
#[error("Cannot set a non-positive size")]
NonPositiveSize,
}
efrom!(SetSizeError, ParseError, MsgParserError);
#[derive(Debug, Error)]
pub enum SetAnchorRectError {
#[error("Parsing failed")]
ParseError(#[source] Box<MsgParserError>),
#[error("Cannot set an anchor rect with a negative size")]
NegativeAnchorRect,
}
efrom!(SetAnchorRectError, ParseError, MsgParserError);
#[derive(Debug, Error)]
pub enum SetAnchorError {
#[error("Parsing failed")]
ParseError(#[source] Box<MsgParserError>),
#[error("Unknown anchor {0}")]
UnknownAnchor(u32),
}
efrom!(SetAnchorError, ParseError, MsgParserError);
#[derive(Debug, Error)]
pub enum SetGravityError {
#[error("Parsing failed")]
ParseError(#[source] Box<MsgParserError>),
#[error("Unknown gravity {0}")]
UnknownGravity(u32),
}
efrom!(SetGravityError, ParseError, MsgParserError);
#[derive(Debug, Error)]
pub enum SetConstraintAdjustmentError {
#[error("Parsing failed")]
ParseError(#[source] Box<MsgParserError>),
#[error("Unknown constraint adjustment {0}")]
UnknownCa(u32),
}
efrom!(SetConstraintAdjustmentError, ParseError, MsgParserError);
#[derive(Debug, Error)]
pub enum SetOffsetError {
#[error("Parsing failed")]
ParseError(#[source] Box<MsgParserError>),
}
efrom!(SetOffsetError, ParseError, MsgParserError);
#[derive(Debug, Error)]
pub enum SetReactiveError {
#[error("Parsing failed")]
ParseError(#[source] Box<MsgParserError>),
}
efrom!(SetReactiveError, ParseError, MsgParserError);
#[derive(Debug, Error)]
pub enum SetParentSizeError {
#[error("Parsing failed")]
ParseError(#[source] Box<MsgParserError>),
#[error("Cannot set a negative parent size")]
NegativeParentSize,
}
efrom!(SetParentSizeError, ParseError, MsgParserError);
#[derive(Debug, Error)]
pub enum SetParentConfigureError {
#[error("Parsing failed")]
ParseError(#[source] Box<MsgParserError>),
}
efrom!(SetParentConfigureError, ParseError, MsgParserError);
pub(super) struct Destroy;
impl RequestParser<'_> for Destroy {
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
Ok(Self)
}
}
impl Debug for Destroy {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "destroy()")
}
}
pub(super) struct SetSize {
pub width: i32,
pub height: i32,
}
impl RequestParser<'_> for SetSize {
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
Ok(Self {
width: parser.int()?,
height: parser.int()?,
})
}
}
impl Debug for SetSize {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"set_size(width: {}, height: {})",
self.width, self.height
)
}
}
pub(super) struct SetAnchorRect {
pub x: i32,
pub y: i32,
pub width: i32,
pub height: i32,
}
impl RequestParser<'_> for SetAnchorRect {
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
Ok(Self {
x: parser.int()?,
y: parser.int()?,
width: parser.int()?,
height: parser.int()?,
})
}
}
impl Debug for SetAnchorRect {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"set_anchor_rect(x: {}, y: {}, width: {}, height: {})",
self.x, self.y, self.width, self.height
)
}
}
pub(super) struct SetAnchor {
pub anchor: u32,
}
impl RequestParser<'_> for SetAnchor {
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
Ok(Self {
anchor: parser.uint()?,
})
}
}
impl Debug for SetAnchor {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "set_anchor(anchor: {})", self.anchor)
}
}
pub(super) struct SetGravity {
pub gravity: u32,
}
impl RequestParser<'_> for SetGravity {
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
Ok(Self {
gravity: parser.uint()?,
})
}
}
impl Debug for SetGravity {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "set_gravity(gravity: {})", self.gravity)
}
}
pub(super) struct SetConstraintAdjustment {
pub constraint_adjustment: u32,
}
impl RequestParser<'_> for SetConstraintAdjustment {
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
Ok(Self {
constraint_adjustment: parser.uint()?,
})
}
}
impl Debug for SetConstraintAdjustment {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"set_constraint_adjustment(constraint_adjustment: {})",
self.constraint_adjustment
)
}
}
pub(super) struct SetOffset {
pub x: i32,
pub y: i32,
}
impl RequestParser<'_> for SetOffset {
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
Ok(Self {
x: parser.int()?,
y: parser.int()?,
})
}
}
impl Debug for SetOffset {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "set_offset(x: {}, y: {})", self.x, self.y)
}
}
pub(super) struct SetReactive;
impl RequestParser<'_> for SetReactive {
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
Ok(Self)
}
}
impl Debug for SetReactive {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "set_reactive()")
}
}
pub(super) struct SetParentSize {
pub parent_width: i32,
pub parent_height: i32,
}
impl RequestParser<'_> for SetParentSize {
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
Ok(Self {
parent_width: parser.int()?,
parent_height: parser.int()?,
})
}
}
impl Debug for SetParentSize {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"set_parent_size(parent_width: {}, parent_height: {})",
self.parent_width, self.parent_height
)
}
}
pub(super) struct SetParentConfigure {
pub serial: u32,
}
impl RequestParser<'_> for SetParentConfigure {
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
Ok(Self {
serial: parser.uint()?,
})
}
}
impl Debug for SetParentConfigure {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "set_parent_configure(serial: {})", self.serial)
}
}