cli: add seat-test
This commit is contained in:
parent
b20abd28d0
commit
2ced50f3a7
11 changed files with 559 additions and 7 deletions
15
src/cli.rs
15
src/cli.rs
|
|
@ -4,6 +4,7 @@ mod log;
|
|||
mod quit;
|
||||
mod run_privileged;
|
||||
pub mod screenshot;
|
||||
mod seat_test;
|
||||
mod set_log_level;
|
||||
mod unlock;
|
||||
|
||||
|
|
@ -48,8 +49,10 @@ pub enum Cmd {
|
|||
Screenshot(ScreenshotArgs),
|
||||
/// Inspect/modify the idle (screensaver) settings.
|
||||
Idle(IdleArgs),
|
||||
/// Run a privileged program
|
||||
/// Run a privileged program.
|
||||
RunPrivileged(RunPrivilegedArgs),
|
||||
/// Tests the events produced by a seat.
|
||||
SeatTest(SeatTestArgs),
|
||||
#[cfg(feature = "it")]
|
||||
RunTests,
|
||||
}
|
||||
|
|
@ -149,6 +152,15 @@ pub struct SetLogArgs {
|
|||
level: CliLogLevel,
|
||||
}
|
||||
|
||||
#[derive(Args, Debug)]
|
||||
pub struct SeatTestArgs {
|
||||
/// Test all seats.
|
||||
#[clap(long, short = 'a')]
|
||||
all: bool,
|
||||
/// The seat to test.
|
||||
seat: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(ArgEnum, Debug, Copy, Clone, Hash, Eq, PartialEq)]
|
||||
pub enum CliBackend {
|
||||
X11,
|
||||
|
|
@ -201,6 +213,7 @@ pub fn main() {
|
|||
Cmd::Idle(a) => idle::main(cli.global, a),
|
||||
Cmd::Unlock => unlock::main(cli.global),
|
||||
Cmd::RunPrivileged(a) => run_privileged::main(cli.global, a),
|
||||
Cmd::SeatTest(a) => seat_test::main(cli.global, a),
|
||||
#[cfg(feature = "it")]
|
||||
Cmd::RunTests => crate::it::run_tests(),
|
||||
}
|
||||
|
|
|
|||
235
src/cli/seat_test.rs
Normal file
235
src/cli/seat_test.rs
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
use {
|
||||
crate::{
|
||||
cli::{GlobalArgs, SeatTestArgs},
|
||||
ifs::wl_seat::wl_pointer::{PendingScroll, CONTINUOUS, FINGER, WHEEL},
|
||||
tools::tool_client::{Handle, ToolClient},
|
||||
wire::{
|
||||
jay_compositor::{GetSeats, Seat, SeatEvents},
|
||||
jay_seat_events::{
|
||||
Axis120, AxisFrame, AxisPx, AxisSource, AxisStop, Button, Key, Modifiers,
|
||||
PointerAbs, PointerRel,
|
||||
},
|
||||
},
|
||||
},
|
||||
ahash::AHashMap,
|
||||
std::{cell::RefCell, future::pending, ops::Deref, rc::Rc},
|
||||
};
|
||||
|
||||
pub fn main(global: GlobalArgs, args: SeatTestArgs) {
|
||||
let tc = ToolClient::new(global.log_level.into());
|
||||
let screenshot = Rc::new(SeatTest {
|
||||
tc: tc.clone(),
|
||||
args,
|
||||
names: Default::default(),
|
||||
});
|
||||
tc.run(run(screenshot));
|
||||
}
|
||||
|
||||
struct SeatTest {
|
||||
tc: Rc<ToolClient>,
|
||||
args: SeatTestArgs,
|
||||
names: RefCell<AHashMap<u32, Rc<String>>>,
|
||||
}
|
||||
|
||||
impl SeatTest {
|
||||
fn name(&self, seat: u32) -> Rc<String> {
|
||||
match self.names.borrow_mut().get(&seat) {
|
||||
Some(n) => n.clone(),
|
||||
_ => Rc::new("unknown".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn run(seat_test: Rc<SeatTest>) {
|
||||
let tc = &seat_test.tc;
|
||||
let comp = tc.jay_compositor().await;
|
||||
tc.send(GetSeats { self_id: comp });
|
||||
Seat::handle(&tc, comp, seat_test.clone(), |st, seat| {
|
||||
st.names
|
||||
.borrow_mut()
|
||||
.insert(seat.id, Rc::new(seat.name.to_string()));
|
||||
});
|
||||
tc.round_trip().await;
|
||||
let all = seat_test.args.all;
|
||||
let mut seat = 0;
|
||||
if !all {
|
||||
seat = choose_seat(&seat_test);
|
||||
}
|
||||
let se = tc.id();
|
||||
tc.send(SeatEvents {
|
||||
self_id: comp,
|
||||
id: se,
|
||||
});
|
||||
let st = seat_test.clone();
|
||||
Key::handle(tc, se, (), move |_, ev| {
|
||||
if all || ev.seat == seat {
|
||||
if all {
|
||||
print!("Seat: {}, ", st.name(ev.seat));
|
||||
}
|
||||
println!(
|
||||
"Time: {:.4}, Key: {}, State: {}",
|
||||
time(ev.time_usec),
|
||||
ev.key,
|
||||
ev.state
|
||||
);
|
||||
}
|
||||
});
|
||||
let st = seat_test.clone();
|
||||
Modifiers::handle(tc, se, (), move |_, ev| {
|
||||
if all || ev.seat == seat {
|
||||
if all {
|
||||
print!("Seat: {}, ", st.name(ev.seat));
|
||||
}
|
||||
println!("Modifiers: {:08b}, Group: {}", ev.modifiers, ev.group);
|
||||
}
|
||||
});
|
||||
let st = seat_test.clone();
|
||||
PointerAbs::handle(tc, se, (), move |_, ev| {
|
||||
if all || ev.seat == seat {
|
||||
if all {
|
||||
print!("Seat: {}, ", st.name(ev.seat));
|
||||
}
|
||||
println!(
|
||||
"Time: {:.4}, Pointer: {}x{}",
|
||||
time(ev.time_usec),
|
||||
ev.x,
|
||||
ev.y
|
||||
);
|
||||
}
|
||||
});
|
||||
let st = seat_test.clone();
|
||||
PointerRel::handle(tc, se, (), move |_, ev| {
|
||||
if all || ev.seat == seat {
|
||||
if all {
|
||||
print!("Seat: {}, ", st.name(ev.seat));
|
||||
}
|
||||
println!(
|
||||
"Time: {:.4}, Pointer: {:+.4}x{:+.4}, Rel: {:+.4}x{:+.4}, Unaccelerated: {:+.4}x{:+.4}",
|
||||
time(ev.time_usec),
|
||||
ev.x,
|
||||
ev.y,
|
||||
ev.dx,
|
||||
ev.dy,
|
||||
ev.dx_unaccelerated,
|
||||
ev.dy_unaccelerated
|
||||
);
|
||||
}
|
||||
});
|
||||
let st = seat_test.clone();
|
||||
Button::handle(tc, se, (), move |_, ev| {
|
||||
if all || ev.seat == seat {
|
||||
if all {
|
||||
print!("Seat: {:.4}, ", st.name(ev.seat));
|
||||
}
|
||||
println!(
|
||||
"Time: {}, Button: {}, State: {}",
|
||||
time(ev.time_usec),
|
||||
ev.button,
|
||||
ev.state
|
||||
);
|
||||
}
|
||||
});
|
||||
let ps = Rc::new(PendingScroll::default());
|
||||
AxisSource::handle(tc, se, ps.clone(), move |ps, ev| {
|
||||
ps.source.set(Some(ev.source));
|
||||
});
|
||||
AxisPx::handle(tc, se, ps.clone(), move |ps, ev| {
|
||||
ps.px[ev.axis as usize].set(Some(ev.dist));
|
||||
});
|
||||
AxisStop::handle(tc, se, ps.clone(), move |ps, ev| {
|
||||
ps.stop[ev.axis as usize].set(true);
|
||||
});
|
||||
Axis120::handle(tc, se, ps.clone(), move |ps, ev| {
|
||||
ps.v120[ev.axis as usize].set(Some(ev.dist));
|
||||
});
|
||||
let st = seat_test.clone();
|
||||
AxisFrame::handle(tc, se, ps.clone(), move |ps, ev| {
|
||||
let source = ps.source.take();
|
||||
let px_x = ps.px[0].take();
|
||||
let px_y = ps.px[1].take();
|
||||
let stop_x = ps.stop[0].take();
|
||||
let stop_y = ps.stop[1].take();
|
||||
let v120_x = ps.v120[0].take();
|
||||
let v120_y = ps.v120[1].take();
|
||||
if all || ev.seat == seat {
|
||||
if all {
|
||||
print!("Seat: {}, ", st.name(ev.seat));
|
||||
}
|
||||
let mut need_comma = false;
|
||||
macro_rules! comma {
|
||||
() => {
|
||||
if std::mem::take(&mut need_comma) {
|
||||
print!(", ");
|
||||
}
|
||||
};
|
||||
}
|
||||
print!("Time: {:.4}, ", time(ev.time_usec));
|
||||
if let Some(source) = source {
|
||||
let source = match source {
|
||||
WHEEL => "wheel",
|
||||
FINGER => "finger",
|
||||
CONTINUOUS => "continuous",
|
||||
_ => "unknown",
|
||||
};
|
||||
print!("Source: {}", source);
|
||||
need_comma = true;
|
||||
}
|
||||
for (axis, px, steps, stop) in [
|
||||
("horizontal", px_x, v120_x, stop_x),
|
||||
("vertical", px_y, v120_y, stop_y),
|
||||
] {
|
||||
if px.is_some() || steps.is_some() || stop {
|
||||
comma!();
|
||||
print!("Axis {}: ", axis);
|
||||
}
|
||||
if let Some(dist) = px {
|
||||
print!("{:+.4}px", dist);
|
||||
need_comma = true;
|
||||
}
|
||||
if let Some(dist) = steps {
|
||||
comma!();
|
||||
print!("steps: {:+}/120", dist);
|
||||
need_comma = true;
|
||||
}
|
||||
if stop {
|
||||
comma!();
|
||||
print!("stop");
|
||||
need_comma = true;
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
});
|
||||
pending::<()>().await;
|
||||
}
|
||||
|
||||
fn time(time_usec: u64) -> f64 {
|
||||
time_usec as f64 / 1_000_000f64
|
||||
}
|
||||
|
||||
fn choose_seat(st: &SeatTest) -> u32 {
|
||||
let seat_name = match &st.args.seat {
|
||||
Some(s) => s.clone(),
|
||||
_ => {
|
||||
let mut seats: Vec<_> = st.names.borrow_mut().values().cloned().collect();
|
||||
seats.sort();
|
||||
eprintln!("Seats:");
|
||||
for seat in seats {
|
||||
eprintln!(" - {}", seat);
|
||||
}
|
||||
eprint!("Name a seat to test: ");
|
||||
let mut name = String::new();
|
||||
if let Err(e) = std::io::stdin().read_line(&mut name) {
|
||||
fatal!("Could not read from stdin: {}", e);
|
||||
}
|
||||
name
|
||||
}
|
||||
};
|
||||
let seat_name = seat_name.trim();
|
||||
for seat in st.names.borrow_mut().deref() {
|
||||
if seat.1.as_str() == seat_name {
|
||||
return *seat.0;
|
||||
}
|
||||
}
|
||||
fatal!("Unknown seat `{}`", seat_name);
|
||||
}
|
||||
|
|
@ -194,6 +194,7 @@ fn start_compositor2(
|
|||
scales,
|
||||
cursor_sizes: Default::default(),
|
||||
hardware_tick_cursor: Default::default(),
|
||||
testers: Default::default(),
|
||||
});
|
||||
state.tracker.register(ClientId::from_raw(0));
|
||||
create_dummy_output(&state);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ pub mod jay_compositor;
|
|||
pub mod jay_idle;
|
||||
pub mod jay_log_file;
|
||||
pub mod jay_screenshot;
|
||||
pub mod jay_seat_events;
|
||||
pub mod org_kde_kwin_server_decoration;
|
||||
pub mod org_kde_kwin_server_decoration_manager;
|
||||
pub mod wl_buffer;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@ use {
|
|||
cli::CliLogLevel,
|
||||
client::{Client, ClientError},
|
||||
globals::{Global, GlobalName},
|
||||
ifs::{jay_idle::JayIdle, jay_log_file::JayLogFile, jay_screenshot::JayScreenshot},
|
||||
ifs::{
|
||||
jay_idle::JayIdle, jay_log_file::JayLogFile, jay_screenshot::JayScreenshot,
|
||||
jay_seat_events::JaySeatEvents,
|
||||
},
|
||||
leaks::Tracker,
|
||||
object::Object,
|
||||
screenshoter::take_screenshot,
|
||||
|
|
@ -193,6 +196,35 @@ impl JayCompositor {
|
|||
self.client.symmetric_delete.set(true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_seats(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> {
|
||||
let _req: GetSeats = self.client.parse(self, parser)?;
|
||||
for seat in self.client.state.globals.seats.lock().values() {
|
||||
self.client.event(Seat {
|
||||
self_id: self.id,
|
||||
id: seat.id().raw(),
|
||||
name: seat.seat_name(),
|
||||
})
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn seat_events(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> {
|
||||
let req: SeatEvents = self.client.parse(self, parser)?;
|
||||
let se = Rc::new(JaySeatEvents {
|
||||
id: req.id,
|
||||
client: self.client.clone(),
|
||||
tracker: Default::default(),
|
||||
});
|
||||
track!(self.client, se);
|
||||
self.client.add_client_obj(&se)?;
|
||||
self.client
|
||||
.state
|
||||
.testers
|
||||
.borrow_mut()
|
||||
.insert((self.client.id, req.id), se);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
|
|
@ -207,11 +239,13 @@ object_base! {
|
|||
GET_CLIENT_ID => get_client_id,
|
||||
ENABLE_SYMMETRIC_DELETE => enable_symmetric_delete,
|
||||
UNLOCK => unlock,
|
||||
GET_SEATS => get_seats,
|
||||
SEAT_EVENTS => seat_events,
|
||||
}
|
||||
|
||||
impl Object for JayCompositor {
|
||||
fn num_requests(&self) -> u32 {
|
||||
UNLOCK + 1
|
||||
SEAT_EVENTS + 1
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
152
src/ifs/jay_seat_events.rs
Normal file
152
src/ifs/jay_seat_events.rs
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
use {
|
||||
crate::{
|
||||
backend::{self, KeyState},
|
||||
client::Client,
|
||||
fixed::Fixed,
|
||||
ifs::wl_seat::{wl_pointer::PendingScroll, SeatId},
|
||||
leaks::Tracker,
|
||||
object::Object,
|
||||
state::DeviceHandlerData,
|
||||
wire::{jay_seat_events::*, JaySeatEventsId},
|
||||
xkbcommon::ModifierState,
|
||||
},
|
||||
std::rc::Rc,
|
||||
};
|
||||
|
||||
pub struct JaySeatEvents {
|
||||
pub id: JaySeatEventsId,
|
||||
pub client: Rc<Client>,
|
||||
pub tracker: Tracker<Self>,
|
||||
}
|
||||
|
||||
impl JaySeatEvents {
|
||||
pub fn send_modifiers(&self, seat: SeatId, mods: &ModifierState) {
|
||||
self.client.event(Modifiers {
|
||||
self_id: self.id,
|
||||
seat: seat.raw(),
|
||||
modifiers: mods.mods_effective,
|
||||
group: mods.group,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn send_key(&self, seat: SeatId, time_usec: u64, key: u32, state: KeyState) {
|
||||
self.client.event(Key {
|
||||
self_id: self.id,
|
||||
seat: seat.raw(),
|
||||
time_usec,
|
||||
key,
|
||||
state: state as u32,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn send_pointer_abs(&self, seat: SeatId, time_usec: u64, x: Fixed, y: Fixed) {
|
||||
self.client.event(PointerAbs {
|
||||
self_id: self.id,
|
||||
seat: seat.raw(),
|
||||
time_usec,
|
||||
x,
|
||||
y,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn send_pointer_rel(
|
||||
&self,
|
||||
seat: SeatId,
|
||||
time_usec: u64,
|
||||
x: Fixed,
|
||||
y: Fixed,
|
||||
dx: Fixed,
|
||||
dy: Fixed,
|
||||
dx_unaccelerated: Fixed,
|
||||
dy_unaccelerated: Fixed,
|
||||
) {
|
||||
self.client.event(PointerRel {
|
||||
self_id: self.id,
|
||||
seat: seat.raw(),
|
||||
time_usec,
|
||||
x,
|
||||
y,
|
||||
dx,
|
||||
dy,
|
||||
dx_unaccelerated,
|
||||
dy_unaccelerated,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn send_button(&self, seat: SeatId, time_usec: u64, button: u32, state: KeyState) {
|
||||
self.client.event(Button {
|
||||
self_id: self.id,
|
||||
seat: seat.raw(),
|
||||
time_usec,
|
||||
button,
|
||||
state: state as u32,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn send_axis(
|
||||
&self,
|
||||
seat: SeatId,
|
||||
time_usec: u64,
|
||||
dev: &DeviceHandlerData,
|
||||
ps: &PendingScroll,
|
||||
) {
|
||||
if let Some(source) = ps.source.get() {
|
||||
self.client.event(AxisSource {
|
||||
self_id: self.id,
|
||||
source,
|
||||
});
|
||||
}
|
||||
for axis in 0..1 {
|
||||
if let Some(dist) = ps.v120[axis].get() {
|
||||
self.client.event(Axis120 {
|
||||
self_id: self.id,
|
||||
dist,
|
||||
axis: axis as _,
|
||||
});
|
||||
let px = (dist as f64 / backend::AXIS_120 as f64) * dev.px_per_scroll_wheel.get();
|
||||
self.client.event(AxisPx {
|
||||
self_id: self.id,
|
||||
dist: Fixed::from_f64(px),
|
||||
axis: axis as _,
|
||||
});
|
||||
} else if let Some(dist) = ps.px[axis].get() {
|
||||
self.client.event(AxisPx {
|
||||
self_id: self.id,
|
||||
dist,
|
||||
axis: axis as _,
|
||||
});
|
||||
}
|
||||
if ps.stop[axis].get() {
|
||||
self.client.event(AxisStop {
|
||||
self_id: self.id,
|
||||
axis: axis as _,
|
||||
});
|
||||
}
|
||||
}
|
||||
self.client.event(AxisFrame {
|
||||
self_id: self.id,
|
||||
seat: seat.raw(),
|
||||
time_usec,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
JaySeatEvents;
|
||||
}
|
||||
|
||||
impl Object for JaySeatEvents {
|
||||
fn num_requests(&self) -> u32 {
|
||||
0
|
||||
}
|
||||
|
||||
fn break_loops(&self) {
|
||||
self.client
|
||||
.state
|
||||
.testers
|
||||
.borrow_mut()
|
||||
.remove(&(self.client.id, self.id));
|
||||
}
|
||||
}
|
||||
|
||||
simple_add_obj!(JaySeatEvents);
|
||||
|
|
@ -191,7 +191,7 @@ impl WlSeatGlobal {
|
|||
time_usec,
|
||||
button,
|
||||
state,
|
||||
} => self.pointer_owner.button(self, time_usec, button, state),
|
||||
} => self.button_event(time_usec, button, state),
|
||||
|
||||
InputEvent::AxisSource { source } => self.pointer_owner.axis_source(source),
|
||||
InputEvent::Axis120 { dist, axis } => self.pointer_owner.axis_120(dist, axis),
|
||||
|
|
@ -216,6 +216,9 @@ impl WlSeatGlobal {
|
|||
let pos = output.node.global.pos.get();
|
||||
x += Fixed::from_int(pos.x1());
|
||||
y += Fixed::from_int(pos.y1());
|
||||
self.state.for_each_seat_tester(|t| {
|
||||
t.send_pointer_abs(self.id, time_usec, x, y);
|
||||
});
|
||||
self.set_new_position(time_usec, x, y);
|
||||
}
|
||||
|
||||
|
|
@ -238,6 +241,18 @@ impl WlSeatGlobal {
|
|||
let (mut x, mut y) = self.pos.get();
|
||||
x += dx;
|
||||
y += dy;
|
||||
self.state.for_each_seat_tester(|t| {
|
||||
t.send_pointer_rel(
|
||||
self.id,
|
||||
time_usec,
|
||||
x,
|
||||
y,
|
||||
dx,
|
||||
dy,
|
||||
dx_unaccelerated,
|
||||
dy_unaccelerated,
|
||||
);
|
||||
});
|
||||
let output = self.output.get();
|
||||
let pos = output.global.pos.get();
|
||||
let mut x_int = x.round_down();
|
||||
|
|
@ -268,10 +283,17 @@ impl WlSeatGlobal {
|
|||
self.set_new_position(time_usec, x, y);
|
||||
}
|
||||
|
||||
fn key_event(&self, time_usec: u64, key: u32, state: KeyState) {
|
||||
fn button_event(self: &Rc<Self>, time_usec: u64, button: u32, state: KeyState) {
|
||||
self.state.for_each_seat_tester(|t| {
|
||||
t.send_button(self.id, time_usec, button, state);
|
||||
});
|
||||
self.pointer_owner.button(self, time_usec, button, state);
|
||||
}
|
||||
|
||||
fn key_event(&self, time_usec: u64, key: u32, key_state: KeyState) {
|
||||
let (state, xkb_dir) = {
|
||||
let mut pk = self.pressed_keys.borrow_mut();
|
||||
match state {
|
||||
match key_state {
|
||||
KeyState::Released => {
|
||||
if !pk.remove(&key) {
|
||||
return;
|
||||
|
|
@ -304,6 +326,9 @@ impl WlSeatGlobal {
|
|||
}
|
||||
new_mods = kb_state.update(key, xkb_dir);
|
||||
}
|
||||
self.state.for_each_seat_tester(|t| {
|
||||
t.send_key(self.id, time_usec, key, key_state);
|
||||
});
|
||||
let node = self.keyboard_node.get();
|
||||
if shortcuts.is_empty() {
|
||||
node.node_on_key(self, time_usec, key, state);
|
||||
|
|
@ -313,6 +338,9 @@ impl WlSeatGlobal {
|
|||
}
|
||||
}
|
||||
if let Some(mods) = new_mods {
|
||||
self.state.for_each_seat_tester(|t| {
|
||||
t.send_modifiers(self.id, &mods);
|
||||
});
|
||||
node.node_on_mods(self, mods);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ impl PointerOwnerHolder {
|
|||
pub fn frame(&self, dev: &DeviceHandlerData, seat: &Rc<WlSeatGlobal>, time_usec: u64) {
|
||||
self.pending_scroll.time_usec.set(time_usec);
|
||||
let pending = self.pending_scroll.take();
|
||||
seat.state.for_each_seat_tester(|t| {
|
||||
t.send_axis(seat.id, time_usec, dev, &pending);
|
||||
});
|
||||
if let Some(node) = self.owner.get().axis_node(seat) {
|
||||
node.node_on_axis_event(dev, seat, &pending);
|
||||
}
|
||||
|
|
|
|||
12
src/state.rs
12
src/state.rs
|
|
@ -8,7 +8,7 @@ use {
|
|||
},
|
||||
backends::dummy::DummyBackend,
|
||||
cli::RunArgs,
|
||||
client::{Client, Clients, SerialRange, NUM_CACHED_SERIAL_RANGES},
|
||||
client::{Client, ClientId, Clients, SerialRange, NUM_CACHED_SERIAL_RANGES},
|
||||
config::ConfigProxy,
|
||||
cursor::{Cursor, ServerCursors},
|
||||
dbus::Dbus,
|
||||
|
|
@ -17,6 +17,7 @@ use {
|
|||
globals::{Globals, GlobalsError, WaylandGlobal},
|
||||
ifs::{
|
||||
ext_session_lock_v1::ExtSessionLockV1,
|
||||
jay_seat_events::JaySeatEvents,
|
||||
wl_drm::WlDrmGlobal,
|
||||
wl_seat::{SeatIds, WlSeatGlobal},
|
||||
wl_surface::{
|
||||
|
|
@ -41,6 +42,7 @@ use {
|
|||
queue::AsyncQueue, refcounted::RefCounted, run_toplevel::RunToplevel,
|
||||
},
|
||||
wheel::Wheel,
|
||||
wire::JaySeatEventsId,
|
||||
xkbcommon::{XkbContext, XkbKeymap},
|
||||
xwayland::{self, XWaylandEvent},
|
||||
},
|
||||
|
|
@ -114,6 +116,7 @@ pub struct State {
|
|||
pub scales: RefCounted<Fixed>,
|
||||
pub cursor_sizes: RefCounted<u32>,
|
||||
pub hardware_tick_cursor: AsyncQueue<Option<Rc<dyn Cursor>>>,
|
||||
pub testers: RefCell<AHashMap<(ClientId, JaySeatEventsId), Rc<JaySeatEvents>>>,
|
||||
}
|
||||
|
||||
// impl Drop for State {
|
||||
|
|
@ -622,4 +625,11 @@ impl State {
|
|||
};
|
||||
seat.update_hardware_cursor();
|
||||
}
|
||||
|
||||
pub fn for_each_seat_tester<F: Fn(&JaySeatEvents)>(&self, f: F) {
|
||||
let testers = self.testers.borrow_mut();
|
||||
for tester in testers.values() {
|
||||
f(tester);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,8 +35,21 @@ msg unlock = 8 {
|
|||
|
||||
}
|
||||
|
||||
msg get_seats = 9 {
|
||||
|
||||
}
|
||||
|
||||
msg seat_events = 10 {
|
||||
id: id(jay_seat_events),
|
||||
}
|
||||
|
||||
# events
|
||||
|
||||
msg client_id = 0 {
|
||||
client_id: pod(u64),
|
||||
}
|
||||
|
||||
msg seat = 1 {
|
||||
id: u32,
|
||||
name: str,
|
||||
}
|
||||
|
|
|
|||
62
wire/jay_seat_events.txt
Normal file
62
wire/jay_seat_events.txt
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# events
|
||||
|
||||
msg key = 0 {
|
||||
seat: u32,
|
||||
time_usec: pod(u64),
|
||||
key: u32,
|
||||
state: u32,
|
||||
}
|
||||
|
||||
msg pointer_abs = 1 {
|
||||
seat: u32,
|
||||
time_usec: pod(u64),
|
||||
x: fixed,
|
||||
y: fixed,
|
||||
}
|
||||
|
||||
msg pointer_rel = 2 {
|
||||
seat: u32,
|
||||
time_usec: pod(u64),
|
||||
x: fixed,
|
||||
y: fixed,
|
||||
dx: fixed,
|
||||
dy: fixed,
|
||||
dx_unaccelerated: fixed,
|
||||
dy_unaccelerated: fixed,
|
||||
}
|
||||
|
||||
msg button = 3 {
|
||||
seat: u32,
|
||||
time_usec: pod(u64),
|
||||
button: u32,
|
||||
state: u32,
|
||||
}
|
||||
|
||||
msg axis_source = 5 {
|
||||
source: u32,
|
||||
}
|
||||
|
||||
msg axis_px = 6 {
|
||||
dist: fixed,
|
||||
axis: u32,
|
||||
}
|
||||
|
||||
msg axis_stop = 7 {
|
||||
axis: u32,
|
||||
}
|
||||
|
||||
msg axis_120 = 8 {
|
||||
dist: i32,
|
||||
axis: u32,
|
||||
}
|
||||
|
||||
msg axis_frame = 9 {
|
||||
seat: u32,
|
||||
time_usec: pod(u64),
|
||||
}
|
||||
|
||||
msg modifiers = 10 {
|
||||
seat: u32,
|
||||
modifiers: u32,
|
||||
group: u32,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue