autocommit 2022-01-09 14:36:34 CET
This commit is contained in:
parent
02d1c90501
commit
928f94daa6
14 changed files with 200 additions and 102 deletions
|
|
@ -24,6 +24,7 @@ use uapi::c;
|
||||||
use xcb_dl::{ffi, Xcb, XcbShm, XcbXinput, XcbXkb};
|
use xcb_dl::{ffi, Xcb, XcbShm, XcbXinput, XcbXkb};
|
||||||
use xcb_dl_util::error::{XcbError, XcbErrorParser};
|
use xcb_dl_util::error::{XcbError, XcbErrorParser};
|
||||||
use xcb_dl_util::xcb_box::XcbBox;
|
use xcb_dl_util::xcb_box::XcbBox;
|
||||||
|
use crate::utils::clonecell::CloneCell;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum XorgBackendError {
|
pub enum XorgBackendError {
|
||||||
|
|
@ -246,7 +247,7 @@ impl XorgBackend {
|
||||||
width: Cell::new(0),
|
width: Cell::new(0),
|
||||||
height: Cell::new(0),
|
height: Cell::new(0),
|
||||||
image: RefCell::new(None),
|
image: RefCell::new(None),
|
||||||
cb: RefCell::new(None),
|
cb: CloneCell::new(None),
|
||||||
});
|
});
|
||||||
{
|
{
|
||||||
let class = "i4\0i4\0";
|
let class = "i4\0i4\0";
|
||||||
|
|
@ -378,7 +379,7 @@ impl XorgBackend {
|
||||||
_kb: info.deviceid,
|
_kb: info.deviceid,
|
||||||
mouse: info.attachment,
|
mouse: info.attachment,
|
||||||
removed: Cell::new(false),
|
removed: Cell::new(false),
|
||||||
cb: RefCell::new(None),
|
cb: CloneCell::new(None),
|
||||||
events: RefCell::new(Default::default()),
|
events: RefCell::new(Default::default()),
|
||||||
button_map: Default::default(),
|
button_map: Default::default(),
|
||||||
last_position: Cell::new((0, 0)),
|
last_position: Cell::new((0, 0)),
|
||||||
|
|
@ -685,9 +686,8 @@ impl XorgBackend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let buffer = surface.buffer.borrow();
|
if let Some(buffer) = surface.buffer.get() {
|
||||||
if let Some(buffer) = &*buffer {
|
self.render_buffer(image, &buffer, x, y);
|
||||||
self.render_buffer(image, buffer, x, y);
|
|
||||||
let mut fr = surface.frame_requests.borrow_mut();
|
let mut fr = surface.frame_requests.borrow_mut();
|
||||||
for cb in fr.drain(..) {
|
for cb in fr.drain(..) {
|
||||||
surface.client.dispatch_frame_requests.push(cb);
|
surface.client.dispatch_frame_requests.push(cb);
|
||||||
|
|
@ -776,7 +776,7 @@ struct XorgOutput {
|
||||||
width: Cell<u32>,
|
width: Cell<u32>,
|
||||||
height: Cell<u32>,
|
height: Cell<u32>,
|
||||||
image: RefCell<Option<Image<Rc<ServerMem>>>>,
|
image: RefCell<Option<Image<Rc<ServerMem>>>>,
|
||||||
cb: RefCell<Option<Rc<dyn Fn()>>>,
|
cb: CloneCell<Option<Rc<dyn Fn()>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for XorgOutput {
|
impl Drop for XorgOutput {
|
||||||
|
|
@ -790,7 +790,7 @@ impl Drop for XorgOutput {
|
||||||
|
|
||||||
impl XorgOutput {
|
impl XorgOutput {
|
||||||
fn changed(&self) {
|
fn changed(&self) {
|
||||||
if let Some(cb) = self.cb.borrow().clone() {
|
if let Some(cb) = self.cb.get() {
|
||||||
cb();
|
cb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -814,7 +814,7 @@ impl Output for XorgOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_change(&self, cb: Rc<dyn Fn()>) {
|
fn on_change(&self, cb: Rc<dyn Fn()>) {
|
||||||
*self.cb.borrow_mut() = Some(cb);
|
self.cb.set(Some(cb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -824,7 +824,7 @@ struct XorgSeat {
|
||||||
_kb: ffi::xcb_input_device_id_t,
|
_kb: ffi::xcb_input_device_id_t,
|
||||||
mouse: ffi::xcb_input_device_id_t,
|
mouse: ffi::xcb_input_device_id_t,
|
||||||
removed: Cell<bool>,
|
removed: Cell<bool>,
|
||||||
cb: RefCell<Option<Rc<dyn Fn()>>>,
|
cb: CloneCell<Option<Rc<dyn Fn()>>>,
|
||||||
events: RefCell<VecDeque<SeatEvent>>,
|
events: RefCell<VecDeque<SeatEvent>>,
|
||||||
button_map: CopyHashMap<u32, u32>,
|
button_map: CopyHashMap<u32, u32>,
|
||||||
last_position: Cell<(ffi::xcb_input_fp1616_t, ffi::xcb_input_fp1616_t)>,
|
last_position: Cell<(ffi::xcb_input_fp1616_t, ffi::xcb_input_fp1616_t)>,
|
||||||
|
|
@ -832,7 +832,7 @@ struct XorgSeat {
|
||||||
|
|
||||||
impl XorgSeat {
|
impl XorgSeat {
|
||||||
fn changed(&self) {
|
fn changed(&self) {
|
||||||
if let Some(cb) = self.cb.borrow().clone() {
|
if let Some(cb) = self.cb.get() {
|
||||||
cb();
|
cb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -889,6 +889,6 @@ impl Seat for XorgSeat {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_change(&self, cb: Rc<dyn Fn()>) {
|
fn on_change(&self, cb: Rc<dyn Fn()>) {
|
||||||
*self.cb.borrow_mut() = Some(cb);
|
self.cb.set(Some(cb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,7 @@ impl Clients {
|
||||||
dispatch_frame_requests: AsyncQueue::new(),
|
dispatch_frame_requests: AsyncQueue::new(),
|
||||||
});
|
});
|
||||||
let display = Rc::new(WlDisplay::new(&data));
|
let display = Rc::new(WlDisplay::new(&data));
|
||||||
*data.objects.display.borrow_mut() = Some(display.clone());
|
data.objects.display.set(Some(display.clone()));
|
||||||
data.objects.add_client_object(display).expect("");
|
data.objects.add_client_object(display).expect("");
|
||||||
let client = ClientHolder {
|
let client = ClientHolder {
|
||||||
_handler: global.eng.spawn(tasks::client(data.clone(), recv)),
|
_handler: global.eng.spawn(tasks::client(data.clone(), recv)),
|
||||||
|
|
@ -365,7 +365,7 @@ impl Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn display(&self) -> Result<Rc<WlDisplay>, ClientError> {
|
pub fn display(&self) -> Result<Rc<WlDisplay>, ClientError> {
|
||||||
match self.objects.display.borrow_mut().clone() {
|
match self.objects.display.get() {
|
||||||
Some(d) => Ok(d),
|
Some(d) => Ok(d),
|
||||||
_ => Err(ClientError::NotADisplay(WL_DISPLAY_ID)),
|
_ => Err(ClientError::NotADisplay(WL_DISPLAY_ID)),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,10 @@ use ahash::AHashMap;
|
||||||
use std::cell::{RefCell, RefMut};
|
use std::cell::{RefCell, RefMut};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use crate::utils::clonecell::CloneCell;
|
||||||
|
|
||||||
pub struct Objects {
|
pub struct Objects {
|
||||||
pub display: RefCell<Option<Rc<WlDisplay>>>,
|
pub display: CloneCell<Option<Rc<WlDisplay>>>,
|
||||||
registry: CopyHashMap<ObjectId, Rc<dyn Object>>,
|
registry: CopyHashMap<ObjectId, Rc<dyn Object>>,
|
||||||
registries: CopyHashMap<WlRegistryId, Rc<WlRegistry>>,
|
registries: CopyHashMap<WlRegistryId, Rc<WlRegistry>>,
|
||||||
pub surfaces: CopyHashMap<WlSurfaceId, Rc<WlSurface>>,
|
pub surfaces: CopyHashMap<WlSurfaceId, Rc<WlSurface>>,
|
||||||
|
|
@ -33,7 +34,7 @@ const SEG_SIZE: usize = 8 * mem::size_of::<usize>();
|
||||||
impl Objects {
|
impl Objects {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
display: RefCell::new(None),
|
display: CloneCell::new(None),
|
||||||
registry: Default::default(),
|
registry: Default::default(),
|
||||||
registries: Default::default(),
|
registries: Default::default(),
|
||||||
surfaces: Default::default(),
|
surfaces: Default::default(),
|
||||||
|
|
@ -54,7 +55,7 @@ impl Objects {
|
||||||
}
|
}
|
||||||
registry.clear();
|
registry.clear();
|
||||||
}
|
}
|
||||||
*self.display.borrow_mut() = None;
|
self.display.set(None);
|
||||||
self.regions.clear();
|
self.regions.clear();
|
||||||
self.registries.clear();
|
self.registries.clear();
|
||||||
self.surfaces.clear();
|
self.surfaces.clear();
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ impl WlBuffer {
|
||||||
{
|
{
|
||||||
let surfaces = self.surfaces.lock();
|
let surfaces = self.surfaces.lock();
|
||||||
for surface in surfaces.values() {
|
for surface in surfaces.values() {
|
||||||
*surface.buffer.borrow_mut() = None;
|
surface.buffer.set(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.client.remove_obj(self).await?;
|
self.client.remove_obj(self).await?;
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,14 @@ use crate::utils::buffd::MsgParser;
|
||||||
use crate::utils::copyhashmap::CopyHashMap;
|
use crate::utils::copyhashmap::CopyHashMap;
|
||||||
use crate::xkbcommon::XkbContext;
|
use crate::xkbcommon::XkbContext;
|
||||||
use crate::State;
|
use crate::State;
|
||||||
use ahash::AHashMap;
|
use ahash::{AHashMap, AHashSet};
|
||||||
use bstr::ByteSlice;
|
use bstr::ByteSlice;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
pub use types::*;
|
pub use types::*;
|
||||||
use uapi::{c, OwnedFd};
|
use uapi::{c, OwnedFd};
|
||||||
|
use crate::utils::clonecell::CloneCell;
|
||||||
|
|
||||||
id!(WlSeatId);
|
id!(WlSeatId);
|
||||||
|
|
||||||
|
|
@ -42,6 +43,8 @@ const TOUCH: u32 = 4;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
const MISSING_CAPABILITY: u32 = 0;
|
const MISSING_CAPABILITY: u32 = 0;
|
||||||
|
|
||||||
|
const BTN_LEFT: u32 = 0x110;
|
||||||
|
|
||||||
pub struct WlSeatGlobal {
|
pub struct WlSeatGlobal {
|
||||||
name: GlobalName,
|
name: GlobalName,
|
||||||
state: Rc<State>,
|
state: Rc<State>,
|
||||||
|
|
@ -50,7 +53,9 @@ pub struct WlSeatGlobal {
|
||||||
move_start_pos: Cell<(Fixed, Fixed)>,
|
move_start_pos: Cell<(Fixed, Fixed)>,
|
||||||
extents_start_pos: Cell<(i32, i32)>,
|
extents_start_pos: Cell<(i32, i32)>,
|
||||||
pos: Cell<(Fixed, Fixed)>,
|
pos: Cell<(Fixed, Fixed)>,
|
||||||
cursor_node: RefCell<Rc<dyn Node>>,
|
cursor_node: CloneCell<Rc<dyn Node>>,
|
||||||
|
keyboard_node: CloneCell<Rc<dyn Node>>,
|
||||||
|
pressed_keys: RefCell<AHashSet<u32>>,
|
||||||
bindings: RefCell<AHashMap<ClientId, AHashMap<WlSeatId, Rc<WlSeatObj>>>>,
|
bindings: RefCell<AHashMap<ClientId, AHashMap<WlSeatId, Rc<WlSeatObj>>>>,
|
||||||
layout: Rc<OwnedFd>,
|
layout: Rc<OwnedFd>,
|
||||||
layout_size: u32,
|
layout_size: u32,
|
||||||
|
|
@ -82,7 +87,9 @@ impl WlSeatGlobal {
|
||||||
move_start_pos: Cell::new((Fixed(0), Fixed(0))),
|
move_start_pos: Cell::new((Fixed(0), Fixed(0))),
|
||||||
extents_start_pos: Cell::new((0, 0)),
|
extents_start_pos: Cell::new((0, 0)),
|
||||||
pos: Cell::new((Fixed(0), Fixed(0))),
|
pos: Cell::new((Fixed(0), Fixed(0))),
|
||||||
cursor_node: RefCell::new(state.root.clone()),
|
cursor_node: CloneCell::new(state.root.clone()),
|
||||||
|
keyboard_node: CloneCell::new(state.root.clone()),
|
||||||
|
pressed_keys: RefCell::new(Default::default()),
|
||||||
bindings: Default::default(),
|
bindings: Default::default(),
|
||||||
layout,
|
layout,
|
||||||
layout_size,
|
layout_size,
|
||||||
|
|
@ -90,7 +97,7 @@ impl WlSeatGlobal {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_(&self, node: &Rc<ToplevelNode>) {
|
pub fn move_(&self, node: &Rc<ToplevelNode>) {
|
||||||
let cursor = self.cursor_node.borrow().clone();
|
let cursor = self.cursor_node.get();
|
||||||
if cursor.id() == node.id() {
|
if cursor.id() == node.id() {
|
||||||
self.move_.set(true);
|
self.move_.set(true);
|
||||||
self.move_start_pos.set(self.pos.get());
|
self.move_start_pos.set(self.pos.get());
|
||||||
|
|
@ -119,21 +126,42 @@ impl WlSeatGlobal {
|
||||||
self.handle_new_position(x, y).await;
|
self.handle_new_position(x, y).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_each_pointer<C>(&self, client: ClientId, mut f: C)
|
fn for_each_seat<C>(&self, client: ClientId, mut f: C)
|
||||||
where
|
where
|
||||||
C: FnMut(&Rc<WlPointer>),
|
C: FnMut(&Rc<WlSeatObj>),
|
||||||
{
|
{
|
||||||
let bindings = self.bindings.borrow();
|
let bindings = self.bindings.borrow();
|
||||||
if let Some(hm) = bindings.get(&client) {
|
if let Some(hm) = bindings.get(&client) {
|
||||||
for seat in hm.values() {
|
for seat in hm.values() {
|
||||||
let pointers = seat.pointers.lock();
|
f(seat);
|
||||||
for pointer in pointers.values() {
|
|
||||||
f(pointer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn for_each_pointer<C>(&self, client: ClientId, mut f: C)
|
||||||
|
where
|
||||||
|
C: FnMut(&Rc<WlPointer>),
|
||||||
|
{
|
||||||
|
self.for_each_seat(client, |seat| {
|
||||||
|
let pointers = seat.pointers.lock();
|
||||||
|
for pointer in pointers.values() {
|
||||||
|
f(pointer);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn for_each_kb<C>(&self, client: ClientId, mut f: C)
|
||||||
|
where
|
||||||
|
C: FnMut(&Rc<WlKeyboard>),
|
||||||
|
{
|
||||||
|
self.for_each_seat(client, |seat| {
|
||||||
|
let keyboards = seat.keyboards.lock();
|
||||||
|
for keyboard in keyboards.values() {
|
||||||
|
f(keyboard);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async fn tl_pointer_event<F>(&self, tl: &ToplevelNode, mut f: F)
|
async fn tl_pointer_event<F>(&self, tl: &ToplevelNode, mut f: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&Rc<WlPointer>) -> DynEventFormatter,
|
F: FnMut(&Rc<WlPointer>) -> DynEventFormatter,
|
||||||
|
|
@ -145,9 +173,20 @@ impl WlSeatGlobal {
|
||||||
let _ = client.flush().await;
|
let _ = client.flush().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn tl_kb_event<F>(&self, tl: &ToplevelNode, mut f: F)
|
||||||
|
where
|
||||||
|
F: FnMut(&Rc<WlKeyboard>) -> DynEventFormatter,
|
||||||
|
{
|
||||||
|
let client = &tl.surface.surface.surface.client;
|
||||||
|
self.for_each_kb(client.id, |p| {
|
||||||
|
client.event_locked(f(p));
|
||||||
|
});
|
||||||
|
let _ = client.flush().await;
|
||||||
|
}
|
||||||
|
|
||||||
async fn handle_new_position(&self, x: Fixed, y: Fixed) {
|
async fn handle_new_position(&self, x: Fixed, y: Fixed) {
|
||||||
self.pos.set((x, y));
|
self.pos.set((x, y));
|
||||||
let cur_node = self.cursor_node.borrow().clone();
|
let cur_node = self.cursor_node.get();
|
||||||
if self.move_.get() {
|
if self.move_.get() {
|
||||||
if let NodeKind::Toplevel(tn) = cur_node.into_kind() {
|
if let NodeKind::Toplevel(tn) = cur_node.into_kind() {
|
||||||
let (move_start_x, move_start_y) = self.move_start_pos.get();
|
let (move_start_x, move_start_y) = self.move_start_pos.get();
|
||||||
|
|
@ -172,7 +211,7 @@ impl WlSeatGlobal {
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
enter = true;
|
enter = true;
|
||||||
*self.cursor_node.borrow_mut() = node_dyn;
|
self.cursor_node.set(node_dyn);
|
||||||
}
|
}
|
||||||
if let NodeKind::Toplevel(tl) = &node {
|
if let NodeKind::Toplevel(tl) = &node {
|
||||||
let ee = tl.surface.surface.surface.effective_extents.get();
|
let ee = tl.surface.surface.surface.effective_extents.get();
|
||||||
|
|
@ -196,19 +235,41 @@ impl WlSeatGlobal {
|
||||||
if state == KeyState::Released {
|
if state == KeyState::Released {
|
||||||
self.move_.set(false);
|
self.move_.set(false);
|
||||||
}
|
}
|
||||||
let node = self.cursor_node.borrow().clone().into_kind();
|
let node = self.cursor_node.get();
|
||||||
if let NodeKind::Toplevel(node) = node {
|
let mut enter = false;
|
||||||
|
if button == BTN_LEFT {
|
||||||
|
let kb_node = self.keyboard_node.get();
|
||||||
|
if kb_node.id() != node.id() {
|
||||||
|
enter = true;
|
||||||
|
if let NodeKind::Toplevel(tl) = kb_node.clone().into_kind() {
|
||||||
|
self.tl_kb_event(&tl, |k| k.leave(0, tl.surface.surface.surface.id))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
self.keyboard_node.set(node.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let NodeKind::Toplevel(node) = node.into_kind() {
|
||||||
let state = match state {
|
let state = match state {
|
||||||
KeyState::Released => wl_pointer::RELEASED,
|
KeyState::Released => wl_pointer::RELEASED,
|
||||||
KeyState::Pressed => wl_pointer::PRESSED,
|
KeyState::Pressed => wl_pointer::PRESSED,
|
||||||
};
|
};
|
||||||
self.tl_pointer_event(&node, |p| p.button(0, 0, button, state))
|
self.tl_pointer_event(&node, |p| p.button(0, 0, button, state))
|
||||||
.await;
|
.await;
|
||||||
|
if enter {
|
||||||
|
self.tl_kb_event(&node, |k| {
|
||||||
|
k.enter(
|
||||||
|
0,
|
||||||
|
node.surface.surface.surface.id,
|
||||||
|
self.pressed_keys.borrow().iter().cloned().collect(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn scroll_event(&self, delta: i32, axis: ScrollAxis) {
|
async fn scroll_event(&self, delta: i32, axis: ScrollAxis) {
|
||||||
let node = self.cursor_node.borrow().clone().into_kind();
|
let node = self.cursor_node.get().into_kind();
|
||||||
if let NodeKind::Toplevel(node) = node {
|
if let NodeKind::Toplevel(node) = node {
|
||||||
let axis = match axis {
|
let axis = match axis {
|
||||||
ScrollAxis::Horizontal => wl_pointer::HORIZONTAL_SCROLL,
|
ScrollAxis::Horizontal => wl_pointer::HORIZONTAL_SCROLL,
|
||||||
|
|
@ -219,7 +280,31 @@ impl WlSeatGlobal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn key_event(&self, _key: u32, _state: KeyState) {}
|
async fn key_event(&self, key: u32, state: KeyState) {
|
||||||
|
let state = {
|
||||||
|
let mut pk = self.pressed_keys.borrow_mut();
|
||||||
|
match state {
|
||||||
|
KeyState::Released => {
|
||||||
|
if !pk.remove(&key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log::info!("release");
|
||||||
|
wl_keyboard::RELEASED
|
||||||
|
}
|
||||||
|
KeyState::Pressed => {
|
||||||
|
if !pk.insert(key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log::info!("press");
|
||||||
|
wl_keyboard::PRESSED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let node = self.keyboard_node.get().into_kind();
|
||||||
|
if let NodeKind::Toplevel(node) = node {
|
||||||
|
self.tl_kb_event(&node, |k| k.key(0, 0, key, state)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn bind_(
|
async fn bind_(
|
||||||
self: Rc<Self>,
|
self: Rc<Self>,
|
||||||
|
|
@ -311,11 +396,7 @@ impl WlSeatObj {
|
||||||
self.client.add_client_obj(&p)?;
|
self.client.add_client_obj(&p)?;
|
||||||
self.keyboards.set(req.id, p.clone());
|
self.keyboards.set(req.id, p.clone());
|
||||||
self.client
|
self.client
|
||||||
.event(p.keymap(
|
.event(p.keymap(wl_keyboard::XKB_V1, p.keymap_fd()?, self.global.layout_size))
|
||||||
wl_keyboard::XKB_V1,
|
|
||||||
p.keymap_fd()?,
|
|
||||||
self.global.layout_size,
|
|
||||||
))
|
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,8 @@ const REPEAT_INFO: u32 = 5;
|
||||||
const NO_KEYMAP: u32 = 0;
|
const NO_KEYMAP: u32 = 0;
|
||||||
pub(super) const XKB_V1: u32 = 1;
|
pub(super) const XKB_V1: u32 = 1;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
pub(super) const RELEASED: u32 = 0;
|
||||||
const RELEASED: u32 = 0;
|
pub(super) const PRESSED: u32 = 1;
|
||||||
#[allow(dead_code)]
|
|
||||||
const PRESSED: u32 = 1;
|
|
||||||
|
|
||||||
id!(WlKeyboardId);
|
id!(WlKeyboardId);
|
||||||
|
|
||||||
|
|
@ -65,7 +63,7 @@ impl WlKeyboard {
|
||||||
rem as usize,
|
rem as usize,
|
||||||
);
|
);
|
||||||
match res {
|
match res {
|
||||||
Ok(_) | Err(Errno(c::EINTR)) => { },
|
Ok(_) | Err(Errno(c::EINTR)) => {}
|
||||||
Err(e) => return Err(WlKeyboardError::KeymapCopy(e.into())),
|
Err(e) => return Err(WlKeyboardError::KeymapCopy(e.into())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ use crate::clientmem::ClientMem;
|
||||||
use crate::ifs::wl_buffer::WlBuffer;
|
use crate::ifs::wl_buffer::WlBuffer;
|
||||||
use crate::object::{Interface, Object, ObjectId};
|
use crate::object::{Interface, Object, ObjectId};
|
||||||
use crate::utils::buffd::MsgParser;
|
use crate::utils::buffd::MsgParser;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
pub use types::*;
|
pub use types::*;
|
||||||
use uapi::OwnedFd;
|
use uapi::OwnedFd;
|
||||||
|
use crate::utils::clonecell::CloneCell;
|
||||||
|
|
||||||
const CREATE_BUFFER: u32 = 0;
|
const CREATE_BUFFER: u32 = 0;
|
||||||
const DESTROY: u32 = 1;
|
const DESTROY: u32 = 1;
|
||||||
|
|
@ -20,7 +20,7 @@ pub struct WlShmPool {
|
||||||
id: WlShmPoolId,
|
id: WlShmPoolId,
|
||||||
client: Rc<Client>,
|
client: Rc<Client>,
|
||||||
fd: OwnedFd,
|
fd: OwnedFd,
|
||||||
mem: RefCell<Rc<ClientMem>>,
|
mem: CloneCell<Rc<ClientMem>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WlShmPool {
|
impl WlShmPool {
|
||||||
|
|
@ -33,7 +33,7 @@ impl WlShmPool {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
id,
|
id,
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
mem: RefCell::new(Rc::new(ClientMem::new(fd.raw(), len)?)),
|
mem: CloneCell::new(Rc::new(ClientMem::new(fd.raw(), len)?)),
|
||||||
fd,
|
fd,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -47,7 +47,6 @@ impl WlShmPool {
|
||||||
if req.height < 0 || req.width < 0 || req.stride < 0 || req.offset < 0 {
|
if req.height < 0 || req.width < 0 || req.stride < 0 || req.offset < 0 {
|
||||||
return Err(CreateBufferError::NegativeParameters);
|
return Err(CreateBufferError::NegativeParameters);
|
||||||
}
|
}
|
||||||
let mem = self.mem.borrow();
|
|
||||||
let buffer = Rc::new(WlBuffer::new(
|
let buffer = Rc::new(WlBuffer::new(
|
||||||
req.id,
|
req.id,
|
||||||
&self.client,
|
&self.client,
|
||||||
|
|
@ -56,7 +55,7 @@ impl WlShmPool {
|
||||||
req.height as u32,
|
req.height as u32,
|
||||||
req.stride as u32,
|
req.stride as u32,
|
||||||
format,
|
format,
|
||||||
&mem,
|
&self.mem.get(),
|
||||||
)?);
|
)?);
|
||||||
self.client.add_client_obj(&buffer)?;
|
self.client.add_client_obj(&buffer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -70,14 +69,13 @@ impl WlShmPool {
|
||||||
|
|
||||||
async fn resize(&self, parser: MsgParser<'_, '_>) -> Result<(), ResizeError> {
|
async fn resize(&self, parser: MsgParser<'_, '_>) -> Result<(), ResizeError> {
|
||||||
let req: Resize = self.client.parse(self, parser)?;
|
let req: Resize = self.client.parse(self, parser)?;
|
||||||
let mut mem = self.mem.borrow_mut();
|
|
||||||
if req.size < 0 {
|
if req.size < 0 {
|
||||||
return Err(ResizeError::NegativeSize);
|
return Err(ResizeError::NegativeSize);
|
||||||
}
|
}
|
||||||
if (req.size as usize) < mem.len() {
|
if (req.size as usize) < self.mem.get().len() {
|
||||||
return Err(ResizeError::CannotShrink);
|
return Err(ResizeError::CannotShrink);
|
||||||
}
|
}
|
||||||
*mem = Rc::new(ClientMem::new(self.fd.raw(), req.size as usize)?);
|
self.mem.set(Rc::new(ClientMem::new(self.fd.raw(), req.size as usize)?));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ use std::mem;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
pub use types::*;
|
pub use types::*;
|
||||||
|
use crate::utils::clonecell::CloneCell;
|
||||||
|
|
||||||
const DESTROY: u32 = 0;
|
const DESTROY: u32 = 0;
|
||||||
const ATTACH: u32 = 1;
|
const ATTACH: u32 = 1;
|
||||||
|
|
@ -73,7 +74,7 @@ pub struct WlSurface {
|
||||||
opaque_region: Cell<Option<Region>>,
|
opaque_region: Cell<Option<Region>>,
|
||||||
pub extents: Cell<SurfaceExtents>,
|
pub extents: Cell<SurfaceExtents>,
|
||||||
pub effective_extents: Cell<SurfaceExtents>,
|
pub effective_extents: Cell<SurfaceExtents>,
|
||||||
pub buffer: RefCell<Option<Rc<WlBuffer>>>,
|
pub buffer: CloneCell<Option<Rc<WlBuffer>>>,
|
||||||
pub children: RefCell<Option<Box<ParentData>>>,
|
pub children: RefCell<Option<Box<ParentData>>>,
|
||||||
role_data: RefCell<RoleData>,
|
role_data: RefCell<RoleData>,
|
||||||
pub frame_requests: RefCell<Vec<Rc<WlCallback>>>,
|
pub frame_requests: RefCell<Vec<Rc<WlCallback>>>,
|
||||||
|
|
@ -207,7 +208,7 @@ impl WlSurface {
|
||||||
opaque_region: Cell::new(None),
|
opaque_region: Cell::new(None),
|
||||||
extents: Default::default(),
|
extents: Default::default(),
|
||||||
effective_extents: Default::default(),
|
effective_extents: Default::default(),
|
||||||
buffer: RefCell::new(None),
|
buffer: CloneCell::new(None),
|
||||||
children: Default::default(),
|
children: Default::default(),
|
||||||
role_data: RefCell::new(RoleData::None),
|
role_data: RefCell::new(RoleData::None),
|
||||||
frame_requests: RefCell::new(vec![]),
|
frame_requests: RefCell::new(vec![]),
|
||||||
|
|
@ -225,7 +226,7 @@ impl WlSurface {
|
||||||
fn calculate_extents(&self) {
|
fn calculate_extents(&self) {
|
||||||
{
|
{
|
||||||
let mut extents = SurfaceExtents::default();
|
let mut extents = SurfaceExtents::default();
|
||||||
if let Some(b) = self.buffer.borrow().deref() {
|
if let Some(b) = self.buffer.get() {
|
||||||
extents.x2 = b.width as i32;
|
extents.x2 = b.width as i32;
|
||||||
extents.y2 = b.height as i32;
|
extents.y2 = b.height as i32;
|
||||||
}
|
}
|
||||||
|
|
@ -278,6 +279,9 @@ impl WlSurface {
|
||||||
|
|
||||||
async fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
async fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
||||||
let _req: Destroy = self.parse(parser)?;
|
let _req: Destroy = self.parse(parser)?;
|
||||||
|
if self.role_data.borrow().is_some() {
|
||||||
|
return Err(DestroyError::ReloObjectStillExists);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
let mut children = self.children.borrow_mut();
|
let mut children = self.children.borrow_mut();
|
||||||
if let Some(children) = &mut *children {
|
if let Some(children) = &mut *children {
|
||||||
|
|
@ -287,49 +291,12 @@ impl WlSurface {
|
||||||
}
|
}
|
||||||
*children = None;
|
*children = None;
|
||||||
}
|
}
|
||||||
let mut ss_parent = None;
|
|
||||||
{
|
{
|
||||||
let mut data = self.role_data.borrow_mut();
|
let buffer = self.buffer.get();
|
||||||
match &mut *data {
|
if let Some(buffer) = &buffer {
|
||||||
RoleData::None => {}
|
|
||||||
RoleData::Subsurface(ss) => {
|
|
||||||
ss_parent = Some(ss.subsurface.parent.clone());
|
|
||||||
let mut children = ss.subsurface.parent.children.borrow_mut();
|
|
||||||
if let Some(children) = &mut *children {
|
|
||||||
children.subsurfaces.remove(&self.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RoleData::XdgSurface(xdg) => {
|
|
||||||
let children = xdg.popups.lock();
|
|
||||||
for child in children.values() {
|
|
||||||
let mut rd = child.surface.surface.role_data.borrow_mut();
|
|
||||||
if let RoleData::XdgSurface(xdg) = &mut *rd {
|
|
||||||
if let XdgSurfaceRoleData::Popup(p) = &mut xdg.role_data {
|
|
||||||
p.parent = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let XdgSurfaceRoleData::Popup(p) = &mut xdg.role_data {
|
|
||||||
if let Some(p) = &p.parent {
|
|
||||||
let mut rd = p.surface.role_data.borrow_mut();
|
|
||||||
if let RoleData::XdgSurface(xdg) = &mut *rd {
|
|
||||||
xdg.popups.remove(&self.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*data = RoleData::None;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
let buffer = self.buffer.borrow();
|
|
||||||
if let Some(buffer) = &*buffer {
|
|
||||||
buffer.surfaces.remove(&self.id);
|
buffer.surfaces.remove(&self.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(parent) = ss_parent {
|
|
||||||
parent.calculate_extents();
|
|
||||||
}
|
|
||||||
self.client.remove_obj(self).await?;
|
self.client.remove_obj(self).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -337,14 +304,13 @@ impl WlSurface {
|
||||||
async fn attach(&self, parser: MsgParser<'_, '_>) -> Result<(), AttachError> {
|
async fn attach(&self, parser: MsgParser<'_, '_>) -> Result<(), AttachError> {
|
||||||
let req: Attach = self.parse(parser)?;
|
let req: Attach = self.parse(parser)?;
|
||||||
{
|
{
|
||||||
let mut buffer = self.buffer.borrow_mut();
|
if let Some(buffer) = self.buffer.take() {
|
||||||
if let Some(buffer) = buffer.take() {
|
|
||||||
self.client.event(buffer.release()).await?;
|
self.client.event(buffer.release()).await?;
|
||||||
buffer.surfaces.remove(&self.id);
|
buffer.surfaces.remove(&self.id);
|
||||||
}
|
}
|
||||||
let mut rd = self.role_data.borrow_mut();
|
let mut rd = self.role_data.borrow_mut();
|
||||||
if req.buffer.is_some() {
|
if req.buffer.is_some() {
|
||||||
*buffer = Some(self.client.get_buffer(req.buffer)?);
|
self.buffer.set(Some(self.client.get_buffer(req.buffer)?));
|
||||||
if let RoleData::XdgSurface(xdg) = &mut *rd {
|
if let RoleData::XdgSurface(xdg) = &mut *rd {
|
||||||
if let XdgSurfaceRoleData::Toplevel(td) = &mut xdg.role_data {
|
if let XdgSurfaceRoleData::Toplevel(td) = &mut xdg.role_data {
|
||||||
if td.node.is_none() {
|
if td.node.is_none() {
|
||||||
|
|
@ -370,7 +336,7 @@ impl WlSurface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*buffer = None;
|
self.buffer.set(None);
|
||||||
if let RoleData::XdgSurface(xdg) = &mut *rd {
|
if let RoleData::XdgSurface(xdg) = &mut *rd {
|
||||||
if let XdgSurfaceRoleData::Toplevel(td) = &mut xdg.role_data {
|
if let XdgSurfaceRoleData::Toplevel(td) = &mut xdg.role_data {
|
||||||
td.node = None;
|
td.node = None;
|
||||||
|
|
@ -574,6 +540,6 @@ impl Object for WlSurface {
|
||||||
*self.children.borrow_mut() = None;
|
*self.children.borrow_mut() = None;
|
||||||
*self.role_data.borrow_mut() = RoleData::None;
|
*self.role_data.borrow_mut() = RoleData::None;
|
||||||
mem::take(self.frame_requests.borrow_mut().deref_mut());
|
mem::take(self.frame_requests.borrow_mut().deref_mut());
|
||||||
*self.buffer.borrow_mut() = None;
|
self.buffer.set(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@ pub enum DestroyError {
|
||||||
ParseFailed(#[source] Box<MsgParserError>),
|
ParseFailed(#[source] Box<MsgParserError>),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ClientError(Box<ClientError>),
|
ClientError(Box<ClientError>),
|
||||||
|
#[error("Cannot destroy a `wl_surface` before its role object")]
|
||||||
|
ReloObjectStillExists,
|
||||||
}
|
}
|
||||||
efrom!(DestroyError, ParseFailed, MsgParserError);
|
efrom!(DestroyError, ParseFailed, MsgParserError);
|
||||||
efrom!(DestroyError, ClientError, ClientError);
|
efrom!(DestroyError, ClientError, ClientError);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use crate::utils::asyncevent::AsyncEvent;
|
||||||
use crate::State;
|
use crate::State;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use crate::utils::clonecell::CloneCell;
|
||||||
|
|
||||||
pub async fn handle_backend_events(state: Rc<State>) {
|
pub async fn handle_backend_events(state: Rc<State>) {
|
||||||
let mut beh = BackendEventHandler { state };
|
let mut beh = BackendEventHandler { state };
|
||||||
|
|
@ -77,7 +78,7 @@ impl OutputHandler {
|
||||||
floating_outputs: RefCell::new(Default::default()),
|
floating_outputs: RefCell::new(Default::default()),
|
||||||
},
|
},
|
||||||
backend: self.output.clone(),
|
backend: self.output.clone(),
|
||||||
child: RefCell::new(None),
|
child: CloneCell::new(None),
|
||||||
floating: Default::default(),
|
floating: Default::default(),
|
||||||
});
|
});
|
||||||
self.state.root.outputs.set(self.output.id(), on.clone());
|
self.state.root.outputs.set(self.output.id(), on.clone());
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use ahash::AHashMap;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use crate::utils::clonecell::CloneCell;
|
||||||
|
|
||||||
linear_ids!(NodeIds, NodeId);
|
linear_ids!(NodeIds, NodeId);
|
||||||
|
|
||||||
|
|
@ -135,7 +136,7 @@ impl Node for DisplayNode {
|
||||||
pub struct OutputNode {
|
pub struct OutputNode {
|
||||||
pub common: NodeCommon,
|
pub common: NodeCommon,
|
||||||
pub backend: Rc<dyn Output>,
|
pub backend: Rc<dyn Output>,
|
||||||
pub child: RefCell<Option<Rc<dyn Node>>>,
|
pub child: CloneCell<Option<Rc<dyn Node>>>,
|
||||||
pub floating: LinkedList<Rc<dyn Node>>,
|
pub floating: LinkedList<Rc<dyn Node>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,7 +152,7 @@ impl Node for OutputNode {
|
||||||
for floating in self.floating.iter() {
|
for floating in self.floating.iter() {
|
||||||
floating.clear();
|
floating.clear();
|
||||||
}
|
}
|
||||||
if let Some(child) = self.child.borrow_mut().take() {
|
if let Some(child) = self.child.take() {
|
||||||
child.clear();
|
child.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ impl<'a> MsgFormatter<'a> {
|
||||||
fds: self.fds,
|
fds: self.fds,
|
||||||
};
|
};
|
||||||
f(&mut fmt);
|
f(&mut fmt);
|
||||||
let len = self.buf.out_pos - pos + 4;
|
let len = self.buf.out_pos - pos - 4;
|
||||||
let none = [MaybeUninit::new(0); 4];
|
let none = [MaybeUninit::new(0); 4];
|
||||||
self.buf.write(&none[..self.buf.out_pos.wrapping_neg() & 3]);
|
self.buf.write(&none[..self.buf.out_pos.wrapping_neg() & 3]);
|
||||||
len as u32
|
len as u32
|
||||||
|
|
|
||||||
49
src/utils/clonecell.rs
Normal file
49
src/utils/clonecell.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
use std::cell::UnsafeCell;
|
||||||
|
use std::mem;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use crate::utils::ptr_ext::{MutPtrExt, PtrExt};
|
||||||
|
|
||||||
|
pub struct CloneCell<T: UnsafeCellCloneSafe> {
|
||||||
|
data: UnsafeCell<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: UnsafeCellCloneSafe> CloneCell<T> {
|
||||||
|
pub fn new(t: T) -> Self {
|
||||||
|
Self {
|
||||||
|
data: UnsafeCell::new(t),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn get(&self) -> T {
|
||||||
|
unsafe {
|
||||||
|
self.data.get().deref().clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn set(&self, t: T) {
|
||||||
|
unsafe {
|
||||||
|
let _ = mem::replace(self.data.get().deref_mut(), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn take(&self) -> T where T: Default {
|
||||||
|
unsafe {
|
||||||
|
mem::take(self.data.get().deref_mut())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default + UnsafeCellCloneSafe> Default for CloneCell<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new(Default::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe trait UnsafeCellCloneSafe: Clone { }
|
||||||
|
|
||||||
|
unsafe impl<T: UnsafeCellCloneSafe> UnsafeCellCloneSafe for Option<T> { }
|
||||||
|
|
||||||
|
unsafe impl<T: ?Sized> UnsafeCellCloneSafe for Rc<T> { }
|
||||||
|
|
@ -8,3 +8,4 @@ pub mod oneshot;
|
||||||
pub mod ptr_ext;
|
pub mod ptr_ext;
|
||||||
pub mod queue;
|
pub mod queue;
|
||||||
pub mod vec_ext;
|
pub mod vec_ext;
|
||||||
|
pub mod clonecell;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue