1
0
Fork 0
forked from wry/wry

autocommit 2022-03-30 18:10:37 CEST

This commit is contained in:
Julian Orth 2022-03-30 18:10:37 +02:00
parent c4854c4d7d
commit a8136ed88c
17 changed files with 189 additions and 81 deletions

View file

@ -23,6 +23,18 @@ pub trait InputDevice {
fn event(&self) -> Option<InputEvent>;
fn on_change(&self, cb: Rc<dyn Fn()>);
fn grab(&self, grab: bool);
fn has_capability(&self, cap: InputDeviceCapability) -> bool;
}
#[derive(Debug, Copy, Clone)]
pub enum InputDeviceCapability {
Keyboard,
Pointer,
Touch,
TabletTool,
TabletPad,
Gesture,
Switch,
}
pub enum BackendEvent {

View file

@ -3,7 +3,7 @@ mod monitor;
mod video;
use crate::async_engine::{AsyncError, AsyncFd};
use crate::backend::{Backend, InputDevice, InputDeviceId, InputEvent};
use crate::backend::{Backend, InputDevice, InputDeviceCapability, InputDeviceId, InputEvent};
use crate::backends::metal::video::{MetalDrmDevice, PendingDrmDevice};
use crate::dbus::DbusError;
use crate::drm::drm::DrmError;
@ -25,6 +25,7 @@ use std::future::pending;
use std::rc::Rc;
use thiserror::Error;
use uapi::{c, OwnedFd};
use crate::libinput::consts::{LIBINPUT_DEVICE_CAP_GESTURE, LIBINPUT_DEVICE_CAP_KEYBOARD, LIBINPUT_DEVICE_CAP_POINTER, LIBINPUT_DEVICE_CAP_SWITCH, LIBINPUT_DEVICE_CAP_TABLET_PAD, LIBINPUT_DEVICE_CAP_TABLET_TOOL, LIBINPUT_DEVICE_CAP_TOUCH};
#[derive(Debug, Error)]
pub enum MetalError {
@ -180,7 +181,7 @@ struct MetalInputDevice {
id: InputDeviceId,
_devnum: c::dev_t,
fd: CloneCell<Option<Rc<OwnedFd>>>,
inputdev: Cell<Option<RegisteredDevice>>,
inputdev: CloneCell<Option<Rc<RegisteredDevice>>>,
devnode: CString,
_sysname: CString,
removed: Cell<bool>,
@ -242,6 +243,22 @@ impl InputDevice for MetalInputDevice {
fn grab(&self, _grab: bool) {
// nothing
}
fn has_capability(&self, cap: InputDeviceCapability) -> bool {
let li = match cap {
InputDeviceCapability::Keyboard => LIBINPUT_DEVICE_CAP_KEYBOARD,
InputDeviceCapability::Pointer => LIBINPUT_DEVICE_CAP_POINTER,
InputDeviceCapability::Touch => LIBINPUT_DEVICE_CAP_TOUCH,
InputDeviceCapability::TabletTool => LIBINPUT_DEVICE_CAP_TABLET_TOOL,
InputDeviceCapability::TabletPad => LIBINPUT_DEVICE_CAP_TABLET_PAD,
InputDeviceCapability::Gesture => LIBINPUT_DEVICE_CAP_GESTURE,
InputDeviceCapability::Switch => LIBINPUT_DEVICE_CAP_SWITCH,
};
match self.inputdev.get() {
Some(dev) => dev.device().has_cap(li),
_ => false,
}
}
}
impl MetalInputDevice {

View file

@ -95,7 +95,7 @@ impl MetalBackend {
self.state.fdcloser.close(old);
}
let inputdev = match self.libinput.open(dev.devnode.as_c_str()) {
Ok(d) => d,
Ok(d) => Rc::new(d),
Err(_) => return,
};
inputdev.device().set_slot(dev.slot);
@ -314,7 +314,7 @@ impl MetalBackend {
}
dev.fd.set(Some(res.fd.clone()));
let inputdev = match slf.libinput.open(dev.devnode.as_c_str()) {
Ok(d) => d,
Ok(d) => Rc::new(d),
Err(_) => return,
};
inputdev.device().set_slot(slot);

View file

@ -1,8 +1,5 @@
use crate::async_engine::{Phase, SpawnedFuture};
use crate::backend::{
Backend, BackendEvent, InputDevice, InputDeviceId, InputEvent, KeyState, Output, OutputId,
ScrollAxis,
};
use crate::backend::{Backend, BackendEvent, InputDevice, InputDeviceCapability, InputDeviceId, InputEvent, KeyState, Output, OutputId, ScrollAxis};
use crate::drm::drm::{Drm, DrmError};
use crate::drm::gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING};
use crate::drm::{ModifiedFormat, INVALID_MODIFIER};
@ -638,9 +635,12 @@ impl XBackendData {
return;
}
let image = &output.images[output.next_image.fetch_add(1) % output.images.len()];
let serial = output.serial.fetch_add(1);
let image = &output.images[output.next_image.fetch_add(1) % output.images.len()];
image.idle.set(false);
image.last_serial.set(serial);
if let Some(node) = self.state.root.outputs.get(&output.id) {
let fb = image.fb.get();
fb.render(&*node, &self.state, Some(node.position.get()));
@ -667,8 +667,6 @@ impl XBackendData {
log::error!("Could not present image: {:?}", e);
return;
}
image.idle.set(false);
image.last_serial.set(serial);
}
async fn handle_input_event(self: &Rc<Self>, event: &Event) -> Result<(), XBackendError> {
@ -958,6 +956,13 @@ impl InputDevice for XSeatKeyboard {
fn grab(&self, grab: bool) {
self.0.backend.grab_requests.push((self.0.clone(), grab));
}
fn has_capability(&self, cap: InputDeviceCapability) -> bool {
match cap {
InputDeviceCapability::Keyboard => true,
_ => false,
}
}
}
impl InputDevice for XSeatMouse {
@ -980,4 +985,11 @@ impl InputDevice for XSeatMouse {
fn grab(&self, _grab: bool) {
log::error!("Cannot grab xorg mouse");
}
fn has_capability(&self, cap: InputDeviceCapability) -> bool {
match cap {
InputDeviceCapability::Pointer => true,
_ => false,
}
}
}

View file

@ -9,12 +9,13 @@ use crate::utils::ptr_ext::PtrExt;
use jay_config::_private::ipc::{InitMessage, ServerMessage, V1InitMessage};
use jay_config::_private::{bincode_ops, ConfigEntry, VERSION};
use jay_config::keyboard::ModifiedKeySym;
use jay_config::{InputDevice, Seat};
use jay_config::{Seat};
use libloading::Library;
use std::cell::Cell;
use std::ptr;
use std::rc::Rc;
use thiserror::Error;
use jay_config::input::InputDevice;
#[derive(Debug, Error)]
pub enum ConfigError {

View file

@ -1,5 +1,5 @@
use crate::backend;
use crate::backend::InputDeviceId;
use crate::backend::{InputDeviceCapability, InputDeviceId};
use crate::ifs::wl_seat::{SeatId, WlSeatGlobal};
use crate::state::{DeviceHandlerData, State};
use crate::tree::walker::NodeVisitorBase;
@ -16,12 +16,13 @@ use jay_config::_private::ipc::{ClientMessage, Response, ServerMessage};
use jay_config::keyboard::keymap::Keymap;
use jay_config::keyboard::mods::Modifiers;
use jay_config::keyboard::syms::KeySym;
use jay_config::{Axis, Direction, InputDevice, LogLevel, Seat};
use jay_config::{Axis, Direction, LogLevel, Seat};
use libloading::Library;
use log::Level;
use std::cell::Cell;
use std::rc::Rc;
use thiserror::Error;
use jay_config::input::{CAP_GESTURE, CAP_KEYBOARD, CAP_POINTER, CAP_SWITCH, CAP_TABLET_PAD, CAP_TABLET_TOOL, CAP_TOUCH, Capability, InputDevice};
pub(super) struct ConfigProxyHandler {
pub client_data: Cell<*const u8>,
@ -47,6 +48,12 @@ impl ConfigProxyHandler {
self.bufs.push(buf);
}
pub fn respond(&self, msg: Response) {
self.send(&ServerMessage::Response {
response: msg,
})
}
fn id(&self) -> u64 {
self.next_id.fetch_add(1)
}
@ -83,10 +90,8 @@ impl ConfigProxyHandler {
let global_name = self.state.globals.name();
let seat = WlSeatGlobal::new(global_name, name, &self.state);
self.state.globals.add_global(&self.state, &seat);
self.send(&ServerMessage::Response {
response: Response::CreateSeat {
seat: Seat(seat.id().raw() as _),
},
self.respond(Response::CreateSeat {
seat: Seat(seat.id().raw() as _),
});
}
@ -99,9 +104,7 @@ impl ConfigProxyHandler {
}
_ => (Keymap::INVALID, Err(ParseKeymapError::ParsingFailed)),
};
self.send(&ServerMessage::Response {
response: Response::ParseKeymap { keymap },
});
self.respond(Response::ParseKeymap { keymap });
res
}
@ -131,9 +134,7 @@ impl ConfigProxyHandler {
fn handle_get_repeat_rate(&self, seat: Seat) -> Result<(), SeatGetRepeatRateError> {
let seat = self.get_seat(seat)?;
let (rate, delay) = seat.get_rate();
self.send(&ServerMessage::Response {
response: Response::GetRepeatRate { rate, delay },
});
self.respond(Response::GetRepeatRate { rate, delay });
Ok(())
}
@ -184,7 +185,7 @@ impl ConfigProxyHandler {
let kbs = self.state.input_device_handlers.borrow_mut();
match kbs.get(&(InputDeviceId::from_raw(kb.0 as _))) {
None => Err(CphError::KeyboardDoesNotExist(kb)),
Some(kb) => Ok(kb.device.clone()),
Some(kb) => Ok(kb.data.device.clone()),
}
}
@ -206,12 +207,31 @@ impl ConfigProxyHandler {
Ok(())
}
fn handle_has_capability(&self, device: InputDevice, cap: Capability) -> Result<(), HasCapabilityError> {
let dev = self.get_device_handler_data(device)?;
let has_cap = 'has_cap: {
let cap = match cap {
CAP_KEYBOARD => InputDeviceCapability::Keyboard,
CAP_POINTER => InputDeviceCapability::Pointer,
CAP_TOUCH => InputDeviceCapability::Touch,
CAP_TABLET_TOOL => InputDeviceCapability::TabletTool,
CAP_TABLET_PAD => InputDeviceCapability::TabletPad,
CAP_GESTURE => InputDeviceCapability::Gesture,
CAP_SWITCH => InputDeviceCapability::Switch,
_ => break 'has_cap false,
};
dev.device.has_capability(cap)
};
self.respond(Response::HasCapability {
has: has_cap,
});
Ok(())
}
fn handle_get_mono(&self, seat: Seat) -> Result<(), GetMonoError> {
let seat = self.get_seat(seat)?;
self.send(&ServerMessage::Response {
response: Response::GetMono {
mono: seat.get_mono().unwrap_or(false),
},
self.respond(Response::GetMono {
mono: seat.get_mono().unwrap_or(false),
});
Ok(())
}
@ -224,13 +244,11 @@ impl ConfigProxyHandler {
fn handle_get_split(&self, seat: Seat) -> Result<(), GetSplitError> {
let seat = self.get_seat(seat)?;
self.send(&ServerMessage::Response {
response: Response::GetSplit {
axis: seat
.get_split()
.unwrap_or(ContainerSplit::Horizontal)
.into(),
},
self.respond(Response::GetSplit {
axis: seat
.get_split()
.unwrap_or(ContainerSplit::Horizontal)
.into(),
});
Ok(())
}
@ -284,9 +302,7 @@ impl ConfigProxyHandler {
}
}
}
self.send(&ServerMessage::Response {
response: Response::GetInputDevices { devices: res },
});
self.respond(Response::GetInputDevices { devices: res });
}
fn handle_get_seats(&self) {
@ -297,9 +313,7 @@ impl ConfigProxyHandler {
.map(|seat| Seat::from_raw(seat.id().raw() as _))
.collect()
};
self.send(&ServerMessage::Response {
response: Response::GetSeats { seats },
});
self.respond(Response::GetSeats { seats });
}
fn handle_run(
@ -323,18 +337,14 @@ impl ConfigProxyHandler {
}
fn handle_get_title_height(&self) {
self.send(&ServerMessage::Response {
response: Response::GetTitleHeight {
height: self.state.theme.title_height.get(),
},
self.respond(Response::GetTitleHeight {
height: self.state.theme.title_height.get(),
});
}
fn handle_get_border_width(&self) {
self.send(&ServerMessage::Response {
response: Response::GetBorderWidth {
width: self.state.theme.border_width.get(),
},
self.respond(Response::GetBorderWidth {
width: self.state.theme.border_width.get(),
});
}
@ -500,6 +510,7 @@ impl ConfigProxyHandler {
ClientMessage::ToggleFloating { seat } => self.handle_toggle_floating(seat)?,
ClientMessage::Quit => self.handle_quit(),
ClientMessage::SwitchTo { vtnr } => self.handle_switch_to(vtnr),
ClientMessage::HasCapability { device, cap } => self.handle_has_capability(device, cap)?,
}
Ok(())
}
@ -547,6 +558,8 @@ enum CphError {
SetTitleHeightError(#[from] SetTitleHeightError),
#[error("Could not process a `set_border_width` request")]
SetBorderWidthError(#[from] SetBorderWidthError),
#[error("Could not process a `has_capability` request")]
HasCapabilityError(#[from] HasCapabilityError),
#[error("Device {0:?} does not exist")]
DeviceDoesNotExist(InputDevice),
#[error("Device {0:?} does not exist")]
@ -572,6 +585,13 @@ enum SetSeatError {
}
efrom!(SetSeatError, CphError);
#[derive(Debug, Error)]
enum HasCapabilityError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(HasCapabilityError, CphError);
#[derive(Debug, Error)]
enum AddShortcutError {
#[error(transparent)]

View file

@ -1,10 +1,8 @@
use crate::libinput::sys::{
libinput_device, libinput_device_get_user_data, libinput_device_set_user_data,
libinput_device_unref, libinput_path_remove_device,
};
use crate::libinput::sys::{libinput_device, libinput_device_get_user_data, libinput_device_has_capability, libinput_device_set_user_data, libinput_device_unref, libinput_path_remove_device};
use crate::libinput::LibInput;
use std::marker::PhantomData;
use std::rc::Rc;
use crate::libinput::consts::{DeviceCapability};
pub struct LibInputDevice<'a> {
pub(super) dev: *mut libinput_device,
@ -39,6 +37,11 @@ impl<'a> LibInputDevice<'a> {
Some(res - 1)
}
}
pub fn has_cap(&self, cap: DeviceCapability) -> bool {
let res = unsafe { libinput_device_has_capability(self.dev, cap.raw() as _) };
res != 0
}
}
impl RegisteredDevice {

View file

@ -24,6 +24,11 @@ extern "C" {
interface: *const libinput_interface,
user_data: *mut c::c_void,
) -> *mut libinput;
pub fn libinput_unref(libinput: *mut libinput) -> *mut libinput;
pub fn libinput_get_fd(libinput: *mut libinput) -> c::c_int;
pub fn libinput_dispatch(libinput: *mut libinput) -> c::c_int;
pub fn libinput_get_event(libinput: *mut libinput) -> *mut libinput_event;
pub fn libinput_device_set_user_data(device: *mut libinput_device, user_data: *mut c::c_void);
pub fn libinput_device_get_user_data(device: *mut libinput_device) -> *mut c::c_void;
pub fn libinput_device_ref(device: *mut libinput_device) -> *mut libinput_device;
@ -33,12 +38,7 @@ extern "C" {
path: *const c::c_char,
) -> *mut libinput_device;
pub fn libinput_path_remove_device(device: *mut libinput_device);
pub fn libinput_unref(libinput: *mut libinput) -> *mut libinput;
pub fn libinput_get_fd(libinput: *mut libinput) -> c::c_int;
pub fn libinput_dispatch(libinput: *mut libinput) -> c::c_int;
pub fn libinput_get_event(libinput: *mut libinput) -> *mut libinput_event;
pub fn libinput_device_has_capability(device: *mut libinput_device, cap: libinput_device_capability) -> c::c_int;
pub fn libinput_event_destroy(event: *mut libinput_event);
pub fn libinput_event_get_type(event: *mut libinput_event) -> libinput_event_type;

View file

@ -73,12 +73,12 @@ pub struct State {
pub struct InputDeviceData {
pub handler: SpawnedFuture<()>,
pub id: InputDeviceId,
pub device: Rc<dyn InputDevice>,
pub data: Rc<DeviceHandlerData>,
}
pub struct DeviceHandlerData {
pub seat: CloneCell<Option<Rc<WlSeatGlobal>>>,
pub device: Rc<dyn InputDevice>,
}
impl State {

View file

@ -6,6 +6,7 @@ use std::rc::Rc;
pub fn handle(state: &Rc<State>, dev: Rc<dyn InputDevice>) {
let data = Rc::new(DeviceHandlerData {
seat: Default::default(),
device: dev.clone(),
});
let oh = DeviceHandler {
state: state.clone(),
@ -18,7 +19,6 @@ pub fn handle(state: &Rc<State>, dev: Rc<dyn InputDevice>) {
InputDeviceData {
handler,
id: dev.id(),
device: dev.clone(),
data,
},
);