1
0
Fork 0
forked from wry/wry

autocommit 2022-04-05 21:08:07 CEST

This commit is contained in:
Julian Orth 2022-04-05 21:08:07 +02:00
parent a3e9f21fc5
commit 1d33088dba
27 changed files with 982 additions and 699 deletions

View file

@ -1,6 +1,7 @@
use jay_config::drm::{get_connector, on_connector_connected, on_new_connector};
use jay_config::embedded::grab_input_device; use jay_config::embedded::grab_input_device;
use jay_config::input::capability::{CAP_KEYBOARD, CAP_POINTER}; use jay_config::input::capability::{CAP_KEYBOARD, CAP_POINTER};
use jay_config::input::InputDevice; use jay_config::input::{create_seat, input_devices, on_new_input_device, InputDevice, Seat};
use jay_config::keyboard::mods::{Modifiers, ALT, CTRL, SHIFT}; use jay_config::keyboard::mods::{Modifiers, ALT, CTRL, SHIFT};
use jay_config::keyboard::syms::{ use jay_config::keyboard::syms::{
SYM_Super_L, SYM_b, SYM_d, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l, SYM_m, SYM_p, SYM_q, SYM_t, SYM_Super_L, SYM_b, SYM_d, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l, SYM_m, SYM_p, SYM_q, SYM_t,
@ -10,10 +11,7 @@ use jay_config::keyboard::syms::{
}; };
use jay_config::Axis::{Horizontal, Vertical}; use jay_config::Axis::{Horizontal, Vertical};
use jay_config::Direction::{Down, Left, Right, Up}; use jay_config::Direction::{Down, Left, Right, Up};
use jay_config::{ use jay_config::{config, get_workspace, quit, switch_to_vt, Command};
config, create_seat, get_workspace, input_devices, on_new_input_device, quit, switch_to_vt,
Command, Seat,
};
const MOD: Modifiers = ALT; const MOD: Modifiers = ALT;
@ -96,6 +94,18 @@ pub fn configure() {
}; };
input_devices().into_iter().for_each(handle_input_device); input_devices().into_iter().for_each(handle_input_device);
on_new_input_device(handle_input_device); on_new_input_device(handle_input_device);
let connectors_changed = || {
let left = get_connector("HDMI-A-1");
let right = get_connector("DP-1");
if left.connected() && right.connected() {
left.set_position(0, 0);
right.set_position(left.width(), 0);
}
};
on_new_connector(move |_| connectors_changed());
on_connector_connected(move |_| connectors_changed());
connectors_changed();
} }
config!(configure); config!(configure);

View file

