add some extensions stuff

This commit is contained in:
Michael Zhang 2020-06-28 14:50:29 -05:00
parent 4936812803
commit d4a73a0e8d
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
7 changed files with 89 additions and 3 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "safex11" name = "safex11"
version = "0.0.1" version = "0.0.2"
description = "Safe, high-level x11 bindings" description = "Safe, high-level x11 bindings"
license-file = "LICENSE" license-file = "LICENSE"
authors = ["Michael Zhang <iptq@protonmail.com>"] authors = ["Michael Zhang <iptq@protonmail.com>"]
@ -14,6 +14,7 @@ default = []
xlib = ["x11/xlib"] xlib = ["x11/xlib"]
xrender = ["x11/xrender"] xrender = ["x11/xrender"]
xinerama = ["x11/xlib", "x11/xinerama"] xinerama = ["x11/xlib", "x11/xinerama"]
xinput = ["x11/xinput"]
[dependencies] [dependencies]
libc = "0.2" libc = "0.2"

View file

@ -25,6 +25,12 @@ pub enum Error {
#[error("failed to translate coordinates")] #[error("failed to translate coordinates")]
TranslateCoordinatesError, TranslateCoordinatesError,
#[error("utf8 decoding error: {0}")]
Utf8(#[from] std::str::Utf8Error),
#[error("nul error: {0}")]
Nul(#[from] std::ffi::NulError),
#[error("error")] #[error("error")]
Error, Error,
} }

15
src/ffi.rs Normal file
View file

@ -0,0 +1,15 @@
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
use crate::Result;
pub unsafe fn string_from_c_char_star(ptr: *mut c_char) -> Result<String> {
let c_str = CStr::from_ptr(ptr);
let s = c_str.to_str()?;
Ok(s.to_owned())
}
pub fn c_char_star_from_string(s: impl AsRef<str>) -> Result<*mut c_char> {
let c_str = CString::new(s.as_ref().as_bytes())?;
Ok(c_str.into_raw())
}

View file

@ -7,6 +7,9 @@ extern crate log;
pub extern crate x11; pub extern crate x11;
#[cfg(feature = "xinput")]
pub mod xinput;
#[cfg(feature = "xlib")] #[cfg(feature = "xlib")]
pub mod xlib; pub mod xlib;
@ -17,6 +20,7 @@ pub mod xrender;
pub mod xinerama; pub mod xinerama;
mod errors; mod errors;
mod ffi;
mod rect; mod rect;
pub use crate::errors::{Error, Result}; pub use crate::errors::{Error, Result};

1
src/xinput/mod.rs Normal file
View file

@ -0,0 +1 @@

View file

@ -1,9 +1,11 @@
use std::ffi::CString; use std::ffi::CString;
use std::os::raw::c_char;
use std::ptr; use std::ptr;
use x11::xlib; use x11::xlib;
use crate::errors::{Error, Result}; use crate::errors::{Error, Result};
use crate::ffi;
use super::cursor::Cursor; use super::cursor::Cursor;
use super::event::Event; use super::event::Event;
@ -26,7 +28,9 @@ pub trait GetDisplay {
impl Display { impl Display {
/// Opens a new connection to an X server. /// Opens a new connection to an X server.
/// ///
/// On POSIX-conformant systems, the display name or DISPLAY environment variable can be a string in the format: /// On POSIX-conformant systems, the display name or DISPLAY environment
/// variable can be a string in the format:
///
/// hostname:number.screen_number /// hostname:number.screen_number
pub fn connect(display_name: impl AsRef<str>) -> Result<Display> { pub fn connect(display_name: impl AsRef<str>) -> Result<Display> {
let display_name = CString::new(display_name.as_ref()).unwrap(); let display_name = CString::new(display_name.as_ref()).unwrap();
@ -166,6 +170,36 @@ impl Display {
}; };
return Ok((window, revert_to_return)); return Ok((window, revert_to_return));
} }
/// Query extension
pub fn query_extension(&self, name: impl AsRef<str>) -> Result<()> {
let name = ffi::c_char_star_from_string(name)?;
let mut major_opcode_return = ptr::null_mut();
let mut first_event_return = ptr::null_mut();
let mut first_error_return = ptr::null_mut();
let result = unsafe {
xlib::XQueryExtension(
self.inner,
name,
major_opcode_return,
first_event_return,
first_error_return,
)
};
// TODO: check reuslt
unimplemented!()
}
/// List extensions
pub fn list_extensions(&self) -> Result<ListExtensions> {
let mut nextensions_return = ptr::null_mut();
let result = unsafe { xlib::XListExtensions(self.inner, nextensions_return) };
// TODO: check result null
// TODO: check nextensions_return
let nextensions_return = unsafe { *nextensions_return } as isize;
Ok(ListExtensions(&self, result, nextensions_return))
}
} }
impl Drop for Display { impl Drop for Display {
@ -179,3 +213,28 @@ impl Drop for Grab {
unsafe { xlib::XUngrabServer(self.0) }; unsafe { xlib::XUngrabServer(self.0) };
} }
} }
pub struct ListExtensions<'a>(&'a Display, *mut *mut c_char, isize);
impl<'a> ListExtensions<'a> {
pub fn iter(&self) -> ListExtensionsIter {
ListExtensionsIter(self, 0)
}
}
pub struct ListExtensionsIter<'a>(&'a ListExtensions<'a>, isize);
impl<'a> Iterator for ListExtensionsIter<'a> {
type Item = String;
fn next(&mut self) -> Option<Self::Item> {
if self.1 >= (self.0).2 {
return None;
}
// TODO: check for null
let base = unsafe { *(self.0).1.offset(self.1) };
let s = unsafe { ffi::string_from_c_char_star(base).unwrap() };
// TODO: don't unwrap here
Some(s)
}
}

View file

@ -3,5 +3,5 @@ pub struct Picture {}
impl Picture {} impl Picture {}
impl Drop for Picture { impl Drop for Picture {
fn drop(&self) {} fn drop(&mut self) {}
} }