1
0
Fork 0
forked from wry/wry

autocommit 2022-01-07 15:08:31 CET

This commit is contained in:
Julian Orth 2022-01-07 15:08:31 +01:00
parent 4a939477a2
commit f8e7557d1d
18 changed files with 1258 additions and 35 deletions

View file

@ -1,5 +1,6 @@
use crate::backend::{BackendEvent, Output, OutputId, Seat, SeatEvent, SeatId};
use crate::event_loop::{EventLoopDispatcher, EventLoopId};
use crate::fixed::Fixed;
use crate::ifs::wl_buffer::WlBuffer;
use crate::ifs::wl_surface::WlSurface;
use crate::pixman::{Image, PixmanError};
@ -24,7 +25,6 @@ use uapi::c;
use xcb_dl::{ffi, Xcb, XcbShm, XcbXinput, XcbXkb};
use xcb_dl_util::error::{XcbError, XcbErrorParser};
use xcb_dl_util::xcb_box::XcbBox;
use crate::fixed::Fixed;
#[derive(Debug, Error)]
pub enum XorgBackendError {
@ -71,6 +71,7 @@ struct XcbCon {
input: Box<XcbXinput>,
input_opcode: u8,
xkb: Box<XcbXkb>,
xkb_event: u8,
c: *mut ffi::xcb_connection_t,
errors: XcbErrorParser,
}
@ -92,6 +93,7 @@ impl XcbCon {
input,
input_opcode: 0,
xkb,
xkb_event: 0,
c,
errors,
};
@ -125,6 +127,12 @@ impl XcbCon {
);
con.errors.check(&con.xcb, res, err)?;
let xkb_ex = con
.xcb
.xcb_get_extension_data(con.c, con.xkb.xcb_xkb_id());
assert!(xkb_ex.is_not_null());
con.xkb_event = xkb_ex.deref().first_event;
Ok(con)
}
}
@ -348,6 +356,21 @@ impl XorgBackend {
Ok(())
}
fn create_state(&self, device_id: ffi::xcb_input_device_id_t) -> Result<XkbState, XorgBackendError> {
unsafe {
let keymap = self.xkbcommonx11.keymap_from_device(
&self.xkbcommon,
self.con.c,
device_id as _,
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
)?;
let state =
self.xkbcommonx11
.state_from_device(&keymap, self.con.c, device_id as _)?;
Ok(state)
}
}
fn handle_input_device(self: &Rc<Self>, info: &ffi::xcb_input_xi_device_info_t) {
if info.type_ != ffi::XCB_INPUT_DEVICE_TYPE_MASTER_KEYBOARD as _ {
return;
@ -379,19 +402,7 @@ impl XorgBackend {
e
);
}
let res: Result<_, XkbCommonError> = (|| {
let keymap = self.xkbcommonx11.keymap_from_device(
&self.xkbcommon,
con.c,
info.deviceid as _,
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
)?;
let state =
self.xkbcommonx11
.state_from_device(&keymap, con.c, info.deviceid as _)?;
Ok(state)
})();
let state = match res {
let state = match self.create_state(info.deviceid) {
Ok(c) => c,
Err(e) => {
log::error!(
@ -412,6 +423,7 @@ impl XorgBackend {
events: RefCell::new(Default::default()),
state,
});
seat.send_new_state();
self.seats.set(info.deviceid, seat.clone());
self.mouse_seats.set(info.attachment, seat.clone());
self.state
@ -443,6 +455,30 @@ impl XorgBackend {
ffi::XCB_CONFIGURE_NOTIFY => self.handle_configure(event)?,
ffi::XCB_DESTROY_NOTIFY => self.handle_destroy(event)?,
ffi::XCB_GE_GENERIC => self.handle_generic(event)?,
_ if event_type == self.con.xkb_event => self.handle_xkb(event)?,
_ => {}
}
Ok(())
}
fn handle_xkb(
self: &Rc<Self>,
event: &ffi::xcb_generic_event_t,
) -> Result<(), XorgBackendError> {
let event = unsafe { &*(event as *const _ as *const ffi::xcb_xkb_map_notify_event_t) };
let seat = match self.seats.get(&(event.device_id as _)) {
Some(s) => s,
_ => return Ok(()),
};
match event.xkb_type {
ffi::XCB_XKB_MAP_NOTIFY | ffi::XCB_XKB_NEW_KEYBOARD_NOTIFY => {
}
ffi::XCB_XKB_STATE_NOTIFY => {
let event = unsafe {
(event as *const _ as *const ffi::xcb_xkb_state_notify_event_t).deref()
};
}
_ => {}
}
Ok(())
@ -465,12 +501,25 @@ impl XorgBackend {
) -> Result<(), XorgBackendError> {
match event.event_type {
ffi::XCB_INPUT_MOTION => self.handle_input_motion(event)?,
ffi::XCB_INPUT_KEY_PRESS => self.handle_input_key_press(event)?,
ffi::XCB_INPUT_HIERARCHY => self.handle_input_hierarchy(event)?,
_ => {}
}
Ok(())
}
fn handle_input_key_press(
self: &Rc<Self>,
event: &ffi::xcb_ge_generic_event_t,
) -> Result<(), XorgBackendError> {
let event =
unsafe { (event as *const _ as *const ffi::xcb_input_key_press_event_t).deref() };
if let Some(seat) = self.seats.get(&event.deviceid) {
seat.event(SeatEvent::Key(event.detail - 8));
}
Ok(())
}
fn handle_input_hierarchy(
self: &Rc<Self>,
event: &ffi::xcb_ge_generic_event_t,
@ -748,6 +797,7 @@ struct XorgSeat {
removed: Cell<bool>,
cb: RefCell<Option<Rc<dyn Fn()>>>,
events: RefCell<VecDeque<SeatEvent>>,
last_modifiers: Cell<(u32, u32, u32, u32)>,
state: XkbState,
}
@ -781,7 +831,3 @@ impl Seat for XorgSeat {
*self.cb.borrow_mut() = Some(cb);
}
}
fn fp1616_to_f64(i: ffi::xcb_input_fp1616_t) -> f64 {
i as f64 / (1 << 16) as f64
}