@ -2,13 +2,14 @@
use crate::_private::ipc::{ClientMessage, InitMessage, Response, ServerMessage}; use crate::_private::ipc::{ClientMessage, InitMessage, Response, ServerMessage};
use crate::_private::{bincode_ops, logging, Config, ConfigEntry, ConfigEntryGen, VERSION}; use crate::_private::{bincode_ops, logging, Config, ConfigEntry, ConfigEntryGen, VERSION};
use crate::drm::Connector; use crate::drm::connector_type::{ConnectorType, CON_UNKNOWN};
use crate::drm::{Connector, Mode};
use crate::input::acceleration::AccelProfile; use crate::input::acceleration::AccelProfile;
use crate::input::capability::Capability; use crate::input::capability::Capability;
use crate::input::InputDevice; use crate::input::{InputDevice, Seat};
use crate::keyboard::keymap::Keymap; use crate::keyboard::keymap::Keymap;
use crate::theme::Color; use crate::theme::Color;
use crate::{Axis, Command, Direction, LogLevel, ModifiedKeySym, Seat, Workspace}; use crate::{Axis, Command, Direction, LogLevel, ModifiedKeySym, Workspace};
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::collections::HashMap; use std::collections::HashMap;
@ -127,6 +128,18 @@ pub unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize
}); });
} }
macro_rules! get_response {
($res:expr, $def:expr, $ty:ident, $($field:ident),+) => {
let ($($field,)+) = match $res {
Response::$ty { $($field,)+ } => ($($field,)+),
_ => {
log::error!("Server did not send a response to a {} request", stringify!($ty));
return $def;
}
};
}
}
impl Client { impl Client {
fn send(&self, msg: &ClientMessage) { fn send(&self, msg: &ClientMessage) {
let mut buf = self.bufs.borrow_mut().pop().unwrap_or_default(); let mut buf = self.bufs.borrow_mut().pop().unwrap_or_default();
@ -138,6 +151,10 @@ impl Client {
self.bufs.borrow_mut().push(buf); self.bufs.borrow_mut().push(buf);
} }
fn send_with_response(&self, msg: &ClientMessage) -> Response {
self.with_response(|| self.send(msg))
}
pub fn spawn(&self, command: &Command) { pub fn spawn(&self, command: &Command) {
let env = command let env = command
.env .env
@ -185,36 +202,27 @@ impl Client {
} }
pub fn seats(&self) -> Vec<Seat> { pub fn seats(&self) -> Vec<Seat> {
let response = self.with_response(|| self.send(&ClientMessage::GetSeats)); let res = self.with_response(|| self.send(&ClientMessage::GetSeats));
match response { get_response!(res, vec![], GetSeats, seats);
Response::GetSeats { seats } => seats, seats
_ => {
log::error!("Server did not send a response to a get_seats request");
vec![]
}
}
} }
pub fn mono(&self, seat: Seat) -> bool { pub fn mono(&self, seat: Seat) -> bool {
let res = self.with_response(|| self.send(&ClientMessage::GetMono { seat })); let res = self.with_response(|| self.send(&ClientMessage::GetMono { seat }));
match res { get_response!(res, false, GetMono, mono);
Response::GetMono { mono } => mono, mono
_ => {
log::error!("Server did not send a response to a get_mono request");
false
}
}
} }
pub fn get_workspace(&self, name: &str) -> Workspace { pub fn get_workspace(&self, name: &str) -> Workspace {
let res = self.with_response(|| self.send(&ClientMessage::GetWorkspace { name })); let res = self.with_response(|| self.send(&ClientMessage::GetWorkspace { name }));
match res { get_response!(res, Workspace(0), GetWorkspace, workspace);
Response::GetWorkspace { workspace } => workspace, workspace
_ => { }
log::error!("Server did not send a response to a get_workspace request");
Workspace(0) pub fn get_connector(&self, ty: ConnectorType, idx: u32) -> Connector {
} let res = self.with_response(|| self.send(&ClientMessage::GetConnector { ty, idx }));
} get_response!(res, Connector(0), GetConnector, connector);
connector
} }
pub fn show_workspace(&self, seat: Seat, workspace: Workspace) { pub fn show_workspace(&self, seat: Seat, workspace: Workspace) {
@ -223,13 +231,8 @@ impl Client {
pub fn split(&self, seat: Seat) -> Axis { pub fn split(&self, seat: Seat) -> Axis {
let res = self.with_response(|| self.send(&ClientMessage::GetSplit { seat })); let res = self.with_response(|| self.send(&ClientMessage::GetSplit { seat }));
match res { get_response!(res, Axis::Horizontal, GetSplit, axis);
Response::GetSplit { axis } => axis, axis
_ => {
log::error!("Server did not send a response to a get_split request");
Axis::Horizontal
}
}
} }
pub fn toggle_floating(&self, seat: Seat) { pub fn toggle_floating(&self, seat: Seat) {
@ -253,25 +256,15 @@ impl Client {
} }
pub fn get_title_height(&self) -> i32 { pub fn get_title_height(&self) -> i32 {
let resp = self.with_response(|| self.send(&ClientMessage::GetTitleHeight)); let res = self.with_response(|| self.send(&ClientMessage::GetTitleHeight));
match resp { get_response!(res, 0, GetTitleHeight, height);
Response::GetTitleHeight { height } => height, height
_ => {
log::warn!("Server did not reply to a get_title_height request");
0
}
}
} }
pub fn get_border_width(&self) -> i32 { pub fn get_border_width(&self) -> i32 {
let resp = self.with_response(|| self.send(&ClientMessage::GetBorderWidth)); let res = self.with_response(|| self.send(&ClientMessage::GetBorderWidth));
match resp { get_response!(res, 0, GetBorderWidth, width);
Response::GetBorderWidth { width } => width, width
_ => {
log::warn!("Server did not reply to a get_border_width request");
0
}
}
} }
pub fn set_title_height(&self, height: i32) { pub fn set_title_height(&self, height: i32) {
@ -299,25 +292,15 @@ impl Client {
} }
pub fn create_seat(&self, name: &str) -> Seat { pub fn create_seat(&self, name: &str) -> Seat {
let response = self.with_response(|| self.send(&ClientMessage::CreateSeat { name })); let res = self.with_response(|| self.send(&ClientMessage::CreateSeat { name }));
match response { get_response!(res, Seat(0), CreateSeat, seat);
Response::CreateSeat { seat } => seat, seat
_ => {
log::error!("Server did not send a response to a create_seat request");
Seat(0)
}
}
} }
pub fn get_input_devices(&self, seat: Option<Seat>) -> Vec<InputDevice> { pub fn get_input_devices(&self, seat: Option<Seat>) -> Vec<InputDevice> {
let res = self.with_response(|| self.send(&ClientMessage::GetInputDevices { seat })); let res = self.with_response(|| self.send(&ClientMessage::GetInputDevices { seat }));
match res { get_response!(res, vec!(), GetInputDevices, devices);
Response::GetInputDevices { devices } => devices, devices
_ => {
log::error!("Server did not send a response to a get_input_devices request");
vec![]
}
}
} }
pub fn on_new_seat<F: Fn(Seat) + 'static>(&self, f: F) { pub fn on_new_seat<F: Fn(Seat) + 'static>(&self, f: F) {
@ -336,6 +319,47 @@ impl Client {
*self.on_new_input_device.borrow_mut() = Some(Rc::new(f)); *self.on_new_input_device.borrow_mut() = Some(Rc::new(f));
} }
pub fn connector_set_position(&self, connector: Connector, x: i32, y: i32) {
self.send(&ClientMessage::ConnectorSetPosition { connector, x, y });
}
pub fn connector_connected(&self, connector: Connector) -> bool {
let res = self.send_with_response(&ClientMessage::ConnectorConnected { connector });
get_response!(res, false, ConnectorConnected, connected);
connected
}
pub fn connector_type(&self, connector: Connector) -> ConnectorType {
let res = self.send_with_response(&ClientMessage::ConnectorType { connector });
get_response!(res, CON_UNKNOWN, ConnectorType, ty);
ty
}
pub fn connector_mode(&self, connector: Connector) -> Mode {
let res = self.send_with_response(&ClientMessage::ConnectorMode { connector });
get_response!(
res,
Mode::zeroed(),
ConnectorMode,
width,
height,
refresh_millihz
);
Mode {
width,
height,
refresh_millihz,
}
}
pub fn on_new_connector<F: Fn(Connector) + 'static>(&self, f: F) {
*self.on_new_connector.borrow_mut() = Some(Rc::new(f));
}
pub fn on_connector_connected<F: Fn(Connector) + 'static>(&self, f: F) {
*self.on_connector_connected.borrow_mut() = Some(Rc::new(f));
}
pub fn set_seat(&self, device: InputDevice, seat: Seat) { pub fn set_seat(&self, device: InputDevice, seat: Seat) {
self.send(&ClientMessage::SetSeat { device, seat }) self.send(&ClientMessage::SetSeat { device, seat })
} }
@ -361,24 +385,14 @@ impl Client {
pub fn device_name(&self, device: InputDevice) -> String { pub fn device_name(&self, device: InputDevice) -> String {
let res = self.with_response(|| self.send(&ClientMessage::GetDeviceName { device })); let res = self.with_response(|| self.send(&ClientMessage::GetDeviceName { device }));
match res { get_response!(res, String::new(), GetDeviceName, name);
Response::GetDeviceName { name } => name, name
_ => {
log::error!("Server did not send a response to a get_device_name request");
String::new()
}
}
} }
pub fn has_capability(&self, device: InputDevice, cap: Capability) -> bool { pub fn has_capability(&self, device: InputDevice, cap: Capability) -> bool {
let res = self.with_response(|| self.send(&ClientMessage::HasCapability { device, cap })); let res = self.with_response(|| self.send(&ClientMessage::HasCapability { device, cap }));
match res { get_response!(res, false, HasCapability, has);
Response::HasCapability { has } => has, has
_ => {
log::error!("Server did not send a response to a has_capability request");
false
}
}
} }
pub fn seat_set_keymap(&self, seat: Seat, keymap: Keymap) { pub fn seat_set_keymap(&self, seat: Seat, keymap: Keymap) {
@ -391,24 +405,14 @@ impl Client {
pub fn seat_get_repeat_rate(&self, seat: Seat) -> (i32, i32) { pub fn seat_get_repeat_rate(&self, seat: Seat) -> (i32, i32) {
let res = self.with_response(|| self.send(&ClientMessage::SeatGetRepeatRate { seat })); let res = self.with_response(|| self.send(&ClientMessage::SeatGetRepeatRate { seat }));
match res { get_response!(res, (25, 250), GetRepeatRate, rate, delay);
Response::GetRepeatRate { rate, delay } => (rate, delay), (rate, delay)
_ => {
log::error!("Server did not send a response to a get_repeat_rate request");
(25, 250)
}
}
} }
pub fn parse_keymap(&self, keymap: &str) -> Keymap { pub fn parse_keymap(&self, keymap: &str) -> Keymap {
let res = self.with_response(|| self.send(&ClientMessage::ParseKeymap { keymap })); let res = self.with_response(|| self.send(&ClientMessage::ParseKeymap { keymap }));
match res { get_response!(res, Keymap(0), ParseKeymap, keymap);
Response::ParseKeymap { keymap } => keymap, keymap
_ => {
log::error!("Server did not send a response to a parse_keymap request");
Keymap(0)
}
}
} }
pub fn bind<T: Into<ModifiedKeySym>, F: Fn() + 'static>(&self, seat: Seat, mod_sym: T, f: F) { pub fn bind<T: Into<ModifiedKeySym>, F: Fn() + 'static>(&self, seat: Seat, mod_sym: T, f: F) {

View file

@ -1,12 +1,13 @@
use crate::drm::connector_type::ConnectorType;
use crate::drm::Connector; use crate::drm::Connector;
use crate::input::acceleration::AccelProfile; use crate::input::acceleration::AccelProfile;
use crate::input::capability::Capability; use crate::input::capability::Capability;
use crate::input::InputDevice; use crate::input::{InputDevice, Seat};
use crate::keyboard::keymap::Keymap; use crate::keyboard::keymap::Keymap;
use crate::keyboard::mods::Modifiers; use crate::keyboard::mods::Modifiers;
use crate::keyboard::syms::KeySym; use crate::keyboard::syms::KeySym;
use crate::theme::Color; use crate::theme::Color;
use crate::{Axis, Direction, LogLevel, Seat, Workspace}; use crate::{Axis, Direction, LogLevel, Workspace};
use bincode::{BorrowDecode, Decode, Encode}; use bincode::{BorrowDecode, Decode, Encode};
#[derive(Encode, BorrowDecode, Debug)] #[derive(Encode, BorrowDecode, Debug)]
@ -178,6 +179,24 @@ pub enum ClientMessage<'a> {
GetWorkspace { GetWorkspace {
name: &'a str, name: &'a str,
}, },
GetConnector {
ty: ConnectorType,
idx: u32,
},
ConnectorConnected {
connector: Connector,
},
ConnectorType {
connector: Connector,
},
ConnectorMode {
connector: Connector,
},
ConnectorSetPosition {
connector: Connector,
x: i32,
y: i32,
},
ShowWorkspace { ShowWorkspace {
seat: Seat, seat: Seat,
workspace: Workspace, workspace: Workspace,
@ -187,18 +206,57 @@ pub enum ClientMessage<'a> {
#[derive(Encode, Decode, Debug)] #[derive(Encode, Decode, Debug)]
pub enum Response { pub enum Response {
None, None,
GetSeats { seats: Vec<Seat> }, GetSeats {
GetSplit { axis: Axis }, seats: Vec<Seat>,
GetMono { mono: bool }, },
GetRepeatRate { rate: i32, delay: i32 }, GetSplit {
ParseKeymap { keymap: Keymap }, axis: Axis,
CreateSeat { seat: Seat }, },
GetInputDevices { devices: Vec<InputDevice> }, GetMono {
GetTitleHeight { height: i32 }, mono: bool,
GetBorderWidth { width: i32 }, },
HasCapability { has: bool }, GetRepeatRate {
GetDeviceName { name: String }, rate: i32,
GetWorkspace { workspace: Workspace }, delay: i32,
},
ParseKeymap {
keymap: Keymap,
},
CreateSeat {
seat: Seat,
},
GetInputDevices {
devices: Vec<InputDevice>,
},
GetTitleHeight {
height: i32,
},
GetBorderWidth {
width: i32,
},
HasCapability {
has: bool,
},
GetDeviceName {
name: String,
},
GetWorkspace {
workspace: Workspace,
},
GetConnector {
connector: Connector,
},
ConnectorConnected {
connected: bool,
},
ConnectorType {
ty: ConnectorType,
},
ConnectorMode {
width: i32,
height: i32,
refresh_millihz: u32,
},
} }
#[derive(Encode, Decode, Debug)] #[derive(Encode, Decode, Debug)]

View file

@ -1,4 +1,181 @@
use crate::drm::connector_type::{
ConnectorType, CON_9PIN_DIN, CON_COMPONENT, CON_COMPOSITE, CON_DISPLAY_PORT, CON_DPI, CON_DSI,
CON_DVIA, CON_DVID, CON_DVII, CON_EDP, CON_EMBEDDED_WINDOW, CON_HDMIA, CON_HDMIB, CON_LVDS,
CON_SPI, CON_SVIDEO, CON_TV, CON_UNKNOWN, CON_USB, CON_VGA, CON_VIRTUAL, CON_WRITEBACK,
};
use bincode::{Decode, Encode}; use bincode::{Decode, Encode};
use std::str::FromStr;
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct Mode {
pub(crate) width: i32,
pub(crate) height: i32,
pub(crate) refresh_millihz: u32,
}
impl Mode {
pub fn width(&self) -> i32 {
self.width
}
pub fn height(&self) -> i32 {
self.height
}
pub fn refresh_rate(&self) -> u32 {
self.refresh_millihz
}
pub(crate) fn zeroed() -> Self {
Self {
width: 0,
height: 0,
refresh_millihz: 0,
}
}
}
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)] #[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct Connector(pub u64); pub struct Connector(pub u64);
impl Connector {
pub fn exists(self) -> bool {
self.0 != 0
}
pub fn connected(self) -> bool {
if !self.exists() {
return false;
}
get!(false).connector_connected(self)
}
pub fn ty(self) -> ConnectorType {
if !self.exists() {
return CON_UNKNOWN;
}
get!(CON_UNKNOWN).connector_type(self)
}
pub fn mode(self) -> Mode {
if !self.exists() {
return Mode::zeroed();
}
get!(Mode::zeroed()).connector_mode(self)
}
pub fn width(self) -> i32 {
self.mode().width
}
pub fn height(self) -> i32 {
self.mode().height
}
pub fn refresh_rate(self) -> u32 {
self.mode().refresh_millihz
}
pub fn set_position(self, x: i32, y: i32) {
if !self.exists() {
log::warn!("set_position called on a connector that does not exist");
return;
}
get!().connector_set_position(self, x, y);
}
}
pub fn on_new_connector<F: Fn(Connector) + 'static>(f: F) {
get!().on_new_connector(f)
}
pub fn on_connector_connected<F: Fn(Connector) + 'static>(f: F) {
get!().on_connector_connected(f)
}
pub fn get_connector(id: impl ToConnectorId) -> Connector {
let (ty, idx) = match id.to_connector_id() {
Ok(id) => id,
Err(e) => {
log::error!("{}", e);
return Connector(0);
}
};
get!(Connector(0)).get_connector(ty, idx)
}
pub trait ToConnectorId {
fn to_connector_id(&self) -> Result<(ConnectorType, u32), String>;
}
impl ToConnectorId for (ConnectorType, u32) {
fn to_connector_id(&self) -> Result<(ConnectorType, u32), String> {
Ok(*self)
}
}
impl ToConnectorId for &'_ str {
fn to_connector_id(&self) -> Result<(ConnectorType, u32), String> {
let pairs = [
("DP-", CON_DISPLAY_PORT),
("eDP-", CON_EDP),
("HDMI-A-", CON_HDMIA),
("HDMI-B-", CON_HDMIB),
("EmbeddedWindow-", CON_EMBEDDED_WINDOW),
("VGA-", CON_VGA),
("DVI-I-", CON_DVII),
("DVI-D-", CON_DVID),
("DVI-A-", CON_DVIA),
("Composite-", CON_COMPOSITE),
("SVIDEO-", CON_SVIDEO),
("LVDS-", CON_LVDS),
("Component-", CON_COMPONENT),
("DIN-", CON_9PIN_DIN),
("TV-", CON_TV),
("Virtual-", CON_VIRTUAL),
("DSI-", CON_DSI),
("DPI-", CON_DPI),
("Writeback-", CON_WRITEBACK),
("SPI-", CON_SPI),
("USB-", CON_USB),
];
for (prefix, ty) in pairs {
if let Some(suffix) = self.strip_prefix(prefix) {
if let Ok(idx) = u32::from_str(suffix) {
return Ok((ty, idx));
}
}
}
Err(format!("`{}` is not a valid connector identifier", self))
}
}
pub mod connector_type {
use bincode::{Decode, Encode};
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct ConnectorType(pub u32);
pub const CON_UNKNOWN: ConnectorType = ConnectorType(0);
pub const CON_VGA: ConnectorType = ConnectorType(1);
pub const CON_DVII: ConnectorType = ConnectorType(2);
pub const CON_DVID: ConnectorType = ConnectorType(3);
pub const CON_DVIA: ConnectorType = ConnectorType(4);
pub const CON_COMPOSITE: ConnectorType = ConnectorType(5);
pub const CON_SVIDEO: ConnectorType = ConnectorType(6);
pub const CON_LVDS: ConnectorType = ConnectorType(7);
pub const CON_COMPONENT: ConnectorType = ConnectorType(8);
pub const CON_9PIN_DIN: ConnectorType = ConnectorType(9);
pub const CON_DISPLAY_PORT: ConnectorType = ConnectorType(10);
pub const CON_HDMIA: ConnectorType = ConnectorType(11);
pub const CON_HDMIB: ConnectorType = ConnectorType(12);
pub const CON_TV: ConnectorType = ConnectorType(13);
pub const CON_EDP: ConnectorType = ConnectorType(14);
pub const CON_VIRTUAL: ConnectorType = ConnectorType(15);
pub const CON_DSI: ConnectorType = ConnectorType(16);
pub const CON_DPI: ConnectorType = ConnectorType(17);
pub const CON_WRITEBACK: ConnectorType = ConnectorType(18);
pub const CON_SPI: ConnectorType = ConnectorType(19);
pub const CON_USB: ConnectorType = ConnectorType(20);
pub const CON_EMBEDDED_WINDOW: ConnectorType = ConnectorType(u32::MAX);
}

View file

@ -3,7 +3,7 @@ pub mod capability;
use crate::input::acceleration::AccelProfile; use crate::input::acceleration::AccelProfile;
use crate::input::capability::Capability; use crate::input::capability::Capability;
use crate::Seat; use crate::{Axis, Direction, Keymap, ModifiedKeySym, Workspace};
use bincode::{Decode, Encode}; use bincode::{Decode, Encode};
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)] #[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
@ -38,3 +38,126 @@ impl InputDevice {
get!(String::new()).device_name(self) get!(String::new()).device_name(self)
} }
} }
impl Seat {
#[doc(hidden)]
pub fn raw(self) -> u64 {
self.0
}
#[doc(hidden)]
pub fn from_raw(raw: u64) -> Self {
Self(raw)
}
pub fn bind<T: Into<ModifiedKeySym>, F: Fn() + 'static>(self, mod_sym: T, f: F) {
get!().bind(self, mod_sym, f)
}
pub fn unbind<T: Into<ModifiedKeySym>>(self, mod_sym: T) {
get!().unbind(self, mod_sym)
}
pub fn focus(self, direction: Direction) {
get!().focus(self, direction)
}
pub fn move_(self, direction: Direction) {
get!().move_(self, direction)
}
pub fn set_keymap(self, keymap: Keymap) {
get!().seat_set_keymap(self, keymap)
}
pub fn repeat_rate(self) -> (i32, i32) {
let mut res = (25, 250);
(|| res = get!().seat_get_repeat_rate(self))();
res
}
pub fn set_repeat_rate(self, rate: i32, delay: i32) {
get!().seat_set_repeat_rate(self, rate, delay)
}
pub fn mono(self) -> bool {
let mut res = false;
(|| res = get!().mono(self))();
res
}
pub fn set_mono(self, mono: bool) {
get!().set_mono(self, mono)
}
pub fn split(self) -> Axis {
let mut res = Axis::Horizontal;
(|| res = get!().split(self))();
res
}
pub fn set_split(self, axis: Axis) {
get!().set_split(self, axis)
}
pub fn input_devices(self) -> Vec<InputDevice> {
let mut res = vec![];
(|| res = get!().get_input_devices(Some(self)))();
res
}
pub fn create_split(self, axis: Axis) {
get!().create_split(self, axis);
}
pub fn focus_parent(self) {
get!().focus_parent(self);
}
pub fn toggle_floating(self) {
get!().toggle_floating(self);
}
pub fn show_workspace(self, workspace: Workspace) {
get!().show_workspace(self, workspace)
}
}
pub fn get_seats() -> Vec<Seat> {
let mut res = vec![];
(|| res = get!().seats())();
res
}
pub fn input_devices() -> Vec<InputDevice> {
let mut res = vec![];
(|| res = get!().get_input_devices(None))();
res
}
pub fn remove_all_seats() {}
pub fn create_seat(name: &str) -> Seat {
let mut res = Seat(0);
(|| res = get!().create_seat(name))();
res
}
pub fn on_new_seat<F: Fn(Seat) + 'static>(f: F) {
get!().on_new_seat(f)
}
pub fn on_new_input_device<F: Fn(InputDevice) + 'static>(f: F) {
get!().on_new_input_device(f)
}
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct Seat(pub u64);
impl Seat {
pub const INVALID: Self = Self(0);
pub fn is_invalid(self) -> bool {
self == Self::INVALID
}
}

View file

@ -1,4 +1,3 @@
use crate::input::InputDevice;
use crate::keyboard::keymap::Keymap; use crate::keyboard::keymap::Keymap;
use crate::keyboard::ModifiedKeySym; use crate::keyboard::ModifiedKeySym;
use bincode::{Decode, Encode}; use bincode::{Decode, Encode};
@ -31,17 +30,6 @@ pub enum Direction {
Right, Right,
} }
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct Seat(pub u64);
impl Seat {
pub const INVALID: Self = Self(0);
pub fn is_invalid(self) -> bool {
self == Self::INVALID
}
}
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)] #[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum Axis { pub enum Axis {
Horizontal, Horizontal,
@ -57,118 +45,6 @@ impl Axis {
} }
} }
impl Seat {
#[doc(hidden)]
pub fn raw(self) -> u64 {
self.0
}
#[doc(hidden)]
pub fn from_raw(raw: u64) -> Self {
Self(raw)
}
pub fn bind<T: Into<ModifiedKeySym>, F: Fn() + 'static>(self, mod_sym: T, f: F) {
get!().bind(self, mod_sym, f)
}
pub fn unbind<T: Into<ModifiedKeySym>>(self, mod_sym: T) {
get!().unbind(self, mod_sym)
}
pub fn focus(self, direction: Direction) {
get!().focus(self, direction)
}
pub fn move_(self, direction: Direction) {
get!().move_(self, direction)
}
pub fn set_keymap(self, keymap: Keymap) {
get!().seat_set_keymap(self, keymap)
}
pub fn repeat_rate(self) -> (i32, i32) {
let mut res = (25, 250);
(|| res = get!().seat_get_repeat_rate(self))();
res
}
pub fn set_repeat_rate(self, rate: i32, delay: i32) {
get!().seat_set_repeat_rate(self, rate, delay)
}
pub fn mono(self) -> bool {
let mut res = false;
(|| res = get!().mono(self))();
res
}
pub fn set_mono(self, mono: bool) {
get!().set_mono(self, mono)
}
pub fn split(self) -> Axis {
let mut res = Axis::Horizontal;
(|| res = get!().split(self))();
res
}
pub fn set_split(self, axis: Axis) {
get!().set_split(self, axis)
}
pub fn input_devices(self) -> Vec<InputDevice> {
let mut res = vec![];
(|| res = get!().get_input_devices(Some(self)))();
res
}
pub fn create_split(self, axis: Axis) {
get!().create_split(self, axis);
}
pub fn focus_parent(self) {
get!().focus_parent(self);
}
pub fn toggle_floating(self) {
get!().toggle_floating(self);
}
pub fn show_workspace(self, workspace: Workspace) {
get!().show_workspace(self, workspace)
}
}
pub fn get_seats() -> Vec<Seat> {
let mut res = vec![];
(|| res = get!().seats())();
res
}
pub fn input_devices() -> Vec<InputDevice> {
let mut res = vec![];
(|| res = get!().get_input_devices(None))();
res
}
pub fn remove_all_seats() {}
pub fn create_seat(name: &str) -> Seat {
let mut res = Seat(0);
(|| res = get!().create_seat(name))();
res
}
pub fn on_new_seat<F: Fn(Seat) + 'static>(f: F) {
get!().on_new_seat(f)
}
pub fn on_new_input_device<F: Fn(InputDevice) + 'static>(f: F) {
get!().on_new_input_device(f)
}
pub fn quit() { pub fn quit() {
get!().quit() get!().quit()
} }

