window events

This commit is contained in:
Michael Zhang 2020-06-29 00:22:13 -05:00
parent 89e08301a3
commit 3c2c92dd0d
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
8 changed files with 88 additions and 22 deletions

View file

@ -13,10 +13,11 @@ repository = "https://git.sr.ht/~iptq/safex11"
all-features = true all-features = true
[features] [features]
default = [] default = ["xlib"]
glx = ["x11/glx", "xlib"]
xlib = ["x11/xlib"] xlib = ["x11/xlib"]
xrender = ["x11/xrender"] xrender = ["x11/xrender"]
xinerama = ["x11/xlib", "x11/xinerama"] xinerama = ["x11/xinerama", "xlib"]
xinput = ["x11/xinput"] xinput = ["x11/xinput"]
[dependencies] [dependencies]
@ -24,3 +25,4 @@ libc = "0.2"
x11 = { version = "2.18" } x11 = { version = "2.18" }
thiserror = "1.0.20" thiserror = "1.0.20"
log = "0.4.8" log = "0.4.8"
bitflags = "1.2.1"

15
src/glx/mod.rs Normal file
View file

@ -0,0 +1,15 @@
use x11::glx;
use crate::errors::Result;
use crate::xlib::Display;
pub trait GlxExtension {
fn query_glx_extension(&self) -> Result<bool>;
}
impl GlxExtension for Display {
fn query_glx_extension(&self) -> Result<bool> {
let result = unsafe { glx::glXQueryExtension(self.inner, 0 as *mut _, 0 as *mut _) };
Ok(result == 1)
}
}

View file

@ -1,5 +1,7 @@
//! Higher level bindings to x11. //! Higher level bindings to x11.
#[macro_use]
extern crate bitflags;
#[macro_use] #[macro_use]
extern crate thiserror; extern crate thiserror;
#[macro_use] #[macro_use]
@ -7,6 +9,9 @@ extern crate log;
pub extern crate x11; pub extern crate x11;
#[cfg(feature = "glx")]
pub mod glx;
#[cfg(feature = "xinput")] #[cfg(feature = "xinput")]
pub mod xinput; pub mod xinput;

View file

