1
0
Fork 0
forked from wry/wry

autocommit 2022-02-06 19:56:51 CET

This commit is contained in:
Julian Orth 2022-02-06 19:56:51 +01:00
parent 1fdff156ec
commit 3f50b0c75e
37 changed files with 452 additions and 439 deletions

View file

@ -24,6 +24,6 @@ fn main() -> anyhow::Result<()> {
enums::main()?;
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=build/build.rs");
Ok(())
}

View file

@ -611,7 +611,7 @@ fn write_message<W: Write>(f: &mut W, obj: &BStr, message: &Message) -> Result<(
writeln!(f, " }}")?;
writeln!(f, " }}")?;
writeln!(f, " impl EventFormatter for {}{} {{", message.camel_name, if has_reference_type { "Out" } else { "" })?;
writeln!(f, " fn format(self: Box<Self>, fmt: &mut MsgFormatter<'_>) {{")?;
writeln!(f, " fn format(self, fmt: &mut MsgFormatter<'_>) {{")?;
writeln!(f, " fmt.header(self.self_id, {});", uppercase)?;
fn write_fmt_expr<W: Write>(f: &mut W, prefix: &str, ty: &Type, access: &str) -> Result<()> {
let p = match ty {

View file

@ -6,7 +6,7 @@ use crate::ifs::wl_display::WlDisplay;
use crate::ifs::wl_registry::{WlRegistry};
use crate::object::{Interface, Object, ObjectId, WL_DISPLAY_ID};
use crate::state::State;
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError};
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError, OutBufferSwapchain};
use crate::utils::numcell::NumCell;
use crate::utils::oneshot::{oneshot, OneshotTx};
use crate::utils::queue::AsyncQueue;
@ -19,6 +19,7 @@ use std::fmt::{Debug, Display, Formatter};
use std::mem;
use std::rc::Rc;
use uapi::{c, OwnedFd};
use crate::utils::asyncevent::AsyncEvent;
use crate::wire::WlRegistryId;
mod error;
@ -92,9 +93,9 @@ impl Clients {
checking_queue_size: Cell::new(false),
socket: global.eng.fd(&Rc::new(socket))?,
objects: Objects::new(),
events: AsyncQueue::new(),
swapchain: Default::default(),
flush_request: Default::default(),
shutdown: Cell::new(Some(send)),
shutdown_sent: Cell::new(false),
dispatch_frame_requests: AsyncQueue::new(),
});
let display = Rc::new(WlDisplay::new(&data));
@ -126,8 +127,7 @@ impl Clients {
if let Some(client) = self.clients.borrow_mut().remove(&client_id) {
log::info!("Shutting down client {}", client.data.id.0);
client.data.shutdown.replace(None).unwrap().send(());
client.data.events.push(WlEvent::Shutdown);
client.data.shutdown_sent.set(true);
client.data.flush_request.trigger();
self.shutdown_clients.borrow_mut().insert(client_id, client);
}
}
@ -158,42 +158,33 @@ pub struct ClientHolder {
impl Drop for ClientHolder {
fn drop(&mut self) {
self.data.objects.destroy();
self.data.events.clear();
self.data.dispatch_frame_requests.clear();
}
}
pub trait EventFormatter: Debug {
fn format(self: Box<Self>, fmt: &mut MsgFormatter<'_>);
fn format(self, fmt: &mut MsgFormatter<'_>);
fn id(&self) -> ObjectId;
fn interface(&self) -> Interface;
}
pub type DynEventFormatter = Box<dyn EventFormatter>;
pub trait RequestParser<'a>: Debug + Sized {
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError>;
}
pub enum WlEvent {
Flush,
Shutdown,
Event(Box<dyn EventFormatter>),
}
pub struct Client {
pub id: ClientId,
pub state: Rc<State>,
checking_queue_size: Cell<bool>,
socket: AsyncFd,
pub objects: Objects,
events: AsyncQueue<WlEvent>,
swapchain: Rc<RefCell<OutBufferSwapchain>>,
flush_request: AsyncEvent,
shutdown: Cell<Option<OneshotTx<()>>>,
shutdown_sent: Cell<bool>,
pub dispatch_frame_requests: AsyncQueue<Rc<WlCallback>>,
}
const MAX_PENDING_EVENTS: usize = 10000;
const MAX_PENDING_BUFFERS: usize = 10;
impl Client {
pub fn invalid_request(&self, obj: &dyn Object, request: u32) {
@ -205,7 +196,10 @@ impl Client {
obj.interface().name(),
);
match self.display() {
Ok(d) => self.fatal_event(d.invalid_request(obj, request)),
Ok(d) => {
d.send_invalid_request(obj, request);
self.state.clients.shutdown(self.id);
},
Err(e) => {
log::error!(
"Could not retrieve display of client {}: {}",
@ -249,7 +243,10 @@ impl Client {
let msg = ErrorFmt(message).to_string();
log::error!("Client {}: A fatal error occurred: {}", self.id.0, msg,);
match self.display() {
Ok(d) => self.fatal_event(d.implementation_error(msg)),
Ok(d) => {
d.send_implementation_error(msg);
self.state.clients.shutdown(self.id);
},
Err(e) => {
log::error!(
"Could not retrieve display of client {}: {}",
@ -263,38 +260,39 @@ impl Client {
pub fn protocol_error(&self, obj: &dyn Object, code: u32, message: String) {
if let Ok(d) = self.display() {
self.fatal_event(d.error(obj.id(), code, message));
} else {
self.state.clients.shutdown(self.id);
d.send_error(obj.id(), code, message);
}
}
pub fn fatal_event(&self, event: Box<dyn EventFormatter>) {
self.events.push(WlEvent::Event(event));
self.state.clients.shutdown(self.id);
}
pub fn event(self: &Rc<Self>, event: Box<dyn EventFormatter>) {
self.event2(WlEvent::Event(event));
}
pub fn flush(self: &Rc<Self>) {
self.event2(WlEvent::Flush);
}
pub fn event2(self: &Rc<Self>, event: WlEvent) {
self.events.push(event);
if self.events.size() > MAX_PENDING_EVENTS {
if !self.checking_queue_size.replace(true) {
self.state.slow_clients.push(self.clone());
pub fn event<T: EventFormatter>(self: &Rc<Self>, event: T) {
if log::log_enabled!(log::Level::Trace) {
self.log_event(&event);
}
let mut fds = vec![];
let mut swapchain = self.swapchain.borrow_mut();
let mut fmt = MsgFormatter::new(&mut swapchain.cur, &mut fds);
event.format(&mut fmt);
fmt.write_len();
if swapchain.cur.is_full() {
swapchain.commit();
if swapchain.pending.len() > MAX_PENDING_BUFFERS {
if !self.checking_queue_size.replace(true) {
self.state.slow_clients.push(self.clone());
}
}
self.flush_request.trigger();
}
}
pub fn flush(&self) {
self.flush_request.trigger();
}
pub async fn check_queue_size(&self) {
if self.events.size() > MAX_PENDING_EVENTS {
if self.swapchain.borrow_mut().exceeds_limit() {
self.state.eng.yield_now().await;
if self.events.size() > MAX_PENDING_EVENTS {
if self.swapchain.borrow_mut().exceeds_limit() {
log::error!("Client {} is too slow at fetching events", self.id.0);
self.state.clients.kill(self.id);
return;
@ -307,7 +305,7 @@ impl Client {
self.objects.registries()
}
pub fn log_event(&self, event: &dyn EventFormatter) {
pub fn log_event<T: EventFormatter>(&self, event: &T) {
log::trace!(
"Client {} <= {}@{}.{:?}",
self.id,

View file

@ -156,7 +156,7 @@ impl Objects {
}
ids[pos] |= 1 << seg_offset;
} else {
client_data.event(client_data.display()?.delete_id(id));
client_data.display()?.send_delete_id(id);
}
Ok(())
}

View file

@ -1,6 +1,7 @@
use crate::client::{Client, ClientError, WlEvent};
use std::collections::VecDeque;
use crate::client::{Client, ClientError};
use crate::object::ObjectId;
use crate::utils::buffd::{BufFdIn, BufFdOut, MsgFormatter, MsgParser};
use crate::utils::buffd::{BufFdIn, BufFdOut, MsgParser};
use crate::utils::oneshot::OneshotRx;
use crate::utils::vec_ext::VecExt;
use crate::ErrorFmt;
@ -19,9 +20,7 @@ pub async fn client(data: Rc<Client>, shutdown: OneshotRx<()>) {
}
drop(recv);
drop(dispatch_fr);
if !data.shutdown_sent.get() {
data.events.push(WlEvent::Shutdown);
}
data.flush_request.trigger();
match data.state.eng.timeout(5000) {
Ok(timeout) => {
timeout.await;
@ -38,7 +37,7 @@ async fn dispatch_fr(data: Rc<Client>) {
loop {
let mut fr = data.dispatch_frame_requests.pop().await;
loop {
data.event(fr.done());
fr.send_done();
if let Err(e) = data.remove_obj(&*fr) {
log::error!("Could not remove frame object: {}", ErrorFmt(e));
return;
@ -66,7 +65,8 @@ async fn receive(data: Rc<Client>) {
let obj = match data.objects.get_obj(obj_id) {
Ok(obj) => obj,
_ => {
data.fatal_event(display.invalid_object(obj_id));
display.send_invalid_object(obj_id);
data.state.clients.shutdown(data.id);
return Err(ClientError::InvalidObject(obj_id));
}
};
@ -109,49 +109,27 @@ async fn receive(data: Rc<Client>) {
data.id.0,
e
);
if !data.shutdown_sent.get() {
data.fatal_event(display.implementation_error(e.to_string()));
}
display.send_implementation_error(e.to_string());
data.state.clients.shutdown(data.id);
}
}
}
async fn send(data: Rc<Client>) {
let send = async {
let mut buf = BufFdOut::new(data.socket.clone());
let mut flush_requested = false;
let mut out = BufFdOut::new(data.socket.clone());
let mut buffers = VecDeque::new();
loop {
let mut event = data.events.pop().await;
loop {
match event {
WlEvent::Flush => {
flush_requested = true;
}
WlEvent::Shutdown => {
buf.flush().await?;
return Ok(());
}
WlEvent::Event(e) => {
if log::log_enabled!(log::Level::Trace) {
data.log_event(&*e);
}
let mut fds = vec![];
let mut fmt = MsgFormatter::new(&mut buf, &mut fds);
e.format(&mut fmt);
fmt.write_len();
if buf.needs_flush() {
buf.flush().await?;
flush_requested = false;
}
}
}
event = match data.events.try_pop() {
Some(e) => e,
_ => break,
};
data.flush_request.triggered().await;
{
let mut swapchain = data.swapchain.borrow_mut();
swapchain.commit();
mem::swap(&mut swapchain.pending, &mut buffers);
}
if mem::take(&mut flush_requested) {
buf.flush().await?;
let mut timeout = None;
while let Some(mut cur) = buffers.pop_front() {
out.flush(&mut cur, &mut timeout).await?;
data.swapchain.borrow_mut().free.push(cur);
}
}
};

View file

@ -1,4 +1,4 @@
use crate::client::{Client, DynEventFormatter};
use crate::client::{Client};
use crate::ifs::org_kde_kwin_server_decoration_manager::OrgKdeKwinServerDecorationManagerGlobal;
use crate::ifs::wl_drm::WlDrmGlobal;
use crate::ifs::wl_output::WlOutputGlobal;
@ -123,7 +123,7 @@ impl Globals {
fn insert(&self, state: &State, global: Rc<dyn Global>) {
self.insert_no_broadcast_(&global);
self.broadcast(state, |r| r.global(&global));
self.broadcast(state, |r| r.send_global(&global));
}
pub fn get(&self, name: GlobalName) -> Result<Rc<dyn Global>, GlobalsError> {
@ -133,7 +133,7 @@ impl Globals {
pub fn remove<T: WaylandGlobal>(&self, state: &State, global: &T) -> Result<(), GlobalsError> {
let _global = self.take(global.name(), true)?;
global.remove(self);
self.broadcast(state, |r| r.global_remove(global.name()));
self.broadcast(state, |r| r.send_global_remove(global.name()));
Ok(())
}
@ -141,13 +141,13 @@ impl Globals {
self.seats.lock()
}
pub fn notify_all(&self, client: &Rc<Client>, registry: &Rc<WlRegistry>) {
pub fn notify_all(&self, registry: &Rc<WlRegistry>) {
let globals = self.registry.lock();
macro_rules! emit {
($singleton:expr) => {
for global in globals.values() {
if global.singleton() == $singleton {
client.event(registry.global(global));
registry.send_global(global);
}
}
};
@ -156,11 +156,11 @@ impl Globals {
emit!(false);
}
fn broadcast<F: Fn(&Rc<WlRegistry>) -> DynEventFormatter>(&self, state: &State, f: F) {
fn broadcast<F: Fn(&Rc<WlRegistry>)>(&self, state: &State, f: F) {
state.clients.broadcast(|c| {
let registries = c.lock_registries();
for registry in registries.values() {
c.event(f(registry));
f(registry);
}
c.flush();
});

View file

@ -1,4 +1,4 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use crate::client::{Client, ClientError};
use crate::object::Object;
use crate::utils::buffd::MsgParser;
use std::cell::Cell;
@ -29,8 +29,8 @@ impl OrgKdeKwinServerDecoration {
}
}
pub fn mode(self: &Rc<Self>, mode: u32) -> DynEventFormatter {
Box::new(Mode {
pub fn send_mode(self: &Rc<Self>, mode: u32) {
self.client.event(Mode {
self_id: self.id,
mode,
})
@ -52,7 +52,7 @@ impl OrgKdeKwinServerDecoration {
} else {
SERVER
};
self.client.event(self.mode(mode));
self.send_mode(mode);
Ok(())
}
}

View file

@ -1,4 +1,4 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use crate::client::{Client, ClientError};
use crate::globals::{Global, GlobalName};
use crate::ifs::org_kde_kwin_server_decoration::OrgKdeKwinServerDecoration;
use crate::object::Object;
@ -35,7 +35,7 @@ impl OrgKdeKwinServerDecorationManagerGlobal {
_version: version,
});
client.add_client_obj(&obj)?;
client.event(obj.default_mode(SERVER));
obj.send_default_mode(SERVER);
Ok(())
}
}
@ -65,8 +65,8 @@ pub struct OrgKdeKwinServerDecorationManager {
}
impl OrgKdeKwinServerDecorationManager {
fn default_mode(self: &Rc<Self>, mode: u32) -> DynEventFormatter {
Box::new(DefaultMode {
fn send_default_mode(self: &Rc<Self>, mode: u32) {
self.client.event(DefaultMode {
self_id: self.id,
mode,
})
@ -77,7 +77,7 @@ impl OrgKdeKwinServerDecorationManager {
let _ = self.client.lookup(req.surface)?;
let obj = Rc::new(OrgKdeKwinServerDecoration::new(req.id, &self.client));
self.client.add_client_obj(&obj)?;
self.client.event(obj.mode(SERVER));
obj.send_mode(SERVER);
Ok(())
}
}

View file

@ -1,4 +1,4 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use crate::client::{Client, ClientError};
use crate::clientmem::{ClientMem, ClientMemOffset};
use crate::format::Format;
use crate::object::Object;
@ -118,8 +118,8 @@ impl WlBuffer {
Ok(())
}
pub fn release(&self) -> DynEventFormatter {
Box::new(Release { self_id: self.id })
pub fn send_release(&self) {
self.client.event(Release { self_id: self.id })
}
}

View file

@ -1,4 +1,4 @@
use crate::client::DynEventFormatter;
use crate::client::{Client};
use crate::object::Object;
use std::rc::Rc;
use thiserror::Error;
@ -6,16 +6,17 @@ use crate::wire::wl_callback::*;
use crate::wire::WlCallbackId;
pub struct WlCallback {
client: Rc<Client>,
id: WlCallbackId,
}
impl WlCallback {
pub fn new(id: WlCallbackId) -> Self {
Self { id }
pub fn new(id: WlCallbackId, client: &Rc<Client>) -> Self {
Self { client: client.clone(), id }
}
pub fn done(self: &Rc<Self>) -> DynEventFormatter {
Box::new(Done { self_id: self.id, callback_data: 0 })
pub fn send_done(&self) {
self.client.event(Done { self_id: self.id, callback_data: 0 });
}
}

View file

@ -1,4 +1,4 @@
use crate::client::{ClientError, DynEventFormatter};
use crate::client::{ClientError};
use crate::ifs::wl_data_device_manager::WlDataDeviceManager;
use crate::ifs::wl_seat::WlSeat;
use crate::object::Object;
@ -28,15 +28,15 @@ impl WlDataDevice {
}
}
pub fn data_offer(self: &Rc<Self>, id: WlDataOfferId) -> DynEventFormatter {
Box::new(DataOffer {
pub fn send_data_offer(&self, id: WlDataOfferId) {
self.manager.client.event(DataOffer {
self_id: self.id,
id,
})
}
pub fn selection(self: &Rc<Self>, id: WlDataOfferId) -> DynEventFormatter {
Box::new(Selection {
pub fn send_selection(&self, id: WlDataOfferId) {
self.manager.client.event(Selection {
self_id: self.id,
id,
})

View file

@ -1,5 +1,5 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use std::mem;
use crate::client::{Client, ClientError};
use crate::ifs::wl_data_source::WlDataSource;
use crate::ifs::wl_seat::WlSeatGlobal;
use crate::object::Object;
@ -54,22 +54,29 @@ impl WlDataOffer {
source: CloneCell::new(Some(src.clone())),
});
let mt = src.mime_types.borrow_mut();
let mut sent_offer = false;
seat.for_each_data_device(0, client.id, |device| {
client.event(device.data_offer(slf.id));
for mt in mt.deref() {
client.event(slf.offer(mt));
if !mem::replace(&mut sent_offer, true) {
device.send_data_offer(slf.id);
}
for mt in mt.deref() {
slf.send_offer(mt);
}
match role {
DataOfferRole::Selection => device.send_selection(id),
}
let ev = match role {
DataOfferRole::Selection => device.selection(id),
};
client.event(ev);
});
client.add_server_obj(&slf);
Some(slf)
if !sent_offer {
let _ = client.remove_obj(&*slf);
None
} else {
Some(slf)
}
}
pub fn offer(self: &Rc<Self>, mime_type: &str) -> DynEventFormatter {
Box::new(OfferOut {
pub fn send_offer(self: &Rc<Self>, mime_type: &str) {
self.client.event(OfferOut {
self_id: self.id,
mime_type: mime_type.to_string(),
})
@ -83,7 +90,7 @@ impl WlDataOffer {
fn receive(&self, parser: MsgParser<'_, '_>) -> Result<(), ReceiveError> {
let req: ReceiveIn = self.client.parse(self, parser)?;
if let Some(src) = self.source.get() {
src.client.event(src.send(req.mime_type, req.fd));
src.send_send(req.mime_type, req.fd);
src.client.flush();
}
Ok(())

View file

@ -1,5 +1,5 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use crate::client::{Client, ClientError};
use crate::ifs::wl_data_offer::{DataOfferRole, WlDataOffer};
use crate::ifs::wl_seat::WlSeatGlobal;
use crate::object::Object;
@ -66,7 +66,7 @@ impl WlDataSource {
if let Some(offer) = self.offer.set(None) {
offer.source.set(None);
}
self.client.event(self.cancelled());
self.send_cancelled();
self.client.flush();
}
@ -89,12 +89,12 @@ impl WlDataSource {
self.offer.take();
}
pub fn cancelled(self: &Rc<Self>) -> DynEventFormatter {
Box::new(Cancelled { self_id: self.id })
pub fn send_cancelled(self: &Rc<Self>) {
self.client.event(Cancelled { self_id: self.id })
}
pub fn send(&self, mime_type: &str, fd: Rc<OwnedFd>) -> DynEventFormatter {
Box::new(SendOut {
pub fn send_send(&self, mime_type: &str, fd: Rc<OwnedFd>) {
self.client.event(SendOut {
self_id: self.id,
mime_type: mime_type.to_string(),
fd,
@ -109,7 +109,7 @@ impl WlDataSource {
.insert(req.mime_type.to_string())
{
if let Some(offer) = self.offer.get() {
offer.client.event(offer.offer(req.mime_type));
offer.send_offer(req.mime_type);
}
}
Ok(())

View file

@ -1,5 +1,5 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use crate::client::{Client, ClientError};
use crate::ifs::wl_callback::WlCallback;
use crate::ifs::wl_registry::WlRegistry;
use crate::object::{Object, ObjectId, WL_DISPLAY_ID};
@ -32,9 +32,9 @@ impl WlDisplay {
fn sync(&self, parser: MsgParser<'_, '_>) -> Result<(), SyncError> {
let sync: Sync = self.client.parse(self, parser)?;
let cb = Rc::new(WlCallback::new(sync.callback));
let cb = Rc::new(WlCallback::new(sync.callback, &self.client));
self.client.add_client_obj(&cb)?;
self.client.event(cb.done());
cb.send_done();
self.client.remove_obj(&*cb)?;
Ok(())
}
@ -46,17 +46,17 @@ impl WlDisplay {
self.client
.state
.globals
.notify_all(&self.client, &registry);
.notify_all(&registry);
Ok(())
}
pub fn error<O: Into<ObjectId>>(
self: &Rc<Self>,
pub fn send_error<O: Into<ObjectId>>(
&self,
object_id: O,
code: u32,
message: String,
) -> DynEventFormatter {
Box::new(ErrorOut {
) {
self.client.event(ErrorOut {
self_id: self.id,
object_id: object_id.into(),
code,
@ -64,7 +64,7 @@ impl WlDisplay {
})
}
pub fn invalid_request(self: &Rc<Self>, obj: &dyn Object, request: u32) -> DynEventFormatter {
pub fn send_invalid_request(self: &Rc<Self>, obj: &dyn Object, request: u32) {
let id = obj.id();
let msg = format!(
"Object {} of type {} has no method {}",
@ -72,20 +72,20 @@ impl WlDisplay {
obj.interface().name(),
request
);
self.error(id, INVALID_METHOD, msg)
self.send_error(id, INVALID_METHOD, msg)
}
pub fn invalid_object(self: &Rc<Self>, id: ObjectId) -> DynEventFormatter {
pub fn send_invalid_object(self: &Rc<Self>, id: ObjectId) {
let msg = format!("Object {} does not exist", id,);
self.error(id, INVALID_OBJECT, msg)
self.send_error(id, INVALID_OBJECT, msg)
}
pub fn implementation_error(self: &Rc<Self>, msg: String) -> DynEventFormatter {
self.error(WL_DISPLAY_ID, IMPLEMENTATION, msg)
pub fn send_implementation_error(self: &Rc<Self>, msg: String) {
self.send_error(WL_DISPLAY_ID, IMPLEMENTATION, msg)
}
pub fn delete_id(self: &Rc<Self>, id: ObjectId) -> DynEventFormatter {
Box::new(DeleteId {
pub fn send_delete_id(self: &Rc<Self>, id: ObjectId) {
self.client.event(DeleteId {
self_id: self.id,
id: id.raw(),
})

View file

@ -1,4 +1,4 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use crate::client::{Client, ClientError};
use crate::globals::{Global, GlobalName};
use crate::object::Object;
use crate::utils::buffd::MsgParser;
@ -35,8 +35,8 @@ impl WlDrmGlobal {
});
client.add_client_obj(&obj)?;
if let Some(rc) = client.state.render_ctx.get() {
client.event(obj.device(&rc.render_node()));
client.event(obj.capabilities(PRIME));
obj.send_device(&rc.render_node());
obj.send_capabilities(PRIME);
}
Ok(())
}
@ -63,19 +63,19 @@ pub struct WlDrm {
}
impl WlDrm {
fn device(self: &Rc<Self>, device: &Rc<CString>) -> DynEventFormatter {
Box::new(DeviceOut {
fn send_device(self: &Rc<Self>, device: &Rc<CString>) {
self.client.event(DeviceOut {
self_id: self.id,
name: device.as_bytes().as_bstr().to_owned(),
})
}
fn authenticated(self: &Rc<Self>) -> DynEventFormatter {
Box::new(Authenticated { self_id: self.id })
fn send_authenticated(self: &Rc<Self>) {
self.client.event(Authenticated { self_id: self.id })
}
fn capabilities(self: &Rc<Self>, value: u32) -> DynEventFormatter {
Box::new(Capabilities {
fn send_capabilities(self: &Rc<Self>, value: u32) {
self.client.event(Capabilities {
self_id: self.id,
value,
})
@ -83,7 +83,7 @@ impl WlDrm {
fn authenticate(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), AuthenticateError> {
let _req: Authenticate = self.client.parse(&**self, parser)?;
self.client.event(self.authenticated());
self.send_authenticated();
Ok(())
}

View file

@ -1,13 +1,12 @@
use crate::backend::Output;
use crate::client::{Client, ClientError, ClientId, DynEventFormatter, WlEvent};
use crate::client::{Client, ClientError, ClientId};
use crate::globals::{Global, GlobalName};
use crate::object::Object;
use crate::utils::buffd::MsgParser;
use ahash::AHashMap;
use std::cell::{Cell, RefCell};
use std::collections::hash_map::Entry;
use std::iter;
use std::rc::Rc;
use thiserror::Error;
use crate::wire::wl_output::*;
@ -81,19 +80,11 @@ impl WlOutputGlobal {
let bindings = self.bindings.borrow_mut();
for binding in bindings.values() {
for binding in binding.values() {
let events = [
binding.geometry(),
binding.mode(),
binding.scale(),
binding.done(),
];
let events = events
.into_iter()
.map(|e| WlEvent::Event(e))
.chain(iter::once(WlEvent::Flush));
for event in events {
binding.client.event2(event);
}
binding.send_geometry();
binding.send_mode();
binding.send_scale();
binding.send_done();
binding.client.flush();
}
}
}
@ -117,13 +108,13 @@ impl WlOutputGlobal {
.entry(client.id)
.or_default()
.insert(id, obj.clone());
client.event(obj.geometry());
client.event(obj.mode());
if obj.send_scale() {
client.event(obj.scale());
obj.send_geometry();
obj.send_mode();
if obj.version >= SEND_SCALE_SINCE {
obj.send_scale();
}
if obj.send_done() {
client.event(obj.done());
if obj.version >= SEND_DONE_SINCE {
obj.send_done();
}
Ok(())
}
@ -154,17 +145,12 @@ pub struct WlOutput {
version: u32,
}
pub const SEND_DONE_SINCE: u32 = 2;
pub const SEND_SCALE_SINCE: u32 = 2;
impl WlOutput {
fn send_done(&self) -> bool {
self.version >= 2
}
fn send_scale(&self) -> bool {
self.version >= 2
}
fn geometry(self: &Rc<Self>) -> DynEventFormatter {
Box::new(GeometryOut {
fn send_geometry(&self) {
let event = GeometryOut {
self_id: self.id,
x: 0,
y: 0,
@ -174,28 +160,32 @@ impl WlOutput {
make: "i4".to_string(),
model: "i4".to_string(),
transform: TF_NORMAL,
})
};
self.client.event(event);
}
fn mode(self: &Rc<Self>) -> DynEventFormatter {
Box::new(Mode {
fn send_mode(&self) {
let event = Mode {
self_id: self.id,
flags: MODE_CURRENT,
width: self.global.width.get() as _,
height: self.global.height.get() as _,
refresh: 60_000_000,
})
};
self.client.event(event);
}
fn scale(self: &Rc<Self>) -> DynEventFormatter {
Box::new(Scale {
fn send_scale(self: &Rc<Self>) {
let event = Scale {
self_id: self.id,
factor: 1,
})
};
self.client.event(event);
}
fn done(self: &Rc<Self>) -> DynEventFormatter {
Box::new(Done { self_id: self.id })
fn send_done(&self) {
let event = Done { self_id: self.id };
self.client.event(event);
}
fn remove_binding(&self) {

View file

@ -1,5 +1,5 @@
use crate::client::{Client, DynEventFormatter};
use crate::client::{Client};
use crate::globals::{Global, GlobalName, GlobalsError};
use crate::object::{Interface, Object};
use crate::utils::buffd::MsgParser;
@ -22,8 +22,8 @@ impl WlRegistry {
}
}
pub fn global(self: &Rc<Self>, global: &Rc<dyn Global>) -> DynEventFormatter {
Box::new(GlobalOut {
pub fn send_global(self: &Rc<Self>, global: &Rc<dyn Global>) {
self.client.event(GlobalOut {
self_id: self.id,
name: global.name().raw(),
interface: global.interface().name().to_string(),
@ -31,8 +31,8 @@ impl WlRegistry {
})
}
pub fn global_remove(self: &Rc<Self>, name: GlobalName) -> DynEventFormatter {
Box::new(GlobalRemove {
pub fn send_global_remove(self: &Rc<Self>, name: GlobalName) {
self.client.event(GlobalRemove {
self_id: self.id,
name: name.raw(),
})

View file

@ -4,7 +4,7 @@ pub mod wl_pointer;
pub mod wl_touch;
use crate::backend::{Seat, SeatId};
use crate::client::{Client, ClientError, ClientId, DynEventFormatter};
use crate::client::{Client, ClientError, ClientId};
use crate::cursor::{Cursor, KnownCursor};
use crate::fixed::Fixed;
use crate::globals::{Global, GlobalName};
@ -174,7 +174,7 @@ impl WlSeatGlobal {
}
_ => {
self.for_each_data_device(0, client.id, |device| {
client.event(device.selection(WlDataOfferId::NONE));
device.send_selection(WlDataOfferId::NONE);
});
}
}
@ -200,7 +200,7 @@ impl WlSeatGlobal {
}
_ => {
self.for_each_primary_selection_device(0, client.id, |device| {
client.event(device.selection(ZwpPrimarySelectionOfferV1Id::NONE));
device.send_selection(ZwpPrimarySelectionOfferV1Id::NONE);
});
}
}
@ -264,9 +264,9 @@ impl WlSeatGlobal {
version,
});
client.add_client_obj(&obj)?;
client.event(obj.capabilities());
obj.send_capabilities();
if version >= SEAT_NAME_SINCE {
client.event(obj.name(&self.seat_name));
obj.send_name(&self.seat_name);
}
{
let mut bindings = self.bindings.borrow_mut();
@ -297,23 +297,23 @@ dedicated_add_global!(WlSeatGlobal, seats);
pub struct WlSeat {
pub global: Rc<WlSeatGlobal>,
id: WlSeatId,
client: Rc<Client>,
pub id: WlSeatId,
pub client: Rc<Client>,
pointers: CopyHashMap<WlPointerId, Rc<WlPointer>>,
keyboards: CopyHashMap<WlKeyboardId, Rc<WlKeyboard>>,
version: u32,
}
impl WlSeat {
fn capabilities(self: &Rc<Self>) -> DynEventFormatter {
Box::new(Capabilities {
fn send_capabilities(self: &Rc<Self>) {
self.client.event(Capabilities {
self_id: self.id,
capabilities: POINTER | KEYBOARD,
})
}
fn name(self: &Rc<Self>, name: &Rc<String>) -> DynEventFormatter {
Box::new(NameOut {
fn send_name(self: &Rc<Self>, name: &Rc<String>) {
self.client.event(NameOut {
self_id: self.id,
name: name.deref().clone(),
})
@ -370,10 +370,9 @@ impl WlSeat {
let p = Rc::new(WlKeyboard::new(req.id, self));
self.client.add_client_obj(&p)?;
self.keyboards.set(req.id, p.clone());
self.client
.event(p.keymap(wl_keyboard::XKB_V1, p.keymap_fd()?, self.global.layout_size));
p.send_keymap(wl_keyboard::XKB_V1, p.keymap_fd()?, self.global.layout_size);
if self.version >= REPEAT_INFO_SINCE {
self.client.event(p.repeat_info(25, 250));
p.send_repeat_info(25, 250);
}
Ok(())
}

View file

@ -1,5 +1,5 @@
use crate::backend::{KeyState, OutputId, ScrollAxis, SeatEvent, SeatId};
use crate::client::{ClientId, DynEventFormatter};
use crate::client::{ClientId};
use crate::fixed::Fixed;
use crate::ifs::wl_data_device::WlDataDevice;
use crate::ifs::wl_seat::wl_keyboard::WlKeyboard;
@ -229,7 +229,7 @@ impl WlSeatGlobal {
let pressed_keys: Vec<_> = self.pressed_keys.borrow().iter().copied().collect();
let serial = self.serial.fetch_add(1);
self.surface_kb_event(0, &surface, |k| {
k.enter(serial, surface.id, pressed_keys.clone())
k.send_enter(serial, surface.id, pressed_keys.clone())
});
let ModifierState {
mods_depressed,
@ -239,14 +239,14 @@ impl WlSeatGlobal {
} = self.kb_state.borrow().mods();
let serial = self.serial.fetch_add(1);
self.surface_kb_event(0, &surface, |k| {
k.modifiers(serial, mods_depressed, mods_latched, mods_locked, group)
k.send_modifiers(serial, mods_depressed, mods_latched, mods_locked, group)
});
if old.client_id() != Some(surface.client.id) {
match self.selection.get() {
None => {
self.surface_data_device_event(0, &surface, |dd| {
dd.selection(WlDataOfferId::NONE)
dd.send_selection(WlDataOfferId::NONE)
});
}
Some(sel) => {
@ -256,7 +256,7 @@ impl WlSeatGlobal {
match self.primary_selection.get() {
None => {
self.surface_primary_selection_device_event(0, &surface, |dd| {
dd.selection(ZwpPrimarySelectionOfferV1Id::NONE)
dd.send_selection(ZwpPrimarySelectionOfferV1Id::NONE)
});
}
Some(sel) => {
@ -333,49 +333,49 @@ impl WlSeatGlobal {
}
fn surface_pointer_frame(&self, surface: &WlSurface) {
self.surface_pointer_event(POINTER_FRAME_SINCE_VERSION, surface, |p| p.frame());
self.surface_pointer_event(POINTER_FRAME_SINCE_VERSION, surface, |p| p.send_frame());
}
fn surface_pointer_event<F>(&self, ver: u32, surface: &WlSurface, mut f: F)
where
F: FnMut(&Rc<WlPointer>) -> DynEventFormatter,
F: FnMut(&Rc<WlPointer>),
{
let client = &surface.client;
self.for_each_pointer(ver, client.id, |p| {
client.event(f(p));
f(p);
});
client.flush();
}
fn surface_kb_event<F>(&self, ver: u32, surface: &WlSurface, mut f: F)
where
F: FnMut(&Rc<WlKeyboard>) -> DynEventFormatter,
F: FnMut(&Rc<WlKeyboard>),
{
let client = &surface.client;
self.for_each_kb(ver, client.id, |p| {
client.event(f(p));
f(p);
});
client.flush();
}
fn surface_data_device_event<F>(&self, ver: u32, surface: &WlSurface, mut f: F)
where
F: FnMut(&Rc<WlDataDevice>) -> DynEventFormatter,
F: FnMut(&Rc<WlDataDevice>),
{
let client = &surface.client;
self.for_each_data_device(ver, client.id, |p| {
client.event(f(p));
f(p);
});
client.flush();
}
fn surface_primary_selection_device_event<F>(&self, ver: u32, surface: &WlSurface, mut f: F)
where
F: FnMut(&Rc<ZwpPrimarySelectionDeviceV1>) -> DynEventFormatter,
F: FnMut(&Rc<ZwpPrimarySelectionDeviceV1>),
{
let client = &surface.client;
self.for_each_primary_selection_device(ver, client.id, |p| {
client.event(f(p));
f(p);
});
client.flush();
}
@ -487,7 +487,7 @@ impl WlSeatGlobal {
KeyState::Pressed => (wl_pointer::PRESSED, true),
};
let serial = self.serial.fetch_add(1);
self.surface_pointer_event(0, surface, |p| p.button(serial, 0, button, state));
self.surface_pointer_event(0, surface, |p| p.send_button(serial, 0, button, state));
self.surface_pointer_frame(surface);
if pressed && surface.belongs_to_toplevel() {
self.focus_surface(surface);
@ -502,7 +502,7 @@ impl WlSeatGlobal {
ScrollAxis::Horizontal => wl_pointer::HORIZONTAL_SCROLL,
ScrollAxis::Vertical => wl_pointer::VERTICAL_SCROLL,
};
self.surface_pointer_event(0, surface, |p| p.axis(0, axis, Fixed::from_int(delta)));
self.surface_pointer_event(0, surface, |p| p.send_axis(0, axis, Fixed::from_int(delta)));
self.surface_pointer_frame(surface);
}
}
@ -510,7 +510,7 @@ impl WlSeatGlobal {
// Motion callbacks
impl WlSeatGlobal {
pub fn motion_surface(&self, n: &WlSurface, x: Fixed, y: Fixed) {
self.surface_pointer_event(0, n, |p| p.motion(0, x, y));
self.surface_pointer_event(0, n, |p| p.send_motion(0, x, y));
self.surface_pointer_frame(n);
}
}
@ -527,7 +527,7 @@ impl WlSeatGlobal {
pub fn enter_surface(&self, n: &WlSurface, x: Fixed, y: Fixed) {
let serial = self.serial.fetch_add(1);
self.surface_pointer_event(0, n, |p| p.enter(serial, n.id, x, y));
self.surface_pointer_event(0, n, |p| p.send_enter(serial, n.id, x, y));
self.surface_pointer_frame(n);
}
}
@ -536,7 +536,7 @@ impl WlSeatGlobal {
impl WlSeatGlobal {
pub fn leave_surface(&self, n: &WlSurface) {
let serial = self.serial.fetch_add(1);
self.surface_pointer_event(0, n, |p| p.leave(serial, n.id));
self.surface_pointer_event(0, n, |p| p.send_leave(serial, n.id));
self.surface_pointer_frame(n);
}
}
@ -544,7 +544,7 @@ impl WlSeatGlobal {
// Unfocus callbacks
impl WlSeatGlobal {
pub fn unfocus_surface(&self, surface: &WlSurface) {
self.surface_kb_event(0, surface, |k| k.leave(0, surface.id))
self.surface_kb_event(0, surface, |k| k.send_leave(0, surface.id))
}
}
@ -558,11 +558,11 @@ impl WlSeatGlobal {
mods: Option<ModifierState>,
) {
let serial = self.serial.fetch_add(1);
self.surface_kb_event(0, surface, |k| k.key(serial, 0, key, state));
self.surface_kb_event(0, surface, |k| k.send_key(serial, 0, key, state));
let serial = self.serial.fetch_add(1);
if let Some(mods) = mods {
self.surface_kb_event(0, surface, |k| {
k.modifiers(
k.send_modifiers(
serial,
mods.mods_depressed,
mods.mods_latched,

View file

@ -1,5 +1,5 @@
use crate::client::{ClientError, DynEventFormatter};
use crate::client::{ClientError};
use crate::ifs::wl_seat::WlSeat;
use crate::object::Object;
use crate::utils::buffd::MsgParser;
@ -62,8 +62,8 @@ impl WlKeyboard {
Ok(Rc::new(fd))
}
pub fn keymap(self: &Rc<Self>, format: u32, fd: Rc<OwnedFd>, size: u32) -> DynEventFormatter {
Box::new(Keymap {
pub fn send_keymap(self: &Rc<Self>, format: u32, fd: Rc<OwnedFd>, size: u32) {
self.seat.client.event(Keymap {
self_id: self.id,
format,
fd,
@ -71,13 +71,13 @@ impl WlKeyboard {
})
}
pub fn enter(
pub fn send_enter(
self: &Rc<Self>,
serial: u32,
surface: WlSurfaceId,
keys: Vec<u32>,
) -> DynEventFormatter {
Box::new(EnterOut {
) {
self.seat.client.event(EnterOut {
self_id: self.id,
serial,
surface,
@ -85,16 +85,16 @@ impl WlKeyboard {
})
}
pub fn leave(self: &Rc<Self>, serial: u32, surface: WlSurfaceId) -> DynEventFormatter {
Box::new(Leave {
pub fn send_leave(self: &Rc<Self>, serial: u32, surface: WlSurfaceId) {
self.seat.client.event(Leave {
self_id: self.id,
serial,
surface,
})
}
pub fn key(self: &Rc<Self>, serial: u32, time: u32, key: u32, state: u32) -> DynEventFormatter {
Box::new(Key {
pub fn send_key(self: &Rc<Self>, serial: u32, time: u32, key: u32, state: u32) {
self.seat.client.event(Key {
self_id: self.id,
serial,
time,
@ -103,15 +103,15 @@ impl WlKeyboard {
})
}
pub fn modifiers(
pub fn send_modifiers(
self: &Rc<Self>,
serial: u32,
mods_depressed: u32,
mods_latched: u32,
mods_locked: u32,
group: u32,
) -> DynEventFormatter {
Box::new(Modifiers {
) {
self.seat.client.event(Modifiers {
self_id: self.id,
serial,
mods_depressed,
@ -121,8 +121,8 @@ impl WlKeyboard {
})
}
pub fn repeat_info(self: &Rc<Self>, rate: i32, delay: i32) -> DynEventFormatter {
Box::new(RepeatInfo {
pub fn send_repeat_info(self: &Rc<Self>, rate: i32, delay: i32) {
self.seat.client.event(RepeatInfo {
self_id: self.id,
rate,
delay,

View file

@ -1,5 +1,5 @@
use crate::client::{ClientError, DynEventFormatter};
use crate::client::{ClientError};
use crate::cursor::Cursor;
use crate::fixed::Fixed;
use crate::ifs::wl_seat::WlSeat;
@ -45,14 +45,14 @@ impl WlPointer {
}
}
pub fn enter(
self: &Rc<Self>,
pub fn send_enter(
&self,
serial: u32,
surface: WlSurfaceId,
x: Fixed,
y: Fixed,
) -> DynEventFormatter {
Box::new(Enter {
) {
self.seat.client.event(Enter {
self_id: self.id,
serial,
surface,
@ -61,16 +61,16 @@ impl WlPointer {
})
}
pub fn leave(self: &Rc<Self>, serial: u32, surface: WlSurfaceId) -> DynEventFormatter {
Box::new(Leave {
pub fn send_leave(&self, serial: u32, surface: WlSurfaceId) {
self.seat.client.event(Leave {
self_id: self.id,
serial,
surface,
})
}
pub fn motion(self: &Rc<Self>, time: u32, x: Fixed, y: Fixed) -> DynEventFormatter {
Box::new(Motion {
pub fn send_motion(&self, time: u32, x: Fixed, y: Fixed) {
self.seat.client.event(Motion {
self_id: self.id,
time,
surface_x: x,
@ -78,14 +78,14 @@ impl WlPointer {
})
}
pub fn button(
self: &Rc<Self>,
pub fn send_button(
&self,
serial: u32,
time: u32,
button: u32,
state: u32,
) -> DynEventFormatter {
Box::new(Button {
) {
self.seat.client.event(Button {
self_id: self.id,
serial,
time,
@ -94,8 +94,8 @@ impl WlPointer {
})
}
pub fn axis(self: &Rc<Self>, time: u32, axis: u32, value: Fixed) -> DynEventFormatter {
Box::new(Axis {
pub fn send_axis(&self, time: u32, axis: u32, value: Fixed) {
self.seat.client.event(Axis {
self_id: self.id,
time,
axis,
@ -104,21 +104,21 @@ impl WlPointer {
}
#[allow(dead_code)]
pub fn frame(self: &Rc<Self>) -> DynEventFormatter {
Box::new(Frame { self_id: self.id })
pub fn send_frame(&self) {
self.seat.client.event(Frame { self_id: self.id })
}
#[allow(dead_code)]
pub fn axis_source(self: &Rc<Self>, axis_source: u32) -> DynEventFormatter {
Box::new(AxisSource {
pub fn send_axis_source(&self, axis_source: u32) {
self.seat.client.event(AxisSource {
self_id: self.id,
axis_source,
})
}
#[allow(dead_code)]
pub fn axis_stop(self: &Rc<Self>, time: u32, axis: u32) -> DynEventFormatter {
Box::new(AxisStop {
pub fn send_axis_stop(&self, time: u32, axis: u32) {
self.seat.client.event(AxisStop {
self_id: self.id,
time,
axis,
@ -126,8 +126,8 @@ impl WlPointer {
}
#[allow(dead_code)]
pub fn axis_discrete(self: &Rc<Self>, axis: u32, discrete: i32) -> DynEventFormatter {
Box::new(AxisDiscrete {
pub fn send_axis_discrete(&self, axis: u32, discrete: i32) {
self.seat.client.event(AxisDiscrete {
self_id: self.id,
axis,
discrete,

View file

@ -39,10 +39,10 @@ impl WlShmGlobal {
});
client.add_client_obj(&obj)?;
for format in FORMATS {
client.event(Box::new(Format {
client.event(Format {
self_id: id,
format: format.wl_id.unwrap_or(format.drm),
}));
});
}
Ok(())
}

View file

@ -3,7 +3,7 @@ pub mod wl_subsurface;
pub mod xdg_surface;
use crate::backend::{KeyState, ScrollAxis, SeatId};
use crate::client::{Client, ClientError, DynEventFormatter, RequestParser};
use crate::client::{Client, ClientError, RequestParser};
use crate::fixed::Fixed;
use crate::ifs::wl_buffer::WlBuffer;
use crate::ifs::wl_callback::WlCallback;
@ -212,8 +212,8 @@ impl WlSurface {
false
}
fn enter_event(self: &Rc<Self>, output: WlOutputId) -> DynEventFormatter {
Box::new(Enter {
fn send_enter(&self, output: WlOutputId) {
self.client.event(Enter {
self_id: self.id,
output,
})
@ -346,7 +346,7 @@ impl WlSurface {
fn frame(&self, parser: MsgParser<'_, '_>) -> Result<(), FrameError> {
let req: Frame = self.parse(parser)?;
let cb = Rc::new(WlCallback::new(req.callback));
let cb = Rc::new(WlCallback::new(req.callback, &self.client));
self.client.add_client_obj(&cb)?;
self.pending.frame_request.borrow_mut().push(cb);
Ok(())
@ -393,7 +393,7 @@ impl WlSurface {
if let Some(buffer) = self.buffer.take() {
old_size = Some(buffer.rect);
if !buffer.destroyed() {
self.client.event(buffer.release());
buffer.send_release();
}
}
if let Some((dx, dy, buffer)) = buffer_change {

View file

@ -2,7 +2,7 @@ pub mod xdg_popup;
pub mod xdg_toplevel;
use crate::backend::SeatId;
use crate::client::{ClientError, DynEventFormatter};
use crate::client::{ClientError};
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
use crate::ifs::wl_surface::xdg_surface::xdg_popup::{XdgPopup, XdgPopupError};
use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel;
@ -181,13 +181,13 @@ impl XdgSurface {
self.geometry.get()
}
pub fn send_configure(self: &Rc<Self>) {
pub fn do_send_configure(&self) {
let serial = self.requested_serial.fetch_add(1) + 1;
self.surface.client.event(self.configure(serial));
self.send_configure(serial);
}
pub fn configure(self: &Rc<Self>, serial: u32) -> DynEventFormatter {
Box::new(Configure {
pub fn send_configure(&self, serial: u32) {
self.surface.client.event(Configure {
self_id: self.id,
serial,
})
@ -356,7 +356,7 @@ impl SurfaceExt for XdgSurface {
if let Some(ext) = self.ext.get() {
ext.initial_configure()?;
}
self.surface.client.event(self.configure(rse));
self.send_configure(rse);
}
// return CommitAction::AbortCommit;
}

View file

@ -1,5 +1,5 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use crate::client::{Client, ClientError};
use crate::cursor::KnownCursor;
use crate::fixed::Fixed;
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
@ -58,8 +58,8 @@ impl XdgPopup {
})
}
fn configure(self: &Rc<Self>, x: i32, y: i32, width: i32, height: i32) -> DynEventFormatter {
Box::new(Configure {
fn send_configure(&self, x: i32, y: i32, width: i32, height: i32) {
self.xdg.surface.client.event(Configure {
self_id: self.id,
x,
y,
@ -68,15 +68,15 @@ impl XdgPopup {
})
}
fn repositioned(self: &Rc<Self>, token: u32) -> DynEventFormatter {
Box::new(Repositioned {
fn send_repositioned(&self, token: u32) {
self.xdg.surface.client.event(Repositioned {
self_id: self.id,
token,
})
}
fn popup_done(self: &Rc<Self>) -> DynEventFormatter {
Box::new(PopupDone { self_id: self.id })
fn send_popup_done(&self) {
self.xdg.surface.client.event(PopupDone { self_id: self.id })
}
fn update_position(&self, parent: &XdgSurface) -> Result<(), XdgPopupError> {
@ -205,14 +205,14 @@ impl XdgPopup {
if let Some(parent) = self.parent.get() {
self.update_position(&parent)?;
let rel = self.relative_position.get();
self.xdg.surface.client.event(self.repositioned(req.token));
self.xdg.surface.client.event(self.configure(
self.send_repositioned(req.token);
self.send_configure(
rel.x1(),
rel.y1(),
rel.width(),
rel.height(),
));
self.xdg.send_configure();
);
self.xdg.do_send_configure();
}
Ok(())
}
@ -303,12 +303,12 @@ impl XdgSurfaceExt for XdgPopup {
if let Some(parent) = self.parent.get() {
self.update_position(&parent)?;
let rel = self.relative_position.get();
self.xdg.surface.client.event(self.configure(
self.send_configure(
rel.x1(),
rel.y1(),
rel.width(),
rel.height(),
));
);
}
Ok(())
}
@ -335,7 +335,7 @@ impl XdgSurfaceExt for XdgPopup {
} else {
if wl.take().is_some() {
self.destroy_node(true);
surface.client.event(self.popup_done());
self.send_popup_done();
}
}
}

View file

@ -1,7 +1,7 @@
use crate::backend::SeatId;
use crate::bugs::Bugs;
use crate::client::{Client, ClientError, DynEventFormatter};
use crate::client::{Client, ClientError};
use crate::cursor::KnownCursor;
use crate::fixed::Fixed;
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
@ -117,11 +117,8 @@ impl XdgToplevel {
};
if changed {
let rect = self.xdg.absolute_desired_extents.get();
self.xdg
.surface
.client
.event(self.configure_checked(rect.width(), rect.height()));
self.xdg.send_configure();
self.send_configure_checked(rect.width(), rect.height());
self.xdg.do_send_configure();
}
}
@ -132,7 +129,7 @@ impl XdgToplevel {
false
}
fn configure_checked(self: &Rc<Self>, mut width: i32, mut height: i32) -> DynEventFormatter {
fn send_configure_checked(&self, mut width: i32, mut height: i32) {
width = width.max(1);
height = height.max(1);
if self.bugs.get().respect_min_max_size {
@ -149,11 +146,11 @@ impl XdgToplevel {
height = height.min(max);
}
}
self.configure(width, height)
self.send_configure(width, height)
}
fn configure(self: &Rc<Self>, width: i32, height: i32) -> DynEventFormatter {
Box::new(ConfigureOut {
fn send_configure(&self, width: i32, height: i32) {
self.xdg.surface.client.event(ConfigureOut {
self_id: self.id,
width,
height,
@ -447,11 +444,8 @@ impl Node for XdgToplevel {
let nh = rect.height();
let de = self.xdg.absolute_desired_extents.get();
if de.width() != nw || de.height() != nh {
self.xdg
.surface
.client
.event(self.configure_checked(nw, nh));
self.xdg.send_configure();
self.send_configure_checked(nw, nh);
self.xdg.do_send_configure();
self.xdg.surface.client.flush();
}
self.xdg.set_absolute_desired_extents(rect);
@ -468,7 +462,7 @@ impl Node for XdgToplevel {
impl XdgSurfaceExt for XdgToplevel {
fn initial_configure(self: Rc<Self>) -> Result<(), XdgSurfaceError> {
self.xdg.surface.client.event(self.configure(0, 0));
self.send_configure(0, 0);
Ok(())
}
@ -498,10 +492,7 @@ impl XdgSurfaceExt for XdgToplevel {
let bindings = output.global.bindings.borrow_mut();
for binding in bindings.get(&self.xdg.surface.client.id) {
for binding in binding.values() {
self.xdg
.surface
.client
.event(self.xdg.surface.enter_event(binding.id));
self.xdg.surface.send_enter(binding.id);
}
}
}

View file

@ -1,4 +1,4 @@
use crate::client::{ClientError, DynEventFormatter};
use crate::client::{ClientError};
use crate::drm::dma::{DmaBuf, DmaBufPlane};
use crate::drm::INVALID_MODIFIER;
use crate::ifs::wl_buffer::{WlBuffer};
@ -25,8 +25,8 @@ const BOTTOM_FIRST: u32 = 4;
const MAX_PLANE: u32 = 3;
pub struct ZwpLinuxBufferParamsV1 {
id: ZwpLinuxBufferParamsV1Id,
parent: Rc<ZwpLinuxDmabufV1>,
pub id: ZwpLinuxBufferParamsV1Id,
pub parent: Rc<ZwpLinuxDmabufV1>,
planes: RefCell<AHashMap<u32, Add>>,
used: Cell<bool>,
}
@ -41,15 +41,15 @@ impl ZwpLinuxBufferParamsV1 {
}
}
fn created(self: &Rc<Self>, buffer_id: WlBufferId) -> DynEventFormatter {
Box::new(Created {
fn send_created(&self, buffer_id: WlBufferId) {
self.parent.client.event(Created {
self_id: self.id,
buffer: buffer_id,
})
}
fn failed(self: &Rc<Self>) -> DynEventFormatter {
Box::new(Failed { self_id: self.id })
fn send_failed(&self) {
self.parent.client.event(Failed { self_id: self.id })
}
fn destroy(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
@ -136,11 +136,11 @@ impl ZwpLinuxBufferParamsV1 {
}
match self.do_create(None, req.width, req.height, req.format, req.flags) {
Ok(id) => {
self.parent.client.event(self.created(id));
self.send_created(id);
}
Err(e) => {
log::debug!("Could not create a dmabuf buffer: {}", ErrorFmt(e));
self.parent.client.event(self.failed());
self.send_failed();
}
}
Ok(())

View file

@ -1,4 +1,4 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use crate::client::{Client, ClientError};
use crate::drm::INVALID_MODIFIER;
use crate::globals::{Global, GlobalName};
use crate::ifs::zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1;
@ -35,9 +35,9 @@ impl ZwpLinuxDmabufV1Global {
if let Some(ctx) = client.state.render_ctx.get() {
let formats = ctx.formats();
for format in formats.values() {
client.event(obj.format(format.drm));
obj.send_format(format.drm);
if version >= MODIFIERS_SINCE_VERSION {
client.event(obj.modifier(format.drm, INVALID_MODIFIER));
obj.send_modifier(format.drm, INVALID_MODIFIER);
}
}
}
@ -72,15 +72,15 @@ pub struct ZwpLinuxDmabufV1 {
}
impl ZwpLinuxDmabufV1 {
fn format(self: &Rc<Self>, format: u32) -> DynEventFormatter {
Box::new(Format {
fn send_format(&self, format: u32) {
self.client.event(Format {
self_id: self.id,
format,
})
}
fn modifier(self: &Rc<Self>, format: u32, modifier: u64) -> DynEventFormatter {
Box::new(Modifier {
fn send_modifier(&self, format: u32, modifier: u64) {
self.client.event(Modifier {
self_id: self.id,
format,
modifier_hi: (modifier >> 32) as _,

View file

@ -1,5 +1,5 @@
use crate::client::{ClientError, DynEventFormatter};
use crate::client::{ClientError};
use crate::ifs::wl_seat::WlSeat;
use crate::ifs::zwp_primary_selection_device_manager_v1::ZwpPrimarySelectionDeviceManagerV1;
use crate::object::Object;
@ -29,15 +29,15 @@ impl ZwpPrimarySelectionDeviceV1 {
}
}
pub fn data_offer(self: &Rc<Self>, offer: ZwpPrimarySelectionOfferV1Id) -> DynEventFormatter {
Box::new(DataOffer {
pub fn send_data_offer(&self, offer: ZwpPrimarySelectionOfferV1Id) {
self.manager.client.event(DataOffer {
self_id: self.id,
offer,
})
}
pub fn selection(self: &Rc<Self>, id: ZwpPrimarySelectionOfferV1Id) -> DynEventFormatter {
Box::new(Selection {
pub fn send_selection(&self, id: ZwpPrimarySelectionOfferV1Id) {
self.manager.client.event(Selection {
self_id: self.id,
id,
})

View file

@ -1,5 +1,5 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use std::mem;
use crate::client::{Client, ClientError};
use crate::ifs::wl_seat::WlSeatGlobal;
use crate::ifs::zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1;
use crate::object::Object;
@ -36,19 +36,27 @@ impl ZwpPrimarySelectionOfferV1 {
source: CloneCell::new(Some(src.clone())),
});
let mt = src.mime_types.borrow_mut();
let mut sent_offer = false;
seat.for_each_primary_selection_device(0, client.id, |device| {
client.event(device.data_offer(slf.id));
for mt in mt.deref() {
client.event(slf.offer(mt));
if !mem::replace(&mut sent_offer, true) {
device.send_data_offer(slf.id);
}
client.event(device.selection(id));
for mt in mt.deref() {
slf.send_offer(mt);
}
device.send_selection(id);
});
client.add_server_obj(&slf);
Some(slf)
if !sent_offer {
let _ = client.remove_obj(&*slf);
None
} else {
Some(slf)
}
}
pub fn offer(self: &Rc<Self>, mime_type: &str) -> DynEventFormatter {
Box::new(OfferOut {
pub fn send_offer(self: &Rc<Self>, mime_type: &str) {
self.client.event(OfferOut {
self_id: self.id,
mime_type: mime_type.to_string(),
})
@ -57,7 +65,7 @@ impl ZwpPrimarySelectionOfferV1 {
fn receive(&self, parser: MsgParser<'_, '_>) -> Result<(), ReceiveError> {
let req: ReceiveIn = self.client.parse(self, parser)?;
if let Some(src) = self.source.get() {
src.client.event(src.send(req.mime_type, req.fd));
src.send_send(req.mime_type, req.fd);
src.client.flush();
}
Ok(())

View file

@ -1,5 +1,5 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use crate::client::{Client, ClientError};
use crate::ifs::wl_seat::WlSeatGlobal;
use crate::ifs::zwp_primary_selection_offer_v1::ZwpPrimarySelectionOfferV1;
use crate::object::Object;
@ -45,7 +45,7 @@ impl ZwpPrimarySelectionSourceV1 {
if let Some(offer) = self.offer.set(None) {
offer.source.set(None);
}
self.client.event(self.cancelled());
self.send_cancelled();
self.client.flush();
}
@ -68,12 +68,12 @@ impl ZwpPrimarySelectionSourceV1 {
self.offer.take();
}
pub fn cancelled(self: &Rc<Self>) -> DynEventFormatter {
Box::new(Cancelled { self_id: self.id })
pub fn send_cancelled(&self) {
self.client.event(Cancelled { self_id: self.id })
}
pub fn send(self: &Rc<Self>, mime_type: &str, fd: Rc<OwnedFd>) -> DynEventFormatter {
Box::new(SendOut {
pub fn send_send(&self, mime_type: &str, fd: Rc<OwnedFd>) {
self.client.event(SendOut {
self_id: self.id,
mime_type: mime_type.to_string(),
fd,
@ -88,7 +88,7 @@ impl ZwpPrimarySelectionSourceV1 {
.insert(req.mime_type.to_string())
{
if let Some(offer) = self.offer.get() {
offer.client.event(offer.offer(req.mime_type));
offer.send_offer(req.mime_type);
}
}
Ok(())

View file

@ -72,7 +72,7 @@ impl ZxdgDecorationManagerV1 {
let tl = self.client.lookup(req.toplevel)?;
let obj = Rc::new(ZxdgToplevelDecorationV1::new(req.id, &self.client, &tl));
self.client.add_client_obj(&obj)?;
obj.send_configure();
obj.do_send_configure();
Ok(())
}
}

View file

@ -1,5 +1,5 @@
use crate::client::{Client, ClientError, DynEventFormatter};
use crate::client::{Client, ClientError};
use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::{Decoration, XdgToplevel};
use crate::object::Object;
use crate::utils::buffd::{MsgParser, MsgParserError};
@ -30,20 +30,20 @@ impl ZxdgToplevelDecorationV1 {
}
}
fn configure(self: &Rc<Self>, mode: u32) -> DynEventFormatter {
Box::new(Configure {
fn send_configure(&self, mode: u32) {
self.client.event(Configure {
self_id: self.id,
mode,
})
}
pub fn send_configure(self: &Rc<Self>) {
pub fn do_send_configure(&self) {
let mode = match self.toplevel.decoration.get() {
Decoration::Client => CLIENT_SIDE,
Decoration::Server => SERVER_SIDE,
};
self.client.event(self.configure(mode));
self.toplevel.xdg.send_configure();
self.send_configure(mode);
self.toplevel.xdg.do_send_configure();
}
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
@ -54,13 +54,13 @@ impl ZxdgToplevelDecorationV1 {
fn set_mode(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), SetModeError> {
let _req: SetMode = self.client.parse(&**self, parser)?;
self.send_configure();
self.do_send_configure();
Ok(())
}
fn unset_mode(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), UnsetModeError> {
let _req: UnsetMode = self.client.parse(&**self, parser)?;
self.send_configure();
self.do_send_configure();
Ok(())
}
}

View file

@ -1,10 +1,11 @@
use crate::async_engine::AsyncFd;
use crate::async_engine::{AsyncFd, Timeout};
use crate::utils::buffd::{BufFdError, BUF_SIZE, CMSG_BUF_SIZE};
use futures::{select, FutureExt};
use std::collections::VecDeque;
use std::mem::MaybeUninit;
use std::rc::Rc;
use std::slice;
use std::{mem, slice};
use futures::future::Fuse;
use uapi::{c, Errno, OwnedFd};
pub(super) const OUT_BUF_SIZE: usize = 2 * BUF_SIZE;
@ -14,70 +15,114 @@ pub(super) struct MsgFds {
pub(super) fds: Vec<Rc<OwnedFd>>,
}
pub struct OutBuffer {
pub(super) read_pos: usize,
pub(super) write_pos: usize,
pub(super) buf: *mut [MaybeUninit<u8>; OUT_BUF_SIZE],
pub(super) fds: VecDeque<MsgFds>,
}
impl Default for OutBuffer {
fn default() -> Self {
Self {
read_pos: 0,
write_pos: 0,
buf: Box::into_raw(Box::new([MaybeUninit::<u32>::uninit(); OUT_BUF_SIZE / 4])) as _,
fds: Default::default(),
}
}
}
impl OutBuffer {
pub fn write(&mut self, bytes: &[MaybeUninit<u8>]) {
if bytes.len() > OUT_BUF_SIZE - self.write_pos {
panic!("Out buffer overflow");
}
unsafe {
(*self.buf)[self.write_pos..self.write_pos + bytes.len()].copy_from_slice(bytes);
}
self.write_pos += bytes.len();
}
pub fn is_full(&self) -> bool {
self.write_pos > BUF_SIZE
}
pub fn len(&self) -> usize {
self.write_pos
}
}
const LIMIT_PENDING: usize = 10;
#[derive(Default)]
pub struct OutBufferSwapchain {
pub cur: OutBuffer,
pub pending: VecDeque<OutBuffer>,
pub free: Vec<OutBuffer>,
}
impl OutBufferSwapchain {
pub fn exceeds_limit(&self) -> bool {
self.pending.len() > LIMIT_PENDING
}
pub fn commit(&mut self) {
if self.cur.write_pos > 0 {
let new = self.free.pop().unwrap_or_else(|| {
log::warn!("new buffer");
Default::default()
});
let old = mem::replace(&mut self.cur, new);
self.pending.push_back(old);
}
}
}
pub struct BufFdOut {
fd: AsyncFd,
pub(super) out_pos: usize,
pub(super) out_buf: *mut [MaybeUninit<u8>; OUT_BUF_SIZE],
pub(super) fds: VecDeque<MsgFds>,
fd_ids: Vec<i32>,
cmsg_buf: Box<[MaybeUninit<u8>; CMSG_BUF_SIZE]>,
fd_ids: Vec<i32>,
}
impl BufFdOut {
pub fn new(fd: AsyncFd) -> Self {
Self {
fd,
out_pos: 0,
out_buf: Box::into_raw(Box::new([MaybeUninit::<u32>::uninit(); OUT_BUF_SIZE / 4])) as _,
fds: Default::default(),
fd_ids: vec![],
cmsg_buf: Box::new([MaybeUninit::uninit(); CMSG_BUF_SIZE]),
fd_ids: vec![],
}
}
pub fn write(&mut self, bytes: &[MaybeUninit<u8>]) {
if bytes.len() > OUT_BUF_SIZE - self.out_pos {
panic!("Out buffer overflow");
}
unsafe {
(*self.out_buf)[self.out_pos..self.out_pos + bytes.len()].copy_from_slice(bytes);
}
self.out_pos += bytes.len();
}
pub fn needs_flush(&self) -> bool {
self.out_pos > BUF_SIZE
}
pub async fn flush(&mut self) -> Result<(), BufFdError> {
let mut timeout = None;
let mut pos = 0;
while pos < self.out_pos {
if self.flush_sync(&mut pos)? {
pub async fn flush(&mut self, buf: &mut OutBuffer, timeout: &mut Option<Fuse<Timeout>>) -> Result<(), BufFdError> {
while buf.read_pos < buf.write_pos {
if self.flush_sync(buf)? {
self.fd.writable().await?;
if timeout.is_none() {
timeout = Some(self.fd.eng().timeout(5000)?.fuse());
*timeout = Some(self.fd.eng().timeout(5000)?.fuse());
}
select! {
_ = timeout.as_mut().unwrap() => return Err(BufFdError::Timeout),
_ = timeout.as_mut().unwrap() => {
return Err(BufFdError::Timeout);
},
res = self.fd.writable().fuse() => res?,
}
}
}
self.out_pos = 0;
buf.read_pos = 0;
buf.write_pos = 0;
Ok(())
}
fn flush_sync(&mut self, pos: &mut usize) -> Result<bool, BufFdError> {
while *pos < self.out_pos {
let mut buf = unsafe { &(*self.out_buf)[*pos..self.out_pos] };
fn flush_sync(&mut self, buffer: &mut OutBuffer) -> Result<bool, BufFdError> {
while buffer.read_pos < buffer.write_pos {
let mut buf = unsafe { &(*buffer.buf)[buffer.read_pos..buffer.write_pos] };
let mut cmsg_len = 0;
let mut fds_opt = None;
{
let mut f = self.fds.front().map(|f| f.pos);
if f == Some(*pos) {
let fds = self.fds.pop_front().unwrap();
let mut f = buffer.fds.front().map(|f| f.pos);
if f == Some(buffer.read_pos) {
let fds = buffer.fds.pop_front().unwrap();
self.fd_ids.clear();
self.fd_ids.extend(fds.fds.iter().map(|f| f.raw()));
let hdr = c::cmsghdr {
@ -88,10 +133,10 @@ impl BufFdOut {
let mut cmsg_buf = &mut self.cmsg_buf[..];
cmsg_len = uapi::cmsg_write(&mut cmsg_buf, hdr, &self.fd_ids[..]).unwrap();
fds_opt = Some(fds);
f = self.fds.front().map(|f| f.pos)
f = buffer.fds.front().map(|f| f.pos)
}
if let Some(next_pos) = f {
buf = &buf[..next_pos - *pos];
buf = &buf[..next_pos - buffer.read_pos];
}
}
let hdr = uapi::Msghdr {
@ -104,23 +149,23 @@ impl BufFdOut {
Ok(b) => b,
Err(Errno(c::EAGAIN)) => {
if let Some(fds) = fds_opt {
self.fds.push_front(fds);
buffer.fds.push_front(fds);
}
return Ok(true);
}
Err(Errno(c::ECONNRESET)) => return Err(BufFdError::Closed),
Err(e) => return Err(BufFdError::Io(e.into())),
};
*pos += bytes_sent;
buffer.read_pos += bytes_sent;
}
Ok(false)
}
}
impl Drop for BufFdOut {
impl Drop for OutBuffer {
fn drop(&mut self) {
unsafe {
Box::from_raw(self.out_buf as *mut [MaybeUninit<u32>; OUT_BUF_SIZE / 4]);
Box::from_raw(self.buf as *mut [MaybeUninit<u32>; OUT_BUF_SIZE / 4]);
}
}
}

View file

@ -1,21 +1,21 @@
use crate::fixed::Fixed;
use crate::object::ObjectId;
use crate::utils::buffd::buf_out::{BufFdOut, MsgFds};
use crate::utils::buffd::buf_out::{MsgFds, OutBuffer};
use std::mem;
use std::mem::MaybeUninit;
use std::rc::Rc;
use uapi::OwnedFd;
pub struct MsgFormatter<'a> {
buf: &'a mut BufFdOut,
buf: &'a mut OutBuffer,
pos: usize,
fds: &'a mut Vec<Rc<OwnedFd>>,
}
impl<'a> MsgFormatter<'a> {
pub fn new(buf: &'a mut BufFdOut, fds: &'a mut Vec<Rc<OwnedFd>>) -> Self {
pub fn new(buf: &'a mut OutBuffer, fds: &'a mut Vec<Rc<OwnedFd>>) -> Self {
Self {
pos: buf.out_pos,
pos: buf.write_pos,
buf,
fds,
}
@ -62,7 +62,7 @@ impl<'a> MsgFormatter<'a> {
#[allow(dead_code)]
pub fn array<F: FnOnce(&mut MsgFormatter<'_>)>(&mut self, f: F) -> &mut Self {
let pos = self.buf.out_pos;
let pos = self.buf.write_pos;
self.uint(0);
let len = {
let mut fmt = MsgFormatter {
@ -71,13 +71,13 @@ impl<'a> MsgFormatter<'a> {
fds: self.fds,
};
f(&mut fmt);
let len = self.buf.out_pos - pos - 4;
let len = self.buf.write_pos - pos - 4;
let none = [MaybeUninit::new(0); 4];
self.buf.write(&none[..self.buf.out_pos.wrapping_neg() & 3]);
self.buf.write(&none[..self.buf.write_pos.wrapping_neg() & 3]);
len as u32
};
unsafe {
(*self.buf.out_buf)[pos..pos + 4].copy_from_slice(uapi::as_maybe_uninit_bytes(&len));
(*self.buf.buf)[pos..pos + 4].copy_from_slice(uapi::as_maybe_uninit_bytes(&len));
}
self
}
@ -86,16 +86,16 @@ impl<'a> MsgFormatter<'a> {
self.uint(mem::size_of_val(t) as u32);
self.buf.write(uapi::as_maybe_uninit_bytes(t));
let none = [MaybeUninit::new(0); 4];
self.buf.write(&none[..self.buf.out_pos.wrapping_neg() & 3]);
self.buf.write(&none[..self.buf.write_pos.wrapping_neg() & 3]);
self
}
pub fn write_len(self) {
assert!(self.buf.out_pos - self.pos >= 8);
assert!(self.buf.write_pos - self.pos >= 8);
assert_eq!(self.pos % 4, 0);
unsafe {
let second_ptr = (self.buf.out_buf as *mut u8).add(self.pos + 4) as *mut u32;
let len = ((self.buf.out_pos - self.pos) as u32) << 16;
let second_ptr = (self.buf.buf as *mut u8).add(self.pos + 4) as *mut u32;
let len = ((self.buf.write_pos - self.pos) as u32) << 16;
*second_ptr |= len;
}
if self.fds.len() > 0 {

View file

@ -1,6 +1,6 @@
use crate::async_engine::AsyncError;
pub use buf_in::BufFdIn;
pub use buf_out::BufFdOut;
pub use buf_out::{BufFdOut, OutBufferSwapchain};
pub use formatter::MsgFormatter;
pub use parser::{MsgParser, MsgParserError};
use thiserror::Error;

View file

@ -33,10 +33,6 @@ impl<T> AsyncQueue<T> {
AsyncQueuePop { queue: self }
}
pub fn size(&self) -> usize {
self.data.borrow().len()
}
pub fn clear(&self) {
mem::take(&mut *self.data.borrow_mut());
}