progress!
This commit is contained in:
parent
c4ebaa35be
commit
1b688c7883
3 changed files with 115 additions and 6 deletions
|
@ -1,18 +1,44 @@
|
||||||
use std::{env, ffi, ptr};
|
use std::{env, ffi, ptr, ops};
|
||||||
|
|
||||||
use x11::xlib::{self, BadGC};
|
use x11::xlib::{self, BadGC};
|
||||||
|
|
||||||
use super::error;
|
use anyhow::Result;
|
||||||
|
|
||||||
|
use super::{error, screen, window};
|
||||||
|
|
||||||
pub struct Display {
|
pub struct Display {
|
||||||
ptr: *mut xlib::Display,
|
pub(super) ptr: *mut xlib::Display,
|
||||||
name: String,
|
name: String,
|
||||||
|
keyboard_grab: Option<Grabbables>,
|
||||||
|
pointer_grab: Option<Grabbables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// for keyboard/pointer grabs so Display is less messy
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Grabbables {
|
||||||
|
keyboard_mode: GrabMode,
|
||||||
|
pointer_mode: GrabMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum GrabMode {
|
||||||
|
Sync,
|
||||||
|
Async,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<GrabMode> for i32 {
|
||||||
|
fn from(v: GrabMode) -> Self {
|
||||||
|
match v {
|
||||||
|
GrabMode::Sync => xlib::GrabModeSync,
|
||||||
|
GrabMode::Async => xlib::GrabModeAsync,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display {
|
impl Display {
|
||||||
/// Call XOpenDisplay to open a connection to the X Server.
|
/// Call XOpenDisplay to open a connection to the X Server.
|
||||||
/// If `display_name` is `None`, the value of the `DISPLAY` environment variable will be used.
|
/// If `display_name` is `None`, the value of the `DISPLAY` environment variable will be used.
|
||||||
pub fn open(display_name: Option<String>) -> anyhow::Result<Self> {
|
pub fn open(display_name: Option<String>) -> Result<Self> {
|
||||||
let name = ffi::CString::new(if let Some(name) = display_name {
|
let name = ffi::CString::new(if let Some(name) = display_name {
|
||||||
name
|
name
|
||||||
} else {
|
} else {
|
||||||
|
@ -31,6 +57,8 @@ impl Display {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ptr: display_ptr,
|
ptr: display_ptr,
|
||||||
name: name.into_string()?,
|
name: name.into_string()?,
|
||||||
|
pointer_grab: None,
|
||||||
|
keyboard_grab: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +66,7 @@ impl Display {
|
||||||
/// Calls XFlush to flush the output buffer.
|
/// Calls XFlush to flush the output buffer.
|
||||||
pub fn flush(&self) {
|
pub fn flush(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
xlib::XFlush(self.ptr)
|
xlib::XFlush(self.ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +80,80 @@ impl Display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calls xlib::XDefaultScreen to get the default screen number referenced by Display::open.
|
||||||
|
/// This should be used to retrieve the screen number in applications that'll only use a single
|
||||||
|
/// screen.
|
||||||
|
pub fn default_screen_nr(&self) -> i32 {
|
||||||
|
unsafe {
|
||||||
|
xlib::XDefaultScreen(self.ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the default screen
|
||||||
|
pub fn default_screen(&self) -> screen::Screen {
|
||||||
|
screen::Screen {
|
||||||
|
ptr: unsafe {
|
||||||
|
xlib::XDefaultScreenOfDisplay(self.ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the root window of the default screen
|
||||||
|
pub fn default_root_window(&self) -> window::Window {
|
||||||
|
window::Window {
|
||||||
|
wid: unsafe {
|
||||||
|
xlib::XDefaultRootWindow(self.ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the range of legal KeyCodes for a display.
|
||||||
|
pub fn keycodes(&self) -> Result<ops::Range<i32>> {
|
||||||
|
let (mut min, mut max) = (0, 0);
|
||||||
|
|
||||||
|
if unsafe { xlib::XDisplayKeycodes(self.ptr, &mut min, &mut max) } == 0 {
|
||||||
|
Err(error::XError::DisplayKeycodesError.into())
|
||||||
|
} else {
|
||||||
|
Ok(min..max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn grab_keyboard(
|
||||||
|
&mut self,
|
||||||
|
grab_window: window::Window,
|
||||||
|
owner_events: bool,
|
||||||
|
pointer_mode: GrabMode,
|
||||||
|
keyboard_mode: GrabMode,
|
||||||
|
time:xlib::Time,
|
||||||
|
) -> Result<()> {
|
||||||
|
match unsafe {
|
||||||
|
xlib::XGrabKeyboard(
|
||||||
|
self.ptr,
|
||||||
|
grab_window.wid,
|
||||||
|
owner_events.into(),
|
||||||
|
pointer_mode.into(),
|
||||||
|
keyboard_mode.into(),
|
||||||
|
time
|
||||||
|
)
|
||||||
|
} {
|
||||||
|
xlib::GrabSuccess => {
|
||||||
|
self.keyboard_grab = Some(Grabbables {
|
||||||
|
keyboard_mode,
|
||||||
|
pointer_mode
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
xlib::AlreadyGrabbed => todo!(),
|
||||||
|
xlib::GrabInvalidTime => todo!(),
|
||||||
|
xlib::GrabNotViewable => todo!(),
|
||||||
|
xlib::GrabFrozen => todo!(),
|
||||||
|
_ => todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Drop for Display {
|
impl Drop for Display {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if unsafe { xlib::XCloseDisplay(self.ptr) } == BadGC.into() {
|
if unsafe { xlib::XCloseDisplay(self.ptr) } == BadGC.into() {
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
use std::fmt;
|
use std::{fmt, ops};
|
||||||
|
|
||||||
|
use x11::xlib;
|
||||||
|
|
||||||
/// Various errors to be used in this wrapper
|
/// Various errors to be used in this wrapper
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum XError {
|
pub enum XError {
|
||||||
OpenDisplayError(String),
|
OpenDisplayError(String),
|
||||||
|
DisplayKeycodesError,
|
||||||
|
InvalidKeycodeError(xlib::KeyCode, ops::Range<i32>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for XError {
|
impl std::fmt::Display for XError {
|
||||||
|
@ -14,6 +18,8 @@ impl std::fmt::Display for XError {
|
||||||
match self {
|
match self {
|
||||||
XError::OpenDisplayError(display_name) =>
|
XError::OpenDisplayError(display_name) =>
|
||||||
format!("error when opening display '{}'", display_name),
|
format!("error when opening display '{}'", display_name),
|
||||||
|
XError::DisplayKeycodesError => String::from("error when running XDisplayKeycodes"),
|
||||||
|
XError::InvalidKeycodeError(code, range) => format!("keycode {} outside of range {:?}", code, range),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
pub mod display;
|
pub mod display;
|
||||||
|
pub mod screen;
|
||||||
|
pub mod window;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
pub mod key;
|
||||||
|
|
Loading…
Add table
Reference in a new issue