View file

@ -30,12 +30,12 @@ pub struct MonitorInfo {
pub struct ConnectorKernelId { pub struct ConnectorKernelId {
pub ty: ConnectorType, pub ty: ConnectorType,
pub id: u32, pub idx: u32,
} }
impl Display for ConnectorKernelId { impl Display for ConnectorKernelId {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}-{}", self.ty, self.id) write!(f, "{}-{}", self.ty, self.idx)
} }
} }

View file

@ -22,7 +22,7 @@ impl Connector for DummyOutput {
fn kernel_id(&self) -> ConnectorKernelId { fn kernel_id(&self) -> ConnectorKernelId {
ConnectorKernelId { ConnectorKernelId {
ty: ConnectorType::Unknown(0), ty: ConnectorType::Unknown(0),
id: 0, idx: 0,
} }
} }

View file

@ -23,7 +23,7 @@ use crate::logind::{LogindError, Session};
use crate::render::RenderError; use crate::render::RenderError;
use crate::state::State; use crate::state::State;
use crate::udev::{Udev, UdevError, UdevMonitor}; use crate::udev::{Udev, UdevError, UdevMonitor};
use crate::utils::clonecell::CloneCell; use crate::utils::clonecell::{CloneCell, UnsafeCellCloneSafe};
use crate::utils::copyhashmap::CopyHashMap; use crate::utils::copyhashmap::CopyHashMap;
use crate::utils::errorfmt::ErrorFmt; use crate::utils::errorfmt::ErrorFmt;
use crate::utils::oserror::OsError; use crate::utils::oserror::OsError;
@ -226,6 +226,8 @@ enum MetalDevice {
Drm(Rc<MetalDrmDevice>), Drm(Rc<MetalDrmDevice>),
} }
unsafe impl UnsafeCellCloneSafe for MetalDevice {}
struct DeviceHolder { struct DeviceHolder {
devices: CopyHashMap<c::dev_t, MetalDevice>, devices: CopyHashMap<c::dev_t, MetalDevice>,
input_devices: RefCell<Vec<Option<Rc<MetalInputDevice>>>>, input_devices: RefCell<Vec<Option<Rc<MetalInputDevice>>>>,

View file

@ -1,5 +1,7 @@
use crate::async_engine::{AsyncFd, SpawnedFuture}; use crate::async_engine::{AsyncFd, SpawnedFuture};
use crate::backend::{BackendEvent, Connector, ConnectorEvent, ConnectorId, ConnectorKernelId, MonitorInfo}; use crate::backend::{
BackendEvent, Connector, ConnectorEvent, ConnectorId, ConnectorKernelId, MonitorInfo,
};
use crate::backends::metal::{DrmId, MetalBackend, MetalError}; use crate::backends::metal::{DrmId, MetalBackend, MetalError};
use crate::drm::drm::{ use crate::drm::drm::{
drm_mode_modeinfo, Change, ConnectorStatus, ConnectorType, DrmBlob, DrmConnector, DrmCrtc, drm_mode_modeinfo, Change, ConnectorStatus, ConnectorType, DrmBlob, DrmConnector, DrmCrtc,
@ -9,11 +11,13 @@ use crate::drm::drm::{
}; };
use crate::drm::gbm::{GbmDevice, GBM_BO_USE_RENDERING, GBM_BO_USE_SCANOUT}; use crate::drm::gbm::{GbmDevice, GBM_BO_USE_RENDERING, GBM_BO_USE_SCANOUT};
use crate::drm::{ModifiedFormat, INVALID_MODIFIER}; use crate::drm::{ModifiedFormat, INVALID_MODIFIER};
use crate::edid::Descriptor;
use crate::format::{Format, XRGB8888}; use crate::format::{Format, XRGB8888};
use crate::render::{Framebuffer, RenderContext}; use crate::render::{Framebuffer, RenderContext};
use crate::state::State; use crate::state::State;
use crate::utils::bitflags::BitflagsExt; use crate::utils::bitflags::BitflagsExt;
use crate::utils::clonecell::CloneCell; use crate::utils::clonecell::CloneCell;
use crate::utils::debug_fn::debug_fn;
use crate::utils::errorfmt::ErrorFmt; use crate::utils::errorfmt::ErrorFmt;
use crate::utils::numcell::NumCell; use crate::utils::numcell::NumCell;
use crate::utils::oserror::OsError; use crate::utils::oserror::OsError;
@ -25,7 +29,6 @@ use std::ffi::CString;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::rc::Rc; use std::rc::Rc;
use uapi::c; use uapi::c;
use crate::edid::Descriptor;
pub struct PendingDrmDevice { pub struct PendingDrmDevice {
pub id: DrmId, pub id: DrmId,
@ -126,7 +129,7 @@ impl Connector for MetalConnector {
fn kernel_id(&self) -> ConnectorKernelId { fn kernel_id(&self) -> ConnectorKernelId {
ConnectorKernelId { ConnectorKernelId {
ty: self.connector_type, ty: self.connector_type,
id: self.connector_type_id, idx: self.connector_type_id,
} }
} }
@ -224,11 +227,12 @@ fn create_connector(
} }
} }
let props = collect_properties(&dev.master, connector)?; let props = collect_properties(&dev.master, connector)?;
let connection = ConnectorStatus::from(info.connection); let connection = ConnectorStatus::from_drm(info.connection);
let connector_type = ConnectorType::from(info.connector_type); let connector_type = ConnectorType::from_drm(info.connector_type);
let mut name = String::new(); let mut name = String::new();
let mut manufacturer = String::new(); let mut manufacturer = String::new();
let mut serial_number = String::new(); let mut serial_number = String::new();
let connector_name = debug_fn(|f| write!(f, "{}-{}", connector_type, info.connector_type_id));
'fetch_edid: { 'fetch_edid: {
if connection != ConnectorStatus::Connected { if connection != ConnectorStatus::Connected {
break 'fetch_edid; break 'fetch_edid;
@ -236,21 +240,32 @@ fn create_connector(
let edid = match props.get("EDID") { let edid = match props.get("EDID") {
Ok(e) => e, Ok(e) => e,
_ => { _ => {
log::warn!("Connector {}-{} is connected but has no EDID blob", connector_type, info.connector_type_id); log::warn!(
"Connector {} is connected but has no EDID blob",
connector_name,
);
break 'fetch_edid; break 'fetch_edid;
} }
}; };
let blob = match dev.master.getblob_vec::<u8>(DrmBlob(edid.value.get() as _)) { let blob = match dev.master.getblob_vec::<u8>(DrmBlob(edid.value.get() as _)) {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
log::error!("Could not fetch edid property of connector {}-{}: {}", connector_type, info.connector_type_id, ErrorFmt(e)); log::error!(
"Could not fetch edid property of connector {}: {}",
connector_name,
ErrorFmt(e)
);
break 'fetch_edid; break 'fetch_edid;
} }
}; };
let edid = match crate::edid::parse(&blob) { let edid = match crate::edid::parse(&blob) {
Ok(e) => e, Ok(e) => e,
Err(e) => { Err(e) => {
log::error!("Could not parse edid property of connector {}-{}: {}", connector_type, info.connector_type_id, ErrorFmt(e)); log::error!(
"Could not parse edid property of connector {}: {}",
connector_name,
ErrorFmt(e)
);
break 'fetch_edid; break 'fetch_edid;
} }
}; };
@ -264,14 +279,21 @@ fn create_connector(
Descriptor::DisplayProductName(s) => { Descriptor::DisplayProductName(s) => {
name = s.to_string(); name = s.to_string();
} }
_ => { }, _ => {}
} }
} }
} }
if name.is_empty() { if name.is_empty() {
log::warn!("The display attached to connector {}-{} does not have a product name descriptor", connector_type, info.connector_type_id); log::warn!(
"The display attached to connector {} does not have a product name descriptor",
connector_name,
);
} }
if serial_number.is_empty() { if serial_number.is_empty() {
log::warn!(
"The display attached to connector {} does not have a serial number descriptor",
connector_name,
);
serial_number = edid.base_block.id_serial_number.to_string(); serial_number = edid.base_block.id_serial_number.to_string();
} }
} }
@ -547,25 +569,31 @@ impl MetalBackend {
.push(BackendEvent::NewConnector(connector.clone())); .push(BackendEvent::NewConnector(connector.clone()));
if connector.connection == ConnectorStatus::Connected { if connector.connection == ConnectorStatus::Connected {
if connector.primary_plane.get().is_none() { if connector.primary_plane.get().is_none() {
log::error!("Connector {}-{} is connected but does not have a primary plane", connector.connector_type, connector.connector_type_id); log::error!(
"Connector {}-{} is connected but does not have a primary plane",
connector.connector_type,
connector.connector_type_id
);
continue; continue;
} }
let mut prev_mode = None; let mut prev_mode = None;
let mut modes = vec!(); let mut modes = vec![];
for mode in connector.modes.iter().map(|m| m.to_backend()) { for mode in connector.modes.iter().map(|m| m.to_backend()) {
if prev_mode.replace(mode) != Some(mode) { if prev_mode.replace(mode) != Some(mode) {
modes.push(mode); modes.push(mode);
} }
} }
connector.events.push(ConnectorEvent::Connected(MonitorInfo { connector
modes, .events
manufacturer: connector.monitor_manufacturer.clone(), .push(ConnectorEvent::Connected(MonitorInfo {
product: connector.monitor_name.clone(), modes,
serial_number: connector.monitor_serial_number.clone(), manufacturer: connector.monitor_manufacturer.clone(),
initial_mode: connector.mode.get().unwrap().to_backend(), product: connector.monitor_name.clone(),
width_mm: connector.mm_width as _, serial_number: connector.monitor_serial_number.clone(),
height_mm: connector.mm_height as _, initial_mode: connector.mode.get().unwrap().to_backend(),
})); width_mm: connector.mm_width as _,
height_mm: connector.mm_height as _,
}));
self.start_connector(connector); self.start_connector(connector);
} }
} }