@ -1,5 +1,6 @@
use std::ffi::CString; use std::ffi::CString;
use std::os::raw::c_char; use std::os::raw::c_char;
use std::mem::MaybeUninit;
use std::ptr; use std::ptr;
use x11::xlib; use x11::xlib;
@ -68,9 +69,13 @@ impl Display {
/// Get the next event, blocks until an event is reached. /// Get the next event, blocks until an event is reached.
pub fn next_event(&self) -> Result<Event> { pub fn next_event(&self) -> Result<Event> {
let event = ptr::null_mut(); debug!("fishing for next event...");
unsafe { xlib::XNextEvent(self.inner, event) }; let mut event = MaybeUninit::uninit();
let ptr = event.as_mut_ptr();
unsafe { xlib::XNextEvent(self.inner, ptr) };
// TODO: check to make sure this isn't null // TODO: check to make sure this isn't null
let mut event = unsafe{event.assume_init()};
debug!("event: {:?}", event);
unsafe { Event::from_raw(event) } unsafe { Event::from_raw(event) }
} }

View file

@ -5,7 +5,7 @@ use crate::errors::{Error, Result};
/// An x11 Event /// An x11 Event
#[derive(Debug)] #[derive(Debug)]
pub struct Event { pub struct Event {
inner: *mut xlib::XEvent, inner: xlib::XEvent,
kind: EventKind, kind: EventKind,
} }
@ -22,9 +22,8 @@ impl Event {
&self.kind &self.kind
} }
pub(super) unsafe fn from_raw(event: *mut xlib::XEvent) -> Result<Self> { pub(super) unsafe fn from_raw(event: xlib::XEvent) -> Result<Self> {
let inner = event; let inner = event;
let event = unsafe { *event };
debug!("event type: {:?}", event.type_); debug!("event type: {:?}", event.type_);
let kind = match event.type_ { let kind = match event.type_ {
xlib::KeyPress => EventKind::KeyPress(KeyEvent(event.key)), xlib::KeyPress => EventKind::KeyPress(KeyEvent(event.key)),
@ -35,11 +34,5 @@ impl Event {
} }
} }
impl Drop for Event {
fn drop(&mut self) {
unsafe { libc::free(self.inner as *mut libc::c_void) };
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct KeyEvent(xlib::XKeyEvent); pub struct KeyEvent(xlib::XKeyEvent);

View file

@ -1,4 +1,16 @@
use std::os::raw::c_ulong; //! XImage
//! ======
//!
//! Xlib provides some structures to perform operations on images. However, because there are
//! different in-memory representations, working with images is actually totally fucked. If you
//! want to maintain your sanity, do NOT pry into the raw data buffer of an Image. Instead, index
//! into the image using `PixBuffer::get_pixel` which already performs the conversion and returns a
//! tuple of RGB values.
//!
//! Peeking into the raw data buffer of an Image
//! --------------------------------------------
//!
//! Images consist of lines of longs in row-major form.
use x11::xlib; use x11::xlib;

View file

@ -14,10 +14,4 @@ pub use self::drawable::Drawable;
pub use self::event::{Event, EventKind}; pub use self::event::{Event, EventKind};
pub use self::image::{Image, ImageByteOrder}; pub use self::image::{Image, ImageByteOrder};
pub use self::visual::Visual; pub use self::visual::Visual;
pub use self::window::Window; pub use self::window::{EventMask, Window};
pub const XC_crosshair: u32 = 34;
pub const XC_ll_angle: u32 = 76;
pub const XC_lr_angle: u32 = 78;
pub const XC_ul_angle: u32 = 144;
pub const XC_ur_angle: u32 = 148;

View file

@ -1,4 +1,5 @@
use std::mem; use std::mem;
use std::os::raw::c_ulong;
use x11::xlib; use x11::xlib;
@ -112,10 +113,18 @@ impl Window {
} }
} }
/// Map to display /// "Maps", or shows a window to a display.
pub fn map(&self) { pub fn map(&self) {
unsafe { xlib::XMapWindow(self.display, self.inner) }; unsafe { xlib::XMapWindow(self.display, self.inner) };
} }
/// Requests for events from the server matching a particular event mask.
///
/// If this function is not called, events will not be reported.
pub fn select_input(&self, event_mask: EventMask) {
debug!("event mask: {:?}", event_mask);
unsafe { xlib::XSelectInput(self.display, self.inner, event_mask.bits as i64) };
}
} }
impl GetDisplay for Window { impl GetDisplay for Window {
@ -183,3 +192,34 @@ impl Drop for WindowAttributes {
unsafe { libc::free(self.inner as *mut libc::c_void) }; unsafe { libc::free(self.inner as *mut libc::c_void) };
} }
} }
bitflags! {
pub struct EventMask: c_ulong {
const NO_EVENT_MASK = 0;
const KEY_PRESS_MASK = (1<<0);
const KEY_RELEASE_MASK = (1<<1);
const BUTTON_PRESS_MASK = (1<<2);
const BUTTON_RELEASE_MASK = (1<<3);
const ENTER_WINDOW_MASK = (1<<4);
const LEAVE_WINDOW_MASK = (1<<5);
const POINTER_MOTION_MASK = (1<<6);
const POINTER_MOTION_HINT_MASK = (1<<7);
const BUTTON_1_MOTION_MASK = (1<<8);
const BUTTON_2_MOTION_MASK = (1<<9);
const BUTTON_3_MOTION_MASK = (1<<10);
const BUTTON_4_MOTION_MASK = (1<<11);
const BUTTON_5_MOTION_MASK = (1<<12);
const BUTTON_MOTION_MASK = (1<<13);
const KEYMAP_STATE_MASK = (1<<14);
const EXPOSURE_MASK = (1<<15);
const VISIBILITY_CHANGE_MASK = (1<<16);
const STRUCTURE_NOTIFY_MASK = (1<<17);
const RESIZE_REDIRECT_MASK = (1<<18);
const SUBSTRUCTURE_NOTIFY_MASK = (1<<19);
const SUBSTRUCTURE_REDIRECT_MASK = (1<<20);
const FOCUS_CHANGE_MASK = (1<<21);
const PROPERTY_CHANGE_MASK = (1<<22);
const COLORMAP_CHANGE_MASK = (1<<23);
const OWNER_GRAB_BUTTON_MASK = (1<<24);
}
}