aboutsummaryrefslogtreecommitdiff
path: root/src/safe_x11
diff options
context:
space:
mode:
Diffstat (limited to 'src/safe_x11')
-rw-r--r--src/safe_x11/Makefile7
-rw-r--r--src/safe_x11/event.rs33
-rw-r--r--src/safe_x11/mod.rs14
-rw-r--r--src/safe_x11/safex11.c32
-rw-r--r--src/safe_x11/safex11.h7
5 files changed, 80 insertions, 13 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <X11/Xutil.h>
+
+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 <X11/Xlib.h>
+
+int select_next_event(Display *display, int x11_fd, XEvent *retval);
+
+#endif