From 5da38341bc54f24c8cad41f1b63405d8cc955fe7 Mon Sep 17 00:00:00 2001 From: Matias Linares Date: Sun, 22 Nov 2015 02:58:41 -0300 Subject: next_xevent don't block anymore! Now the next_xevent (from the safex11) will not block forever. So we can listen the socket without doing some thread stuff. --- src/safe_x11/Makefile | 7 +++++++ src/safe_x11/event.rs | 33 +++++++++++++++++++++++++++++++++ src/safe_x11/mod.rs | 14 +------------- src/safe_x11/safex11.c | 32 ++++++++++++++++++++++++++++++++ src/safe_x11/safex11.h | 7 +++++++ 5 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 src/safe_x11/Makefile create mode 100644 src/safe_x11/event.rs create mode 100644 src/safe_x11/safex11.c create mode 100644 src/safe_x11/safex11.h (limited to 'src/safe_x11') diff --git a/src/safe_x11/Makefile b/src/safe_x11/Makefile new file mode 100644 index 0000000..4ea8a63 --- /dev/null +++ b/src/safe_x11/Makefile @@ -0,0 +1,7 @@ +all: + $(CC) -c -fPIC safex11.c -o safex11.o -lX11 + $(CC) -shared -o libsafex11.so safex11.o -lX11 + +clean: + rm safex11.o + rm *.so* diff --git a/src/safe_x11/event.rs b/src/safe_x11/event.rs new file mode 100644 index 0000000..2519bad --- /dev/null +++ b/src/safe_x11/event.rs @@ -0,0 +1,33 @@ +use x11::xlib::{ + XConnectionNumber, + Display, + XEvent, +}; + +use std::mem::uninitialized; + +use libc::c_int; + +#[link(name = "safex11")] +extern { + /// Get an XEvent if there're one on the queue or wait a little before continue. + fn select_next_event(display: *mut Display, x11_fd: c_int, ev: *mut XEvent) -> c_int; +} + +/// Get the file descriptor for the XServer +pub fn x11_fd(display: *mut Display) -> c_int { + unsafe { XConnectionNumber(display) } +} + +/// Get the next event from the xserver. This call will not block forever +/// (like XNextEvent), instead it will wait for a certain time (1 second +/// for now, but it can change) so we're not blocking the socket interface +/// on the main thread. +pub fn next_xevent(display: *mut Display, fd: c_int) -> XEvent { + unsafe { + let mut last_event: XEvent = uninitialized(); + let retval = select_next_event(display, fd, &mut last_event) as i32; + last_event + } +} + diff --git a/src/safe_x11/mod.rs b/src/safe_x11/mod.rs index e587021..06c7b3c 100644 --- a/src/safe_x11/mod.rs +++ b/src/safe_x11/mod.rs @@ -13,9 +13,6 @@ use x11::xlib::{ // Windows Window, - - // Events - XEvent, }; use x11::xlib::XKeyEvent; @@ -28,6 +25,7 @@ use std::slice; use std::fmt; pub mod window; +pub mod event; #[derive(Debug)] pub struct XSafeError<'a> { @@ -137,16 +135,6 @@ pub fn grab_key(display: *mut Display, key: u32, modifiers: u32, owner_events: b } } -/// Get the next event from the xserver. This call will block until a -/// event spawns. -pub fn next_xevent(display: *mut Display) -> XEvent { - unsafe { - let mut last_event: XEvent = uninitialized(); - xlib::XNextEvent(display, &mut last_event); - last_event - } -} - // Window code. /// Get a list from the active windows. This doesn't generate a hierarchical diff --git a/src/safe_x11/safex11.c b/src/safe_x11/safex11.c new file mode 100644 index 0000000..e4f87d8 --- /dev/null +++ b/src/safe_x11/safex11.c @@ -0,0 +1,32 @@ +#include "safex11.h" +#include +#include +#include + +int select_next_event(Display *display, int x11_fd, XEvent *retval) +{ + fd_set in_fds; + struct timeval tv; + XEvent ev; + /* check if there're some events on the queue first of all. */ + if(XPending(display) > 0) + goto EVENT_QUEUED; + + FD_ZERO(&in_fds); + FD_SET(x11_fd, &in_fds); + + /* one second */ + tv.tv_usec = 0; + tv.tv_sec = 1; + + /* Wait for X Event or a Timer */ + if(select(x11_fd+1, &in_fds, 0, 0, &tv)) + goto EVENT_QUEUED; + + return 0; + +EVENT_QUEUED: + XNextEvent(display, &ev); + *retval = ev; + return 1; +} diff --git a/src/safe_x11/safex11.h b/src/safe_x11/safex11.h new file mode 100644 index 0000000..bbf4e80 --- /dev/null +++ b/src/safe_x11/safex11.h @@ -0,0 +1,7 @@ +#ifndef _WM_EVENT_H_ +#define _WM_EVENT_H_ +#include + +int select_next_event(Display *display, int x11_fd, XEvent *retval); + +#endif -- cgit v1.2.3-70-g09d2