View file

@ -1,5 +1,9 @@
use crate::async_engine::{Phase, SpawnedFuture}; use crate::async_engine::{Phase, SpawnedFuture};
use crate::backend::{Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId, ConnectorKernelId, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent, KeyState, Mode, MonitorInfo, ScrollAxis}; use crate::backend::{
Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId, ConnectorKernelId, InputDevice,
InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent, KeyState, Mode,
MonitorInfo, ScrollAxis,
};
use crate::drm::drm::{ConnectorType, Drm, DrmError}; use crate::drm::drm::{ConnectorType, Drm, DrmError};
use crate::drm::gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING}; use crate::drm::gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING};
use crate::drm::{ModifiedFormat, INVALID_MODIFIER}; use crate::drm::{ModifiedFormat, INVALID_MODIFIER};
@ -878,7 +882,7 @@ impl Connector for XOutput {
fn kernel_id(&self) -> ConnectorKernelId { fn kernel_id(&self) -> ConnectorKernelId {
ConnectorKernelId { ConnectorKernelId {
ty: ConnectorType::EmbeddedWindow, ty: ConnectorType::EmbeddedWindow,
id: self.id.raw(), idx: self.id.raw(),
} }
} }

View file

@ -9,6 +9,7 @@ use crate::object::{Interface, Object, ObjectId, WL_DISPLAY_ID};
use crate::state::State; use crate::state::State;
use crate::utils::asyncevent::AsyncEvent; use crate::utils::asyncevent::AsyncEvent;
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError, OutBufferSwapchain}; use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError, OutBufferSwapchain};
use crate::utils::copyhashmap::Locked;
use crate::utils::errorfmt::ErrorFmt; use crate::utils::errorfmt::ErrorFmt;
use crate::utils::numcell::NumCell; use crate::utils::numcell::NumCell;
use crate::utils::queue::AsyncQueue; use crate::utils::queue::AsyncQueue;
@ -16,7 +17,7 @@ use crate::wire::WlRegistryId;
use crate::xwayland::XWaylandEvent; use crate::xwayland::XWaylandEvent;
use ahash::AHashMap; use ahash::AHashMap;
pub use error::{ClientError, ObjectError}; pub use error::{ClientError, ObjectError};
use std::cell::{Cell, RefCell, RefMut}; use std::cell::{Cell, RefCell};
use std::error::Error; use std::error::Error;
use std::fmt::{Debug, Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
use std::mem; use std::mem;
@ -335,7 +336,7 @@ impl Client {
self.checking_queue_size.set(false); self.checking_queue_size.set(false);
} }
pub fn lock_registries(&self) -> RefMut<AHashMap<WlRegistryId, Rc<WlRegistry>>> { pub fn lock_registries(&self) -> Locked<WlRegistryId, Rc<WlRegistry>> {
self.objects.registries() self.objects.registries()
} }

View file

@ -15,13 +15,12 @@ use crate::ifs::xdg_wm_base::XdgWmBase;
use crate::object::{Object, ObjectId}; use crate::object::{Object, ObjectId};
use crate::tree::Node; use crate::tree::Node;
use crate::utils::clonecell::CloneCell; use crate::utils::clonecell::CloneCell;
use crate::utils::copyhashmap::CopyHashMap; use crate::utils::copyhashmap::{CopyHashMap, Locked};
use crate::wire::{ use crate::wire::{
WlBufferId, WlDataSourceId, WlOutputId, WlRegionId, WlRegistryId, WlSeatId, WlSurfaceId, WlBufferId, WlDataSourceId, WlOutputId, WlRegionId, WlRegistryId, WlSeatId, WlSurfaceId,
XdgPositionerId, XdgSurfaceId, XdgToplevelId, XdgWmBaseId, ZwpPrimarySelectionSourceV1Id, XdgPositionerId, XdgSurfaceId, XdgToplevelId, XdgWmBaseId, ZwpPrimarySelectionSourceV1Id,
}; };
use ahash::AHashMap; use std::cell::RefCell;
use std::cell::{RefCell, RefMut};
use std::mem; use std::mem;
use std::ops::DerefMut; use std::ops::DerefMut;
use std::rc::Rc; use std::rc::Rc;
@ -167,7 +166,7 @@ impl Objects {
Ok(()) Ok(())
} }
pub fn registries(&self) -> RefMut<AHashMap<WlRegistryId, Rc<WlRegistry>>> { pub fn registries(&self) -> Locked<WlRegistryId, Rc<WlRegistry>> {
self.registries.lock() self.registries.lock()
} }

View file

