add some extensions stuff
This commit is contained in:
parent
4936812803
commit
d4a73a0e8d
7 changed files with 89 additions and 3 deletions
|
@ -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"
|
||||||
|
|
|
@ -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
15
src/ffi.rs
Normal 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())
|
||||||
|
}
|
|
@ -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
1
src/xinput/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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) {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue