From 7748132fcaaa710cbfe0274fab07eb1708555169 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Mon, 10 Oct 2022 20:03:18 +0200 Subject: [PATCH] rewriting X wrapper --- src/xwrap/display.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++ src/xwrap/error.rs | 22 ++++++++++++++++++++++ src/xwrap/mod.rs | 2 ++ 3 files changed, 69 insertions(+) create mode 100644 src/xwrap/display.rs create mode 100644 src/xwrap/error.rs create mode 100644 src/xwrap/mod.rs diff --git a/src/xwrap/display.rs b/src/xwrap/display.rs new file mode 100644 index 0000000..e11ec3e --- /dev/null +++ b/src/xwrap/display.rs @@ -0,0 +1,45 @@ +use std::{env, ffi, ptr}; + +use x11::xlib::{self, BadGC}; + +use super::error; + +pub struct Display { + ptr: *mut xlib::Display, + name: String, +} + +impl Display { + /// Call XOpenDisplay to open a display. + /// If `display_name` is `None`, the value of the `DISPLAY` environment variable will be used. + pub fn open(display_name: Option) -> anyhow::Result { + let name = ffi::CString::new(if let Some(name) = display_name { + name + } else { + env::var("DISPLAY")? + })?; + + let name_ptr = name.as_bytes().as_ptr(); + + // try to open display and get either display pointer or null + let display_ptr = unsafe { xlib::XOpenDisplay(name_ptr as *const i8) }; + + // if display is null, return an error, otherwise return instance successfully + if display_ptr == ptr::null_mut::() { + Err(error::XError::OpenDisplayError(name.into_string()?).into()) + } else { + Ok(Self { + ptr: display_ptr, + name: name.into_string()?, + }) + } + } +} + +impl Drop for Display { + fn drop(&mut self) { + if unsafe { xlib::XCloseDisplay(self.ptr) } == BadGC.into() { + eprintln!("BadGC Error when closing display '{}'.", self.name); + }; + } +} diff --git a/src/xwrap/error.rs b/src/xwrap/error.rs new file mode 100644 index 0000000..7bfe885 --- /dev/null +++ b/src/xwrap/error.rs @@ -0,0 +1,22 @@ +use std::fmt; + +/// Various errors to be used in this wrapper +#[derive(Debug)] +pub enum XError { + OpenDisplayError(String), +} + +impl std::fmt::Display for XError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match self { + XError::OpenDisplayError(display_name) => + format!("error when opening display '{}'", display_name), + } + ) + } +} + +impl std::error::Error for XError {} diff --git a/src/xwrap/mod.rs b/src/xwrap/mod.rs new file mode 100644 index 0000000..2848c7e --- /dev/null +++ b/src/xwrap/mod.rs @@ -0,0 +1,2 @@ +pub mod display; +pub mod error;