@ -33,6 +33,8 @@ use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use thiserror::Error; use thiserror::Error;
pub const MAX_EXTENTS: i32 = (1 << 24) - 1;
pub fn start_compositor(global: GlobalArgs, args: RunArgs) { pub fn start_compositor(global: GlobalArgs, args: RunArgs) {
let forker = match ForkerProxy::create() { let forker = match ForkerProxy::create() {
Ok(f) => Rc::new(f), Ok(f) => Rc::new(f),
@ -120,10 +122,13 @@ fn main_(forker: Rc<ForkerProxy>, logger: Arc<Logger>, _args: &RunArgs) -> Resul
global: Rc::new(WlOutputGlobal::new( global: Rc::new(WlOutputGlobal::new(
state.globals.name(), state.globals.name(),
&Rc::new(ConnectorData { &Rc::new(ConnectorData {
connector: Rc::new(DummyOutput { id: state.connector_ids.next() }), connector: Rc::new(DummyOutput {
id: state.connector_ids.next(),
}),
monitor_info: Default::default(), monitor_info: Default::default(),
handler: Cell::new(None), handler: Cell::new(None),
node: Default::default() node: Default::default(),
connected: Cell::new(true),
}), }),
0, 0,
&backend::Mode { &backend::Mode {

View file

@ -9,9 +9,8 @@ use crate::utils::ptr_ext::PtrExt;
use jay_config::_private::ipc::{InitMessage, ServerMessage, V1InitMessage}; use jay_config::_private::ipc::{InitMessage, ServerMessage, V1InitMessage};
use jay_config::_private::{bincode_ops, ConfigEntry, VERSION}; use jay_config::_private::{bincode_ops, ConfigEntry, VERSION};
use jay_config::drm::Connector; use jay_config::drm::Connector;
use jay_config::input::InputDevice; use jay_config::input::{InputDevice, Seat};
use jay_config::keyboard::ModifiedKeySym; use jay_config::keyboard::ModifiedKeySym;
use jay_config::Seat;
use libloading::Library; use libloading::Library;
use std::cell::Cell; use std::cell::Cell;
use std::ptr; use std::ptr;

View file

@ -1,7 +1,10 @@
use crate::backend; use crate::backend;
use crate::backend::{InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId}; use crate::backend::{
ConnectorId, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, Mode,
};
use crate::compositor::MAX_EXTENTS;
use crate::ifs::wl_seat::{SeatId, WlSeatGlobal}; use crate::ifs::wl_seat::{SeatId, WlSeatGlobal};
use crate::state::{DeviceHandlerData, State}; use crate::state::{ConnectorData, DeviceHandlerData, State};
use crate::tree::walker::NodeVisitorBase; use crate::tree::walker::NodeVisitorBase;
use crate::tree::{ContainerNode, ContainerSplit, FloatNode, Node}; use crate::tree::{ContainerNode, ContainerSplit, FloatNode, Node};
use crate::utils::copyhashmap::CopyHashMap; use crate::utils::copyhashmap::CopyHashMap;
@ -9,20 +12,21 @@ use crate::utils::debug_fn::debug_fn;
use crate::utils::errorfmt::ErrorFmt; use crate::utils::errorfmt::ErrorFmt;
use crate::utils::numcell::NumCell; use crate::utils::numcell::NumCell;
use crate::utils::stack::Stack; use crate::utils::stack::Stack;
use crate::xkbcommon::XkbKeymap; use crate::xkbcommon::{XkbCommonError, XkbKeymap};
use bincode::error::DecodeError; use bincode::error::DecodeError;
use jay_config::_private::bincode_ops; use jay_config::_private::bincode_ops;
use jay_config::_private::ipc::{ClientMessage, Response, ServerMessage}; use jay_config::_private::ipc::{ClientMessage, Response, ServerMessage};
use jay_config::drm::Connector;
use jay_config::input::acceleration::{AccelProfile, ACCEL_PROFILE_ADAPTIVE, ACCEL_PROFILE_FLAT}; use jay_config::input::acceleration::{AccelProfile, ACCEL_PROFILE_ADAPTIVE, ACCEL_PROFILE_FLAT};
use jay_config::input::capability::{ use jay_config::input::capability::{
Capability, CAP_GESTURE, CAP_KEYBOARD, CAP_POINTER, CAP_SWITCH, CAP_TABLET_PAD, Capability, CAP_GESTURE, CAP_KEYBOARD, CAP_POINTER, CAP_SWITCH, CAP_TABLET_PAD,
CAP_TABLET_TOOL, CAP_TOUCH, CAP_TABLET_TOOL, CAP_TOUCH,
}; };
use jay_config::input::InputDevice; use jay_config::input::{InputDevice, Seat};
use jay_config::keyboard::keymap::Keymap; use jay_config::keyboard::keymap::Keymap;
use jay_config::keyboard::mods::Modifiers; use jay_config::keyboard::mods::Modifiers;
use jay_config::keyboard::syms::KeySym; use jay_config::keyboard::syms::KeySym;
use jay_config::{Axis, Direction, LogLevel, Seat, Workspace}; use jay_config::{Axis, Direction, LogLevel, Workspace};
use libloading::Library; use libloading::Library;
use log::Level; use log::Level;
use std::cell::Cell; use std::cell::Cell;
@ -101,20 +105,20 @@ impl ConfigProxyHandler {
}); });
} }
fn handle_parse_keymap(&self, keymap: &str) -> Result<(), ParseKeymapError> { fn handle_parse_keymap(&self, keymap: &str) -> Result<(), CphError> {
let (keymap, res) = match self.state.xkb_ctx.keymap_from_str(keymap) { let (keymap, res) = match self.state.xkb_ctx.keymap_from_str(keymap) {
Ok(keymap) => { Ok(keymap) => {
let id = Keymap(self.id()); let id = Keymap(self.id());
self.keymaps.set(id, keymap); self.keymaps.set(id, keymap);
(id, Ok(())) (id, Ok(()))
} }
_ => (Keymap::INVALID, Err(ParseKeymapError::ParsingFailed)), Err(e) => (Keymap::INVALID, Err(CphError::ParseKeymapError(e))),
}; };
self.respond(Response::ParseKeymap { keymap }); self.respond(Response::ParseKeymap { keymap });
res res
} }
fn handle_set_keymap(&self, seat: Seat, keymap: Keymap) -> Result<(), SeatSetKeymapError> { fn handle_set_keymap(&self, seat: Seat, keymap: Keymap) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
let keymap = if keymap.is_invalid() { let keymap = if keymap.is_invalid() {
self.state.default_keymap.clone() self.state.default_keymap.clone()
@ -125,37 +129,32 @@ impl ConfigProxyHandler {
Ok(()) Ok(())
} }
fn handle_focus(&self, seat: Seat, direction: Direction) -> Result<(), FocusError> { fn handle_focus(&self, seat: Seat, direction: Direction) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
seat.move_focus(direction); seat.move_focus(direction);
Ok(()) Ok(())
} }
fn handle_move(&self, seat: Seat, direction: Direction) -> Result<(), MoveError> { fn handle_move(&self, seat: Seat, direction: Direction) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
seat.move_focused(direction); seat.move_focused(direction);
Ok(()) Ok(())
} }
fn handle_get_repeat_rate(&self, seat: Seat) -> Result<(), SeatGetRepeatRateError> { fn handle_get_repeat_rate(&self, seat: Seat) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
let (rate, delay) = seat.get_rate(); let (rate, delay) = seat.get_rate();
self.respond(Response::GetRepeatRate { rate, delay }); self.respond(Response::GetRepeatRate { rate, delay });
Ok(()) Ok(())
} }
fn handle_set_repeat_rate( fn handle_set_repeat_rate(&self, seat: Seat, rate: i32, delay: i32) -> Result<(), CphError> {
&self,
seat: Seat,
rate: i32,
delay: i32,
) -> Result<(), SeatSetRepeatRateError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
if rate < 0 { if rate < 0 {
return Err(SeatSetRepeatRateError::NegativeRate); return Err(CphError::NegativeRepeatRate);
} }
if delay < 0 { if delay < 0 {
return Err(SeatSetRepeatRateError::NegativeDelay); return Err(CphError::NegativeRepeatDelay);
} }
seat.set_rate(rate, delay); seat.set_rate(rate, delay);
Ok(()) Ok(())
@ -184,6 +183,17 @@ impl ConfigProxyHandler {
} }
} }
fn get_connector(&self, connector: Connector) -> Result<Rc<ConnectorData>, CphError> {
let data = self
.state
.connectors
.get(&ConnectorId::from_raw(connector.0 as _));
match data {
Some(d) => Ok(d),
_ => Err(CphError::ConnectorDoesNotExist(connector)),
}
}
fn get_seat(&self, seat: Seat) -> Result<Rc<WlSeatGlobal>, CphError> { fn get_seat(&self, seat: Seat) -> Result<Rc<WlSeatGlobal>, CphError> {
let seats = self.state.globals.seats.lock(); let seats = self.state.globals.seats.lock();
for seat_global in seats.values() { for seat_global in seats.values() {
@ -209,7 +219,7 @@ impl ConfigProxyHandler {
} }
} }
fn handle_set_seat(&self, device: InputDevice, seat: Seat) -> Result<(), SetSeatError> { fn handle_set_seat(&self, device: InputDevice, seat: Seat) -> Result<(), CphError> {
let seat = if seat.is_invalid() { let seat = if seat.is_invalid() {
None None
} else { } else {
@ -224,7 +234,7 @@ impl ConfigProxyHandler {
&self, &self,
device: InputDevice, device: InputDevice,
left_handed: bool, left_handed: bool,
) -> Result<(), SetLeftHandedError> { ) -> Result<(), CphError> {
let dev = self.get_device_handler_data(device)?; let dev = self.get_device_handler_data(device)?;
dev.device.set_left_handed(left_handed); dev.device.set_left_handed(left_handed);
Ok(()) Ok(())
@ -234,22 +244,18 @@ impl ConfigProxyHandler {
&self, &self,
device: InputDevice, device: InputDevice,
accel_profile: AccelProfile, accel_profile: AccelProfile,
) -> Result<(), SetAccelProfileError> { ) -> Result<(), CphError> {
let dev = self.get_device_handler_data(device)?; let dev = self.get_device_handler_data(device)?;
let profile = match accel_profile { let profile = match accel_profile {
ACCEL_PROFILE_FLAT => InputDeviceAccelProfile::Flat, ACCEL_PROFILE_FLAT => InputDeviceAccelProfile::Flat,
ACCEL_PROFILE_ADAPTIVE => InputDeviceAccelProfile::Adaptive, ACCEL_PROFILE_ADAPTIVE => InputDeviceAccelProfile::Adaptive,
_ => return Err(SetAccelProfileError::UnknownAccelProfile(accel_profile)), _ => return Err(CphError::UnknownAccelProfile(accel_profile)),
}; };
dev.device.set_accel_profile(profile); dev.device.set_accel_profile(profile);
Ok(()) Ok(())
} }
fn handle_set_accel_speed( fn handle_set_accel_speed(&self, device: InputDevice, speed: f64) -> Result<(), CphError> {
&self,
device: InputDevice,
speed: f64,
) -> Result<(), SetAccelSpeedError> {
let dev = self.get_device_handler_data(device)?; let dev = self.get_device_handler_data(device)?;
dev.device.set_accel_speed(speed); dev.device.set_accel_speed(speed);
Ok(()) Ok(())
@ -259,7 +265,7 @@ impl ConfigProxyHandler {
&self, &self,
device: InputDevice, device: InputDevice,
matrix: [[f64; 2]; 2], matrix: [[f64; 2]; 2],
) -> Result<(), SetTransformMatrixError> { ) -> Result<(), CphError> {
let dev = self.get_device_handler_data(device)?; let dev = self.get_device_handler_data(device)?;
dev.device.set_transform_matrix(matrix); dev.device.set_transform_matrix(matrix);
Ok(()) Ok(())
@ -281,14 +287,14 @@ impl ConfigProxyHandler {
}); });
} }
fn handle_show_workspace(&self, seat: Seat, ws: Workspace) -> Result<(), ShowWorkspaceError> { fn handle_show_workspace(&self, seat: Seat, ws: Workspace) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
let name = self.get_workspace(ws)?; let name = self.get_workspace(ws)?;
self.state.show_workspace(&seat, &name); self.state.show_workspace(&seat, &name);
Ok(()) Ok(())
} }
fn handle_get_device_name(&self, device: InputDevice) -> Result<(), GetDeviceNameError> { fn handle_get_device_name(&self, device: InputDevice) -> Result<(), CphError> {
let dev = self.get_device_handler_data(device)?; let dev = self.get_device_handler_data(device)?;
let name = dev.device.name(); let name = dev.device.name();
self.respond(Response::GetDeviceName { self.respond(Response::GetDeviceName {
@ -297,11 +303,72 @@ impl ConfigProxyHandler {
Ok(()) Ok(())
} }
fn handle_has_capability( fn handle_connector_connected(&self, connector: Connector) -> Result<(), CphError> {
let connector = self.get_connector(connector)?;
self.respond(Response::ConnectorConnected {
connected: connector.connected.get(),
});
Ok(())
}
fn handle_connector_type(&self, connector: Connector) -> Result<(), CphError> {
let connector = self.get_connector(connector)?;
self.respond(Response::ConnectorType {
ty: connector.connector.kernel_id().ty.to_config(),
});
Ok(())
}
fn handle_connector_mode(&self, connector: Connector) -> Result<(), CphError> {
let connector = self.get_connector(connector)?;
let mut mode = Mode::default();
if let Some(node) = connector.node.get() {
mode = node.global.mode.get();
}
self.respond(Response::ConnectorMode {
width: mode.width,
height: mode.height,
refresh_millihz: mode.refresh_rate_millihz,
});
Ok(())
}
fn handle_connector_set_position(
&self, &self,
device: InputDevice, connector: Connector,
cap: Capability, x: i32,
) -> Result<(), HasCapabilityError> { y: i32,
) -> Result<(), CphError> {
let connector = self.get_connector(connector)?;
if x < 0 || y < 0 || x > MAX_EXTENTS || y > MAX_EXTENTS {
return Err(CphError::InvalidConnectorPosition(x, y));
}
if let Some(node) = connector.node.get() {
node.set_position(x, y);
}
Ok(())
}
fn handle_get_connector(
&self,
ty: jay_config::drm::connector_type::ConnectorType,
idx: u32,
) -> Result<(), CphError> {
let connectors = self.state.connectors.lock();
let connector = 'get_connector: {
for connector in connectors.values() {
let kid = connector.connector.kernel_id();
if ty == kid.ty.to_config() && idx == kid.idx {
break 'get_connector Connector(connector.connector.id().raw() as _);
}
}
Connector(0)
};
self.respond(Response::GetConnector { connector });
Ok(())
}
fn handle_has_capability(&self, device: InputDevice, cap: Capability) -> Result<(), CphError> {
let dev = self.get_device_handler_data(device)?; let dev = self.get_device_handler_data(device)?;
let mut is_unknown = false; let mut is_unknown = false;
let has_cap = 'has_cap: { let has_cap = 'has_cap: {
@ -322,13 +389,13 @@ impl ConfigProxyHandler {
}; };
self.respond(Response::HasCapability { has: has_cap }); self.respond(Response::HasCapability { has: has_cap });
if is_unknown { if is_unknown {
Err(HasCapabilityError::UnknownCapability(cap)) Err(CphError::UnknownCapability(cap))
} else { } else {
Ok(()) Ok(())
} }
} }
fn handle_get_mono(&self, seat: Seat) -> Result<(), GetMonoError> { fn handle_get_mono(&self, seat: Seat) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
self.respond(Response::GetMono { self.respond(Response::GetMono {
mono: seat.get_mono().unwrap_or(false), mono: seat.get_mono().unwrap_or(false),
@ -336,13 +403,13 @@ impl ConfigProxyHandler {
Ok(()) Ok(())
} }
fn handle_set_mono(&self, seat: Seat, mono: bool) -> Result<(), SetMonoError> { fn handle_set_mono(&self, seat: Seat, mono: bool) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
seat.set_mono(mono); seat.set_mono(mono);
Ok(()) Ok(())
} }
fn handle_get_split(&self, seat: Seat) -> Result<(), GetSplitError> { fn handle_get_split(&self, seat: Seat) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
self.respond(Response::GetSplit { self.respond(Response::GetSplit {
axis: seat axis: seat
@ -353,7 +420,7 @@ impl ConfigProxyHandler {
Ok(()) Ok(())
} }
fn handle_set_split(&self, seat: Seat, axis: Axis) -> Result<(), SetSplitError> { fn handle_set_split(&self, seat: Seat, axis: Axis) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
seat.set_split(axis.into()); seat.set_split(axis.into());
Ok(()) Ok(())
@ -364,7 +431,7 @@ impl ConfigProxyHandler {
seat: Seat, seat: Seat,
mods: Modifiers, mods: Modifiers,
sym: KeySym, sym: KeySym,
) -> Result<(), AddShortcutError> { ) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
seat.add_shortcut(mods, sym); seat.add_shortcut(mods, sym);
Ok(()) Ok(())
@ -375,7 +442,7 @@ impl ConfigProxyHandler {
seat: Seat, seat: Seat,
mods: Modifiers, mods: Modifiers,
sym: KeySym, sym: KeySym,
) -> Result<(), AddShortcutError> { ) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
seat.remove_shortcut(mods, sym); seat.remove_shortcut(mods, sym);
Ok(()) Ok(())
@ -421,16 +488,16 @@ impl ConfigProxyHandler {
prog: &str, prog: &str,
args: Vec<String>, args: Vec<String>,
env: Vec<(String, String)>, env: Vec<(String, String)>,
) -> Result<(), RunError> { ) -> Result<(), CphError> {
let forker = match self.state.forker.get() { let forker = match self.state.forker.get() {
Some(f) => f, Some(f) => f,
_ => return Err(RunError::NoForker), _ => return Err(CphError::NoForker),
}; };
forker.spawn(prog.to_string(), args, env, None); forker.spawn(prog.to_string(), args, env, None);
Ok(()) Ok(())
} }
fn handle_grab(&self, kb: InputDevice, grab: bool) -> Result<(), GrabError> { fn handle_grab(&self, kb: InputDevice, grab: bool) -> Result<(), CphError> {
let kb = self.get_kb(kb)?; let kb = self.get_kb(kb)?;
kb.grab(grab); kb.grab(grab);
Ok(()) Ok(())
@ -448,13 +515,13 @@ impl ConfigProxyHandler {
}); });
} }
fn handle_create_split(&self, seat: Seat, axis: Axis) -> Result<(), CreateSplitError> { fn handle_create_split(&self, seat: Seat, axis: Axis) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
seat.create_split(axis.into()); seat.create_split(axis.into());
Ok(()) Ok(())
} }
fn handle_focus_parent(&self, seat: Seat) -> Result<(), FocusParentError> { fn handle_focus_parent(&self, seat: Seat) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
seat.focus_parent(); seat.focus_parent();
Ok(()) Ok(())
@ -472,7 +539,7 @@ impl ConfigProxyHandler {
} }
} }
fn handle_toggle_floating(&self, seat: Seat) -> Result<(), FocusParentError> { fn handle_toggle_floating(&self, seat: Seat) -> Result<(), CphError> {
let seat = self.get_seat(seat)?; let seat = self.get_seat(seat)?;
seat.toggle_floating(); seat.toggle_floating();
Ok(()) Ok(())
@ -508,24 +575,24 @@ impl ConfigProxyHandler {
self.state.root.clone().visit(&mut V); self.state.root.clone().visit(&mut V);
} }
fn handle_set_title_height(&self, height: i32) -> Result<(), SetTitleHeightError> { fn handle_set_title_height(&self, height: i32) -> Result<(), CphError> {
if height < 0 { if height < 0 {
return Err(SetTitleHeightError::Negative(height)); return Err(CphError::NegativeTitleHeight(height));
} }
if height > 1000 { if height > 1000 {
return Err(SetTitleHeightError::Excessive(height)); return Err(CphError::ExcessiveTitleHeight(height));
} }
self.state.theme.title_height.set(height); self.state.theme.title_height.set(height);
self.spaces_change(); self.spaces_change();
Ok(()) Ok(())
} }
fn handle_set_border_width(&self, width: i32) -> Result<(), SetBorderWidthError> { fn handle_set_border_width(&self, width: i32) -> Result<(), CphError> {
if width < 0 { if width < 0 {
return Err(SetBorderWidthError::Negative(width)); return Err(CphError::NegativeBorderWidth(width));
} }
if width > 1000 { if width > 1000 {
return Err(SetBorderWidthError::Excessive(width)); return Err(CphError::ExcessiveBorderWidth(width));
} }
self.state.theme.border_width.set(width); self.state.theme.border_width.set(width);
self.spaces_change(); self.spaces_change();
@ -569,34 +636,54 @@ impl ConfigProxyHandler {
line, line,
} => self.handle_log_request(level, msg, file, line), } => self.handle_log_request(level, msg, file, line),
ClientMessage::CreateSeat { name } => self.handle_create_seat(name), ClientMessage::CreateSeat { name } => self.handle_create_seat(name),
ClientMessage::ParseKeymap { keymap } => self.handle_parse_keymap(keymap)?, ClientMessage::ParseKeymap { keymap } => {
self.handle_parse_keymap(keymap).wrn("parse_keymap")?
}
ClientMessage::SeatSetKeymap { seat, keymap } => { ClientMessage::SeatSetKeymap { seat, keymap } => {
self.handle_set_keymap(seat, keymap)? self.handle_set_keymap(seat, keymap).wrn("set_keymap")?
} }
ClientMessage::SeatGetRepeatRate { seat } => self.handle_get_repeat_rate(seat)?, ClientMessage::SeatGetRepeatRate { seat } => {
ClientMessage::SeatSetRepeatRate { seat, rate, delay } => { self.handle_get_repeat_rate(seat).wrn("get_repeat_rate")?
self.handle_set_repeat_rate(seat, rate, delay)?
} }
ClientMessage::SetSeat { device, seat } => self.handle_set_seat(device, seat)?, ClientMessage::SeatSetRepeatRate { seat, rate, delay } => self
ClientMessage::GetMono { seat } => self.handle_get_mono(seat)?, .handle_set_repeat_rate(seat, rate, delay)
ClientMessage::SetMono { seat, mono } => self.handle_set_mono(seat, mono)?, .wrn("set_repeat_rate")?,
ClientMessage::GetSplit { seat } => self.handle_get_split(seat)?, ClientMessage::SetSeat { device, seat } => {
ClientMessage::SetSplit { seat, axis } => self.handle_set_split(seat, axis)?, self.handle_set_seat(device, seat).wrn("set_seat")?
ClientMessage::AddShortcut { seat, mods, sym } => {
self.handle_add_shortcut(seat, mods, sym)?
} }
ClientMessage::RemoveShortcut { seat, mods, sym } => { ClientMessage::GetMono { seat } => self.handle_get_mono(seat).wrn("get_mono")?,
self.handle_remove_shortcut(seat, mods, sym)? ClientMessage::SetMono { seat, mono } => {
self.handle_set_mono(seat, mono).wrn("set_mono")?
}
ClientMessage::GetSplit { seat } => self.handle_get_split(seat).wrn("get_split")?,
ClientMessage::SetSplit { seat, axis } => {
self.handle_set_split(seat, axis).wrn("set_split")?
}
ClientMessage::AddShortcut { seat, mods, sym } => self
.handle_add_shortcut(seat, mods, sym)
.wrn("add_shortcut")?,
ClientMessage::RemoveShortcut { seat, mods, sym } => self
.handle_remove_shortcut(seat, mods, sym)
.wrn("remove_shortcut")?,
ClientMessage::Focus { seat, direction } => {
self.handle_focus(seat, direction).wrn("focus")?
}
ClientMessage::Move { seat, direction } => {
self.handle_move(seat, direction).wrn("move")?
} }
ClientMessage::Focus { seat, direction } => self.handle_focus(seat, direction)?,
ClientMessage::Move { seat, direction } => self.handle_move(seat, direction)?,
ClientMessage::GetInputDevices { seat } => self.handle_get_input_devices(seat), ClientMessage::GetInputDevices { seat } => self.handle_get_input_devices(seat),
ClientMessage::GetSeats => self.handle_get_seats(), ClientMessage::GetSeats => self.handle_get_seats(),
ClientMessage::RemoveSeat { .. } => {} ClientMessage::RemoveSeat { .. } => {}
ClientMessage::Run { prog, args, env } => self.handle_run(prog, args, env)?, ClientMessage::Run { prog, args, env } => {
ClientMessage::GrabKb { kb, grab } => self.handle_grab(kb, grab)?, self.handle_run(prog, args, env).wrn("run")?
ClientMessage::SetTitleHeight { height } => self.handle_set_title_height(height)?, }
ClientMessage::SetBorderWidth { width } => self.handle_set_border_width(width)?, ClientMessage::GrabKb { kb, grab } => self.handle_grab(kb, grab).wrn("grab")?,
ClientMessage::SetTitleHeight { height } => self
.handle_set_title_height(height)
.wrn("set_title_height")?,
ClientMessage::SetBorderWidth { width } => self
.handle_set_border_width(width)
.wrn("set_bordre_width")?,
ClientMessage::SetTitleColor { color } => self.handle_set_title_color(color), ClientMessage::SetTitleColor { color } => self.handle_set_title_color(color),
ClientMessage::SetTitleUnderlineColor { color } => { ClientMessage::SetTitleUnderlineColor { color } => {
self.handle_set_title_underline_color(color) self.handle_set_title_underline_color(color)
@ -605,32 +692,57 @@ impl ConfigProxyHandler {
ClientMessage::SetBackgroundColor { color } => self.handle_set_background_color(color), ClientMessage::SetBackgroundColor { color } => self.handle_set_background_color(color),
ClientMessage::GetTitleHeight => self.handle_get_title_height(), ClientMessage::GetTitleHeight => self.handle_get_title_height(),
ClientMessage::GetBorderWidth => self.handle_get_border_width(), ClientMessage::GetBorderWidth => self.handle_get_border_width(),
ClientMessage::CreateSplit { seat, axis } => self.handle_create_split(seat, axis)?, ClientMessage::CreateSplit { seat, axis } => {
ClientMessage::FocusParent { seat } => self.handle_focus_parent(seat)?, self.handle_create_split(seat, axis).wrn("create_split")?
ClientMessage::ToggleFloating { seat } => self.handle_toggle_floating(seat)?, }
ClientMessage::FocusParent { seat } => {
self.handle_focus_parent(seat).wrn("focus_parent")?
}
ClientMessage::ToggleFloating { seat } => {
self.handle_toggle_floating(seat).wrn("toggle_floating")?
}
ClientMessage::Quit => self.handle_quit(), ClientMessage::Quit => self.handle_quit(),
ClientMessage::SwitchTo { vtnr } => self.handle_switch_to(vtnr), ClientMessage::SwitchTo { vtnr } => self.handle_switch_to(vtnr),
ClientMessage::HasCapability { device, cap } => { ClientMessage::HasCapability { device, cap } => self
self.handle_has_capability(device, cap)? .handle_has_capability(device, cap)
} .wrn("has_capability")?,
ClientMessage::SetLeftHanded { ClientMessage::SetLeftHanded {
device, device,
left_handed, left_handed,
} => self.handle_set_left_handed(device, left_handed)?, } => self
ClientMessage::SetAccelProfile { device, profile } => { .handle_set_left_handed(device, left_handed)
self.handle_set_accel_profile(device, profile)? .wrn("set_left_handed")?,
ClientMessage::SetAccelProfile { device, profile } => self
.handle_set_accel_profile(device, profile)
.wrn("set_accel_profile")?,
ClientMessage::SetAccelSpeed { device, speed } => self
.handle_set_accel_speed(device, speed)
.wrn("set_accel_speed")?,
ClientMessage::SetTransformMatrix { device, matrix } => self
.handle_set_transform_matrix(device, matrix)
.wrn("set_transform_matrix")?,
ClientMessage::GetDeviceName { device } => {
self.handle_get_device_name(device).wrn("get_device_name")?
} }
ClientMessage::SetAccelSpeed { device, speed } => {
self.handle_set_accel_speed(device, speed)?
}
ClientMessage::SetTransformMatrix { device, matrix } => {
self.handle_set_transform_matrix(device, matrix)?
}
ClientMessage::GetDeviceName { device } => self.handle_get_device_name(device)?,
ClientMessage::GetWorkspace { name } => self.handle_get_workspace(name), ClientMessage::GetWorkspace { name } => self.handle_get_workspace(name),
ClientMessage::ShowWorkspace { seat, workspace } => { ClientMessage::ShowWorkspace { seat, workspace } => self
self.handle_show_workspace(seat, workspace)? .handle_show_workspace(seat, workspace)
.wrn("show_workspace")?,
ClientMessage::GetConnector { ty, idx } => {
self.handle_get_connector(ty, idx).wrn("get_connector")?
} }
ClientMessage::ConnectorConnected { connector } => self
.handle_connector_connected(connector)
.wrn("connector_connected")?,
ClientMessage::ConnectorType { connector } => self
.handle_connector_type(connector)
.wrn("connector_type")?,
ClientMessage::ConnectorMode { connector } => self
.handle_connector_mode(connector)
.wrn("connector_mode")?,
ClientMessage::ConnectorSetPosition { connector, x, y } => self
.handle_connector_set_position(connector, x, y)
.wrn("connector_set_position")?,
} }
Ok(()) Ok(())
} }
@ -638,63 +750,33 @@ impl ConfigProxyHandler {
#[derive(Debug, Error)] #[derive(Debug, Error)]
enum CphError { enum CphError {
#[error("Could not process a `parse_keymap` request")] #[error("Tried to set an unknown accel profile: {}", (.0).0)]
ParseKeymapError(#[from] ParseKeymapError), UnknownAccelProfile(AccelProfile),
#[error("Could not process a `set_seat` request")] #[error("Queried unknown capability: {}", (.0).0)]
SetSeatError(#[from] SetSeatError), UnknownCapability(Capability),
#[error("Could not process a `add_shortcut` request")] #[error("The height {0} is negative")]
AddShortcutError(#[from] AddShortcutError), NegativeTitleHeight(i32),
#[error("Could not process a `remove_shortcut` request")] #[error("The height {0} is larger than the maximum 1000")]
RemoveShortcutError(#[from] RemoveShortcutError), ExcessiveTitleHeight(i32),
#[error("Could not process a `set_keymap` request")] #[error("The width {0} is negative")]
SeatSetKeymapError(#[from] SeatSetKeymapError), NegativeBorderWidth(i32),
#[error("Could not process a `get_repeat_rate` request")] #[error("The width {0} is larger than the maximum 1000")]
SeatGetRepeatRateError(#[from] SeatGetRepeatRateError), ExcessiveBorderWidth(i32),
#[error("Could not process a `set_repeat_rate` request")] #[error("The ol' forker is not available")]
SeatSetRepeatRateError(#[from] SeatSetRepeatRateError), NoForker,
#[error("Could not process a `focus` request")] #[error("Repeat rate is negative")]
FocusError(#[from] FocusError), NegativeRepeatRate,
#[error("Could not process a `move` request")] #[error("Repeat delay is negative")]
MoveError(#[from] MoveError), NegativeRepeatDelay,
#[error("Could not process a `set_mono` request")] #[error("Parsing failed")]
SetMonoError(#[from] SetMonoError), ParseKeymapError(#[from] XkbCommonError),
#[error("Could not process a `get_mono` request")]
GetMonoError(#[from] GetMonoError),
#[error("Could not process a `set_split` request")]
SetSplitError(#[from] SetSplitError),
#[error("Could not process a `get_split` request")]
GetSplitError(#[from] GetSplitError),
#[error("Could not process a `run` request")]
RunError(#[from] RunError),
#[error("Could not process a `grab` request")]
GrabError(#[from] GrabError),
#[error("Could not process a `create_split` request")]
CreateSplitError(#[from] CreateSplitError),
#[error("Could not process a `focus_parent` request")]
FocusParentError(#[from] FocusParentError),
#[error("Could not process a `toggle_floating` request")]
ToggleFloatingError(#[from] ToggleFloatingError),
#[error("Could not process a `set_title_height` request")]
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("Could not process a `set_left_handed` request")]
SetLeftHandedError(#[from] SetLeftHandedError),
#[error("Could not process a `set_accel_profile` request")]
SetAccelProfileError(#[from] SetAccelProfileError),
#[error("Could not process a `set_accel_speed` request")]
SetAccelSpeedError(#[from] SetAccelSpeedError),
#[error("Could not process a `set_transform_matrix` request")]
SetTransformMatrixError(#[from] SetTransformMatrixError),
#[error("Could not process a `get_device_name` request")]
GetDeviceNameError(#[from] GetDeviceNameError),
#[error("Could not process a `show_workspace` request")]
ShowWorkspaceError(#[from] ShowWorkspaceError),
#[error("Device {0:?} does not exist")] #[error("Device {0:?} does not exist")]
DeviceDoesNotExist(InputDevice), DeviceDoesNotExist(InputDevice),
#[error("Device {0:?} does not exist")] #[error("Connector {0:?} does not exist")]
ConnectorDoesNotExist(Connector),
#[error("{0}x{1} is not a valid connector position")]
InvalidConnectorPosition(i32, i32),
#[error("Keymap {0:?} does not exist")]
KeymapDoesNotExist(Keymap), KeymapDoesNotExist(Keymap),
#[error("Seat {0:?} does not exist")] #[error("Seat {0:?} does not exist")]
SeatDoesNotExist(Seat), SeatDoesNotExist(Seat),
@ -704,201 +786,16 @@ enum CphError {
KeyboardDoesNotExist(InputDevice), KeyboardDoesNotExist(InputDevice),
#[error("Could not parse the message")] #[error("Could not parse the message")]
ParsingFailed(#[source] DecodeError), ParsingFailed(#[source] DecodeError),
#[error("Could not process a `{0}` request")]
FailedRequest(&'static str, #[source] Box<Self>),
} }
#[derive(Debug, Error)] trait WithRequestName {
enum ParseKeymapError { fn wrn(self, request: &'static str) -> Result<(), CphError>;
#[error("Parsing failed")]
ParsingFailed,
} }
#[derive(Debug, Error)] impl WithRequestName for Result<(), CphError> {
enum SetSeatError { fn wrn(self, request: &'static str) -> Result<(), CphError> {
#[error(transparent)] self.map_err(move |e| CphError::FailedRequest(request, Box::new(e)))
CphError(#[from] Box<CphError>), }
} }
efrom!(SetSeatError, CphError);
#[derive(Debug, Error)]
enum SetLeftHandedError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(SetLeftHandedError, CphError);
#[derive(Debug, Error)]
enum SetAccelProfileError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
#[error("Tried to set an unknown accel profile: {}", (.0).0)]
UnknownAccelProfile(AccelProfile),
}
efrom!(SetAccelProfileError, CphError);
#[derive(Debug, Error)]
enum SetAccelSpeedError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(SetAccelSpeedError, CphError);
#[derive(Debug, Error)]
enum SetTransformMatrixError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(SetTransformMatrixError, CphError);
#[derive(Debug, Error)]
enum GetDeviceNameError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(GetDeviceNameError, CphError);
#[derive(Debug, Error)]
enum ShowWorkspaceError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(ShowWorkspaceError, CphError);
#[derive(Debug, Error)]
enum HasCapabilityError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
#[error("Queried unknown capability: {}", (.0).0)]
UnknownCapability(Capability),
}
efrom!(HasCapabilityError, CphError);
#[derive(Debug, Error)]
enum AddShortcutError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(AddShortcutError, CphError);
#[derive(Debug, Error)]
enum RemoveShortcutError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(RemoveShortcutError, CphError);
#[derive(Debug, Error)]
enum SeatSetKeymapError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(SeatSetKeymapError, CphError);
#[derive(Debug, Error)]
enum SeatSetRepeatRateError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
#[error("Rate is negative")]
NegativeRate,
#[error("Delay is negative")]
NegativeDelay,
}
efrom!(SeatSetRepeatRateError, CphError);
#[derive(Debug, Error)]
enum SeatGetRepeatRateError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(SeatGetRepeatRateError, CphError);
#[derive(Debug, Error)]
enum FocusError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(FocusError, CphError);
#[derive(Debug, Error)]
enum MoveError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(MoveError, CphError);
#[derive(Debug, Error)]
enum SetMonoError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(SetMonoError, CphError);
#[derive(Debug, Error)]
enum GetMonoError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(GetMonoError, CphError);
#[derive(Debug, Error)]
enum SetSplitError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(SetSplitError, CphError);
#[derive(Debug, Error)]
enum GetSplitError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(GetSplitError, CphError);
#[derive(Debug, Error)]
enum RunError {
#[error("The ol' forker is not available")]
NoForker,
}
#[derive(Debug, Error)]
enum GrabError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(GrabError, CphError);
#[derive(Debug, Error)]
enum SetTitleHeightError {
#[error("The height {0} is negative")]
Negative(i32),
#[error("The height {0} is larger than the maximum 1000")]
Excessive(i32),
}
#[derive(Debug, Error)]
enum SetBorderWidthError {
#[error("The width {0} is negative")]
Negative(i32),
#[error("The width {0} is larger than the maximum 1000")]
Excessive(i32),
}
#[derive(Debug, Error)]
enum CreateSplitError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(CreateSplitError, CphError);
#[derive(Debug, Error)]
enum FocusParentError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(FocusParentError, CphError);
#[derive(Debug, Error)]
enum ToggleFloatingError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(ToggleFloatingError, CphError);

View file

@ -23,6 +23,7 @@ use std::rc::{Rc, Weak};
use thiserror::Error; use thiserror::Error;
use uapi::{c, Errno, OwnedFd, Pod, Ustring}; use uapi::{c, Errno, OwnedFd, Pod, Ustring};
use crate::backend;
use crate::drm::dma::DmaBuf; use crate::drm::dma::DmaBuf;
use crate::drm::INVALID_MODIFIER; use crate::drm::INVALID_MODIFIER;
use crate::utils::errorfmt::ErrorFmt; use crate::utils::errorfmt::ErrorFmt;
@ -33,7 +34,6 @@ pub use sys::{
drm_mode_modeinfo, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET, drm_mode_modeinfo, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET,
DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT, DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT,
}; };
use crate::backend;
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum DrmError { pub enum DrmError {
@ -737,6 +737,90 @@ pub enum ConnectorType {
EmbeddedWindow, EmbeddedWindow,
} }
impl ConnectorType {
pub fn from_drm(v: u32) -> Self {
match v {
sys::DRM_MODE_CONNECTOR_VGA => Self::VGA,
sys::DRM_MODE_CONNECTOR_DVII => Self::DVII,
sys::DRM_MODE_CONNECTOR_DVID => Self::DVID,
sys::DRM_MODE_CONNECTOR_DVIA => Self::DVIA,
sys::DRM_MODE_CONNECTOR_Composite => Self::Composite,
sys::DRM_MODE_CONNECTOR_SVIDEO => Self::SVIDEO,
sys::DRM_MODE_CONNECTOR_LVDS => Self::LVDS,
sys::DRM_MODE_CONNECTOR_Component => Self::Component,
sys::DRM_MODE_CONNECTOR_9PinDIN => Self::_9PinDIN,
sys::DRM_MODE_CONNECTOR_DisplayPort => Self::DisplayPort,
sys::DRM_MODE_CONNECTOR_HDMIA => Self::HDMIA,
sys::DRM_MODE_CONNECTOR_HDMIB => Self::HDMIB,
sys::DRM_MODE_CONNECTOR_TV => Self::TV,
sys::DRM_MODE_CONNECTOR_eDP => Self::eDP,
sys::DRM_MODE_CONNECTOR_VIRTUAL => Self::VIRTUAL,
sys::DRM_MODE_CONNECTOR_DSI => Self::DSI,
sys::DRM_MODE_CONNECTOR_DPI => Self::DPI,
sys::DRM_MODE_CONNECTOR_WRITEBACK => Self::WRITEBACK,
sys::DRM_MODE_CONNECTOR_SPI => Self::SPI,
sys::DRM_MODE_CONNECTOR_USB => Self::USB,
_ => Self::Unknown(v),
}
}
#[allow(dead_code)]
pub fn to_drm(self) -> u32 {
match self {
Self::Unknown(n) => n,
Self::VGA => sys::DRM_MODE_CONNECTOR_VGA,
Self::DVII => sys::DRM_MODE_CONNECTOR_DVII,
Self::DVID => sys::DRM_MODE_CONNECTOR_DVID,
Self::DVIA => sys::DRM_MODE_CONNECTOR_DVIA,
Self::Composite => sys::DRM_MODE_CONNECTOR_Composite,
Self::SVIDEO => sys::DRM_MODE_CONNECTOR_SVIDEO,
Self::LVDS => sys::DRM_MODE_CONNECTOR_LVDS,
Self::Component => sys::DRM_MODE_CONNECTOR_Component,
Self::_9PinDIN => sys::DRM_MODE_CONNECTOR_9PinDIN,
Self::DisplayPort => sys::DRM_MODE_CONNECTOR_DisplayPort,
Self::HDMIA => sys::DRM_MODE_CONNECTOR_HDMIA,
Self::HDMIB => sys::DRM_MODE_CONNECTOR_HDMIB,
Self::TV => sys::DRM_MODE_CONNECTOR_TV,
Self::eDP => sys::DRM_MODE_CONNECTOR_eDP,
Self::VIRTUAL => sys::DRM_MODE_CONNECTOR_VIRTUAL,
Self::DSI => sys::DRM_MODE_CONNECTOR_DSI,
Self::DPI => sys::DRM_MODE_CONNECTOR_DPI,
Self::WRITEBACK => sys::DRM_MODE_CONNECTOR_WRITEBACK,
Self::SPI => sys::DRM_MODE_CONNECTOR_SPI,
Self::USB => sys::DRM_MODE_CONNECTOR_USB,
Self::EmbeddedWindow => sys::DRM_MODE_CONNECTOR_Unknown,
}
}
pub fn to_config(self) -> jay_config::drm::connector_type::ConnectorType {
use jay_config::drm::connector_type::*;
match self {
Self::Unknown(_) => CON_UNKNOWN,
Self::VGA => CON_VGA,
Self::DVII => CON_DVII,
Self::DVID => CON_DVID,
Self::DVIA => CON_DVIA,
Self::Composite => CON_COMPOSITE,
Self::SVIDEO => CON_SVIDEO,
Self::LVDS => CON_LVDS,
Self::Component => CON_COMPONENT,
Self::_9PinDIN => CON_9PIN_DIN,
Self::DisplayPort => CON_DISPLAY_PORT,
Self::HDMIA => CON_HDMIA,
Self::HDMIB => CON_HDMIB,
Self::TV => CON_TV,
Self::eDP => CON_EDP,
Self::VIRTUAL => CON_VIRTUAL,
Self::DSI => CON_DSI,
Self::DPI => CON_DPI,
Self::WRITEBACK => CON_WRITEBACK,
Self::SPI => CON_SPI,
Self::USB => CON_USB,
Self::EmbeddedWindow => CON_EMBEDDED_WINDOW,
}
}
}
impl Display for ConnectorType { impl Display for ConnectorType {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let s = match self { let s = match self {
@ -767,63 +851,6 @@ impl Display for ConnectorType {
} }
} }
impl From<u32> for ConnectorType {
fn from(v: u32) -> Self {
match v {
sys::DRM_MODE_CONNECTOR_VGA => Self::VGA,
sys::DRM_MODE_CONNECTOR_DVII => Self::DVII,
sys::DRM_MODE_CONNECTOR_DVID => Self::DVID,
sys::DRM_MODE_CONNECTOR_DVIA => Self::DVIA,
sys::DRM_MODE_CONNECTOR_Composite => Self::Composite,
sys::DRM_MODE_CONNECTOR_SVIDEO => Self::SVIDEO,
sys::DRM_MODE_CONNECTOR_LVDS => Self::LVDS,
sys::DRM_MODE_CONNECTOR_Component => Self::Component,
sys::DRM_MODE_CONNECTOR_9PinDIN => Self::_9PinDIN,
sys::DRM_MODE_CONNECTOR_DisplayPort => Self::DisplayPort,
sys::DRM_MODE_CONNECTOR_HDMIA => Self::HDMIA,
sys::DRM_MODE_CONNECTOR_HDMIB => Self::HDMIB,
sys::DRM_MODE_CONNECTOR_TV => Self::TV,
sys::DRM_MODE_CONNECTOR_eDP => Self::eDP,
sys::DRM_MODE_CONNECTOR_VIRTUAL => Self::VIRTUAL,
sys::DRM_MODE_CONNECTOR_DSI => Self::DSI,
sys::DRM_MODE_CONNECTOR_DPI => Self::DPI,
sys::DRM_MODE_CONNECTOR_WRITEBACK => Self::WRITEBACK,
sys::DRM_MODE_CONNECTOR_SPI => Self::SPI,
sys::DRM_MODE_CONNECTOR_USB => Self::USB,
_ => Self::Unknown(v),
}
}
}
impl Into<u32> for ConnectorType {
fn into(self) -> u32 {
match self {
Self::Unknown(n) => n,
Self::VGA => sys::DRM_MODE_CONNECTOR_VGA,
Self::DVII => sys::DRM_MODE_CONNECTOR_DVII,
Self::DVID => sys::DRM_MODE_CONNECTOR_DVID,
Self::DVIA => sys::DRM_MODE_CONNECTOR_DVIA,
Self::Composite => sys::DRM_MODE_CONNECTOR_Composite,
Self::SVIDEO => sys::DRM_MODE_CONNECTOR_SVIDEO,
Self::LVDS => sys::DRM_MODE_CONNECTOR_LVDS,
Self::Component => sys::DRM_MODE_CONNECTOR_Component,
Self::_9PinDIN => sys::DRM_MODE_CONNECTOR_9PinDIN,
Self::DisplayPort => sys::DRM_MODE_CONNECTOR_DisplayPort,
Self::HDMIA => sys::DRM_MODE_CONNECTOR_HDMIA,
Self::HDMIB => sys::DRM_MODE_CONNECTOR_HDMIB,
Self::TV => sys::DRM_MODE_CONNECTOR_TV,
Self::eDP => sys::DRM_MODE_CONNECTOR_eDP,
Self::VIRTUAL => sys::DRM_MODE_CONNECTOR_VIRTUAL,
Self::DSI => sys::DRM_MODE_CONNECTOR_DSI,
Self::DPI => sys::DRM_MODE_CONNECTOR_DPI,
Self::WRITEBACK => sys::DRM_MODE_CONNECTOR_WRITEBACK,
Self::SPI => sys::DRM_MODE_CONNECTOR_SPI,
Self::USB => sys::DRM_MODE_CONNECTOR_USB,
Self::EmbeddedWindow => sys::DRM_MODE_CONNECTOR_Unknown,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)] #[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum ConnectorStatus { pub enum ConnectorStatus {
Connected, Connected,
@ -832,8 +859,8 @@ pub enum ConnectorStatus {
Other(u32), Other(u32),
} }
impl From<u32> for ConnectorStatus { impl ConnectorStatus {
fn from(v: u32) -> Self { pub fn from_drm(v: u32) -> Self {
match v { match v {
sys::CONNECTOR_STATUS_CONNECTED => Self::Connected, sys::CONNECTOR_STATUS_CONNECTED => Self::Connected,
sys::CONNECTOR_STATUS_DISCONNECTED => Self::Disconnected, sys::CONNECTOR_STATUS_DISCONNECTED => Self::Disconnected,

View file

@ -1,3 +1,4 @@
use crate::utils::clonecell::UnsafeCellCloneSafe;
use crate::utils::copyhashmap::CopyHashMap; use crate::utils::copyhashmap::CopyHashMap;
use crate::utils::numcell::NumCell; use crate::utils::numcell::NumCell;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
@ -43,6 +44,8 @@ struct Entry {
dispatcher: Rc<dyn EventLoopDispatcher>, dispatcher: Rc<dyn EventLoopDispatcher>,
} }
unsafe impl UnsafeCellCloneSafe for Entry {}
pub struct EventLoop { pub struct EventLoop {
destroyed: Cell<bool>, destroyed: Cell<bool>,
epoll: OwnedFd, epoll: OwnedFd,

View file

@ -17,10 +17,8 @@ use crate::ifs::zxdg_decoration_manager_v1::ZxdgDecorationManagerV1Global;
use crate::ifs::zxdg_output_manager_v1::ZxdgOutputManagerV1Global; use crate::ifs::zxdg_output_manager_v1::ZxdgOutputManagerV1Global;
use crate::object::{Interface, ObjectId}; use crate::object::{Interface, ObjectId};
use crate::state::State; use crate::state::State;
use crate::utils::copyhashmap::CopyHashMap; use crate::utils::copyhashmap::{CopyHashMap, Locked};
use crate::utils::numcell::NumCell; use crate::utils::numcell::NumCell;
use ahash::AHashMap;
use std::cell::RefMut;
use std::error::Error; use std::error::Error;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::rc::Rc; use std::rc::Rc;
@ -153,7 +151,7 @@ impl Globals {
Ok(()) Ok(())
} }
pub fn lock_seats(&self) -> RefMut<AHashMap<GlobalName, Rc<WlSeatGlobal>>> { pub fn lock_seats(&self) -> Locked<GlobalName, Rc<WlSeatGlobal>> {
self.seats.lock() self.seats.lock()
} }

View file

@ -192,7 +192,6 @@ impl WlOutput {
fn send_mode(&self) { fn send_mode(&self) {
let mode = self.global.mode.get(); let mode = self.global.mode.get();
let pos = self.global.pos.get();
let event = Mode { let event = Mode {
self_id: self.id, self_id: self.id,
flags: MODE_CURRENT, flags: MODE_CURRENT,

View file

@ -1,5 +1,8 @@
use crate::async_engine::{AsyncEngine, SpawnedFuture}; use crate::async_engine::{AsyncEngine, SpawnedFuture};
use crate::backend::{Backend, BackendEvent, Connector, ConnectorId, ConnectorIds, InputDevice, InputDeviceId, InputDeviceIds, MonitorInfo}; use crate::backend::{
Backend, BackendEvent, Connector, ConnectorId, ConnectorIds, InputDevice, InputDeviceId,
InputDeviceIds, MonitorInfo,
};
use crate::client::{Client, Clients}; use crate::client::{Client, Clients};
use crate::config::ConfigProxy; use crate::config::ConfigProxy;
use crate::cursor::ServerCursors; use crate::cursor::ServerCursors;
@ -83,6 +86,7 @@ pub struct ConnectorData {
pub monitor_info: CloneCell<Option<Rc<MonitorInfo>>>, pub monitor_info: CloneCell<Option<Rc<MonitorInfo>>>,
pub handler: Cell<Option<SpawnedFuture<()>>>, pub handler: Cell<Option<SpawnedFuture<()>>>,
pub node: CloneCell<Option<Rc<OutputNode>>>, pub node: CloneCell<Option<Rc<OutputNode>>>,
pub connected: Cell<bool>,
} }
impl State { impl State {

View file

@ -1,4 +1,4 @@
use crate::backend::{BackendEvent}; use crate::backend::BackendEvent;
use crate::state::State; use crate::state::State;
use crate::tasks::{connector, input_device}; use crate::tasks::{connector, input_device};
use std::rc::Rc; use std::rc::Rc;

View file

@ -5,7 +5,7 @@ use crate::state::{ConnectorData, State};
use crate::tree::{OutputNode, OutputRenderData}; use crate::tree::{OutputNode, OutputRenderData};
use crate::utils::asyncevent::AsyncEvent; use crate::utils::asyncevent::AsyncEvent;
use crate::utils::clonecell::CloneCell; use crate::utils::clonecell::CloneCell;
use std::cell::RefCell; use std::cell::{Cell, RefCell};
use std::rc::Rc; use std::rc::Rc;
pub fn handle(state: &Rc<State>, connector: &Rc<dyn Connector>) { pub fn handle(state: &Rc<State>, connector: &Rc<dyn Connector>) {
@ -15,6 +15,7 @@ pub fn handle(state: &Rc<State>, connector: &Rc<dyn Connector>) {
monitor_info: Default::default(), monitor_info: Default::default(),
handler: Default::default(), handler: Default::default(),
node: Default::default(), node: Default::default(),
connected: Cell::new(false),
}); });
let oh = ConnectorHandler { let oh = ConnectorHandler {
id, id,
@ -60,7 +61,12 @@ impl ConnectorHandler {
} }
async fn handle_connected(&self, ae: &Rc<AsyncEvent>, info: MonitorInfo) { async fn handle_connected(&self, ae: &Rc<AsyncEvent>, info: MonitorInfo) {
log::info!("Connector {} connected: {:#?}", self.data.connector.kernel_id(), info); log::info!(
"Connector {} connected: {:#?}",
self.data.connector.kernel_id(),
info
);
self.data.connected.set(true);
self.data.monitor_info.set(Some(Rc::new(info.clone()))); self.data.monitor_info.set(Some(Rc::new(info.clone())));
let name = self.state.globals.name(); let name = self.state.globals.name();
let x1 = self let x1 = self
@ -124,5 +130,6 @@ impl ConnectorHandler {
global.node.set(None); global.node.set(None);
let _ = self.state.remove_global(&*global); let _ = self.state.remove_global(&*global);
self.state.root.outputs.remove(&self.id); self.state.root.outputs.remove(&self.id);
self.data.connected.set(false);
} }
} }

View file

@ -126,13 +126,27 @@ impl OutputNode {
.unwrap() .unwrap()
} }
pub fn set_position(&self, x: i32, y: i32) {
let pos = self.global.pos.get();
if (pos.x1(), pos.y1()) == (x, y) {
return;
}
let rect = pos.at_point(x, y);
self.change_extents_(&rect);
}
pub fn update_mode(&self, mode: Mode) { pub fn update_mode(&self, mode: Mode) {
if self.global.mode.get() == mode { if self.global.mode.get() == mode {
return; return;
} }
self.global.mode.set(mode);
let pos = self.global.pos.get(); let pos = self.global.pos.get();
let rect = Rect::new_sized(pos.x1(), pos.y1(), mode.width, mode.height).unwrap(); let rect = Rect::new_sized(pos.x1(), pos.y1(), mode.width, mode.height).unwrap();
self.global.pos.set(rect); self.change_extents_(&rect);
}
fn change_extents_(&self, rect: &Rect) {
self.global.pos.set(*rect);
if let Some(c) = self.workspace.get() { if let Some(c) = self.workspace.get() {
c.change_extents(&self.workspace_rect()); c.change_extents(&self.workspace_rect());
} }

View file

@ -1,5 +1,6 @@
use crate::utils::linkedlist::NodeRef; use crate::utils::linkedlist::NodeRef;
use crate::utils::ptr_ext::{MutPtrExt, PtrExt}; use crate::utils::ptr_ext::{MutPtrExt, PtrExt};
use jay_config::keyboard::mods::Modifiers;
use std::cell::UnsafeCell; use std::cell::UnsafeCell;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::mem; use std::mem;
@ -65,3 +66,6 @@ unsafe impl<T: ?Sized> UnsafeCellCloneSafe for Weak<T> {}
unsafe impl<T> UnsafeCellCloneSafe for NodeRef<T> {} unsafe impl<T> UnsafeCellCloneSafe for NodeRef<T> {}
unsafe impl UnsafeCellCloneSafe for () {} unsafe impl UnsafeCellCloneSafe for () {}
unsafe impl UnsafeCellCloneSafe for u64 {}
unsafe impl UnsafeCellCloneSafe for Modifiers {}

View file

@ -1,12 +1,15 @@
use crate::utils::clonecell::UnsafeCellCloneSafe;
use crate::utils::ptr_ext::{MutPtrExt, PtrExt};
use ahash::AHashMap; use ahash::AHashMap;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::cell::{RefCell, RefMut}; use std::cell::UnsafeCell;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::hash::Hash; use std::hash::Hash;
use std::mem; use std::mem;
use std::ops::{Deref, DerefMut};
pub struct CopyHashMap<K, V> { pub struct CopyHashMap<K, V> {
map: RefCell<AHashMap<K, V>>, map: UnsafeCell<AHashMap<K, V>>,
} }
impl<K: Debug, V: Debug> Debug for CopyHashMap<K, V> { impl<K: Debug, V: Debug> Debug for CopyHashMap<K, V> {
@ -29,20 +32,22 @@ impl<K: Eq + Hash, V> CopyHashMap<K, V> {
} }
pub fn set(&self, k: K, v: V) { pub fn set(&self, k: K, v: V) {
self.map.borrow_mut().insert(k, v); unsafe {
self.map.get().deref_mut().insert(k, v);
}
} }
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<V> pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<V>
where where
V: Clone, V: UnsafeCellCloneSafe,
Q: Hash + Eq, Q: Hash + Eq,
K: Borrow<Q>, K: Borrow<Q>,
{ {
self.map.borrow_mut().get(k).cloned() unsafe { self.map.get().deref().get(k).cloned() }
} }
pub fn remove(&self, k: &K) -> Option<V> { pub fn remove(&self, k: &K) -> Option<V> {
self.map.borrow_mut().remove(k) unsafe { self.map.get().deref_mut().remove(k) }
} }
pub fn contains<Q: ?Sized>(&self, k: &Q) -> bool pub fn contains<Q: ?Sized>(&self, k: &Q) -> bool
@ -50,18 +55,48 @@ impl<K: Eq + Hash, V> CopyHashMap<K, V> {
Q: Hash + Eq, Q: Hash + Eq,
K: Borrow<Q>, K: Borrow<Q>,
{ {
self.map.borrow_mut().contains_key(k) unsafe { self.map.get().deref().contains_key(k) }
} }
pub fn lock(&self) -> RefMut<AHashMap<K, V>> { pub fn lock(&self) -> Locked<K, V> {
self.map.borrow_mut() Locked {
source: self,
map: self.clear(),
}
} }
pub fn clear(&self) { pub fn clear(&self) -> AHashMap<K, V> {
mem::take(&mut *self.map.borrow_mut()); unsafe { mem::take(self.map.get().deref_mut()) }
} }
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.map.borrow_mut().is_empty() unsafe { self.map.get().deref().is_empty() }
}
}
pub struct Locked<'a, K, V> {
source: &'a CopyHashMap<K, V>,
map: AHashMap<K, V>,
}
impl<'a, K, V> Drop for Locked<'a, K, V> {
fn drop(&mut self) {
unsafe {
mem::swap(&mut self.map, self.source.map.get().deref_mut());
}
}
}
impl<'a, K, V> Deref for Locked<'a, K, V> {
type Target = AHashMap<K, V>;
fn deref(&self) -> &Self::Target {
&self.map
}
}
impl<'a, K, V> DerefMut for Locked<'a, K, V> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.map
} }
} }

View file

@ -1,17 +1,26 @@
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Display, Formatter};
pub fn debug_fn<F>(f: F) -> impl Debug pub fn debug_fn<F>(f: F) -> Printable<F>
where where
F: Fn(&mut Formatter<'_>) -> std::fmt::Result, F: Fn(&mut Formatter<'_>) -> std::fmt::Result,
{ {
DebugFn { f } Printable { f }
} }
struct DebugFn<F> { pub struct Printable<F> {
f: F, f: F,
} }
impl<F> Debug for DebugFn<F> impl<F> Debug for Printable<F>
where
F: Fn(&mut Formatter<'_>) -> std::fmt::Result,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
(self.f)(f)
}
}
impl<F> Display for Printable<F>
where where
F: Fn(&mut Formatter<'_>) -> std::fmt::Result, F: Fn(&mut Formatter<'_>) -> std::fmt::Result,
{ {