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

@ -2,13 +2,14 @@
use crate::_private::ipc::{ClientMessage, InitMessage, Response, ServerMessage};
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::capability::Capability;
use crate::input::InputDevice;
use crate::input::{InputDevice, Seat};
use crate::keyboard::keymap::Keymap;
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::collections::hash_map::Entry;
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 {
fn send(&self, msg: &ClientMessage) {
let mut buf = self.bufs.borrow_mut().pop().unwrap_or_default();
@ -138,6 +151,10 @@ impl Client {
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) {
let env = command
.env
@ -185,36 +202,27 @@ impl Client {
}
pub fn seats(&self) -> Vec<Seat> {
let response = self.with_response(|| self.send(&ClientMessage::GetSeats));
match response {
Response::GetSeats { seats } => seats,
_ => {
log::error!("Server did not send a response to a get_seats request");
vec![]
}
}
let res = self.with_response(|| self.send(&ClientMessage::GetSeats));
get_response!(res, vec![], GetSeats, seats);
seats
}
pub fn mono(&self, seat: Seat) -> bool {
let res = self.with_response(|| self.send(&ClientMessage::GetMono { seat }));
match res {
Response::GetMono { mono } => mono,
_ => {
log::error!("Server did not send a response to a get_mono request");
false
}
}
get_response!(res, false, GetMono, mono);
mono
}
pub fn get_workspace(&self, name: &str) -> Workspace {
let res = self.with_response(|| self.send(&ClientMessage::GetWorkspace { name }));
match res {
Response::GetWorkspace { workspace } => workspace,
_ => {
log::error!("Server did not send a response to a get_workspace request");
Workspace(0)
}
}
get_response!(res, Workspace(0), GetWorkspace, workspace);
workspace
}
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) {
@ -223,13 +231,8 @@ impl Client {
pub fn split(&self, seat: Seat) -> Axis {
let res = self.with_response(|| self.send(&ClientMessage::GetSplit { seat }));
match res {
Response::GetSplit { axis } => axis,
_ => {
log::error!("Server did not send a response to a get_split request");
Axis::Horizontal
}
}
get_response!(res, Axis::Horizontal, GetSplit, axis);
axis
}
pub fn toggle_floating(&self, seat: Seat) {
@ -253,25 +256,15 @@ impl Client {
}
pub fn get_title_height(&self) -> i32 {
let resp = self.with_response(|| self.send(&ClientMessage::GetTitleHeight));
match resp {
Response::GetTitleHeight { height } => height,
_ => {
log::warn!("Server did not reply to a get_title_height request");
0
}
}
let res = self.with_response(|| self.send(&ClientMessage::GetTitleHeight));
get_response!(res, 0, GetTitleHeight, height);
height
}
pub fn get_border_width(&self) -> i32 {
let resp = self.with_response(|| self.send(&ClientMessage::GetBorderWidth));
match resp {
Response::GetBorderWidth { width } => width,
_ => {
log::warn!("Server did not reply to a get_border_width request");
0
}
}
let res = self.with_response(|| self.send(&ClientMessage::GetBorderWidth));
get_response!(res, 0, GetBorderWidth, width);
width
}
pub fn set_title_height(&self, height: i32) {
@ -299,25 +292,15 @@ impl Client {
}
pub fn create_seat(&self, name: &str) -> Seat {
let response = self.with_response(|| self.send(&ClientMessage::CreateSeat { name }));
match response {
Response::CreateSeat { seat } => seat,
_ => {
log::error!("Server did not send a response to a create_seat request");
Seat(0)
}
}
let res = self.with_response(|| self.send(&ClientMessage::CreateSeat { name }));
get_response!(res, Seat(0), CreateSeat, seat);
seat
}
pub fn get_input_devices(&self, seat: Option<Seat>) -> Vec<InputDevice> {
let res = self.with_response(|| self.send(&ClientMessage::GetInputDevices { seat }));
match res {
Response::GetInputDevices { devices } => devices,
_ => {
log::error!("Server did not send a response to a get_input_devices request");
vec![]
}
}
get_response!(res, vec!(), GetInputDevices, devices);
devices
}
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));
}
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) {
self.send(&ClientMessage::SetSeat { device, seat })
}
@ -361,24 +385,14 @@ impl Client {
pub fn device_name(&self, device: InputDevice) -> String {
let res = self.with_response(|| self.send(&ClientMessage::GetDeviceName { device }));
match res {
Response::GetDeviceName { name } => name,
_ => {
log::error!("Server did not send a response to a get_device_name request");
String::new()
}
}
get_response!(res, String::new(), GetDeviceName, name);
name
}
pub fn has_capability(&self, device: InputDevice, cap: Capability) -> bool {
let res = self.with_response(|| self.send(&ClientMessage::HasCapability { device, cap }));
match res {
Response::HasCapability { has } => has,
_ => {
log::error!("Server did not send a response to a has_capability request");
false
}
}
get_response!(res, false, HasCapability, has);
has
}
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) {
let res = self.with_response(|| self.send(&ClientMessage::SeatGetRepeatRate { seat }));
match res {
Response::GetRepeatRate { rate, delay } => (rate, delay),
_ => {
log::error!("Server did not send a response to a get_repeat_rate request");
(25, 250)
}
}
get_response!(res, (25, 250), GetRepeatRate, rate, delay);
(rate, delay)
}
pub fn parse_keymap(&self, keymap: &str) -> Keymap {
let res = self.with_response(|| self.send(&ClientMessage::ParseKeymap { keymap }));
match res {
Response::ParseKeymap { keymap } => keymap,
_ => {
log::error!("Server did not send a response to a parse_keymap request");
Keymap(0)
}
}
get_response!(res, Keymap(0), ParseKeymap, keymap);
keymap
}
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::input::acceleration::AccelProfile;
use crate::input::capability::Capability;
use crate::input::InputDevice;
use crate::input::{InputDevice, Seat};
use crate::keyboard::keymap::Keymap;
use crate::keyboard::mods::Modifiers;
use crate::keyboard::syms::KeySym;
use crate::theme::Color;
use crate::{Axis, Direction, LogLevel, Seat, Workspace};
use crate::{Axis, Direction, LogLevel, Workspace};
use bincode::{BorrowDecode, Decode, Encode};
#[derive(Encode, BorrowDecode, Debug)]
@ -178,6 +179,24 @@ pub enum ClientMessage<'a> {
GetWorkspace {
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 {
seat: Seat,
workspace: Workspace,
@ -187,18 +206,57 @@ pub enum ClientMessage<'a> {
#[derive(Encode, Decode, Debug)]
pub enum Response {
None,
GetSeats { seats: Vec<Seat> },
GetSplit { axis: Axis },
GetMono { mono: bool },
GetRepeatRate { rate: i32, 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 },
GetSeats {
seats: Vec<Seat>,
},
GetSplit {
axis: Axis,
},
GetMono {
mono: bool,
},
GetRepeatRate {
rate: i32,
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)]

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 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)]
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::capability::Capability;
use crate::Seat;
use crate::{Axis, Direction, Keymap, ModifiedKeySym, Workspace};
use bincode::{Decode, Encode};
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
@ -38,3 +38,126 @@ impl InputDevice {
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::ModifiedKeySym;
use bincode::{Decode, Encode};
@ -31,17 +30,6 @@ pub enum Direction {
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)]
pub enum Axis {
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() {
get!().quit()
}