Better events handling on X11

This commit is contained in:
Pierre Krieger 2014-07-28 15:06:38 +02:00
parent c1da2b1273
commit 67349d717a
2 changed files with 87 additions and 57 deletions

View file

@ -1311,6 +1311,10 @@ pub struct XButtonEvent {
#[link(name = "X11")] #[link(name = "X11")]
extern "C" { extern "C" {
pub fn XCloseDisplay(display: *mut Display); pub fn XCloseDisplay(display: *mut Display);
pub fn XCheckMaskEvent(display: *mut Display, event_mask: libc::c_long,
event_return: *mut XEvent) -> Bool;
pub fn XCheckTypedEvent(display: *mut Display, event_type: libc::c_int,
event_return: *mut XEvent) -> Bool;
pub fn XCreateColormap(display: *mut Display, w: Window, pub fn XCreateColormap(display: *mut Display, w: Window,
visual: *mut Visual, alloc: libc::c_int) -> Colormap; visual: *mut Visual, alloc: libc::c_int) -> Colormap;
pub fn XCreateWindow(display: *mut Display, parent: Window, x: libc::c_int, pub fn XCreateWindow(display: *mut Display, parent: Window, x: libc::c_int,
@ -1329,6 +1333,7 @@ extern "C" {
pub fn XMapWindow(display: *mut Display, w: Window); pub fn XMapWindow(display: *mut Display, w: Window);
pub fn XNextEvent(display: *mut Display, event_return: *mut XEvent); pub fn XNextEvent(display: *mut Display, event_return: *mut XEvent);
pub fn XOpenDisplay(display_name: *const libc::c_char) -> *mut Display; pub fn XOpenDisplay(display_name: *const libc::c_char) -> *mut Display;
pub fn XPeekEvent(display: *mut Display, event_return: *mut XEvent);
pub fn XSetWMProtocols(display: *mut Display, w: Window, protocols: *mut Atom, pub fn XSetWMProtocols(display: *mut Display, w: Window, protocols: *mut Atom,
count: libc::c_int) -> Status; count: libc::c_int) -> Status;
pub fn XStoreName(display: *mut Display, w: Window, window_name: *const libc::c_char); pub fn XStoreName(display: *mut Display, w: Window, window_name: *const libc::c_char);

View file

@ -141,17 +141,24 @@ impl Window {
} }
pub fn poll_events(&self) -> Vec<Event> { pub fn poll_events(&self) -> Vec<Event> {
unimplemented!()
}
pub fn wait_events(&self) -> Vec<Event> {
use std::mem; use std::mem;
let mut xev = unsafe { mem::uninitialized() };
unsafe { ffi::XNextEvent(self.display, &mut xev) };
let mut events = Vec::new(); let mut events = Vec::new();
loop {
use std::num::Bounded;
let mut xev = unsafe { mem::uninitialized() };
let res = unsafe { ffi::XCheckMaskEvent(self.display, Bounded::max_value(), &mut xev) };
if res == 0 {
let res = unsafe { ffi::XCheckTypedEvent(self.display, ffi::ClientMessage, &mut xev) };
if res == 0 {
break
}
}
match xev.type_ { match xev.type_ {
ffi::ClientMessage => { ffi::ClientMessage => {
use Closed; use Closed;
@ -203,10 +210,28 @@ impl Window {
_ => () _ => ()
} }
}
events events
} }
pub fn wait_events(&self) -> Vec<Event> {
use std::mem;
loop {
// this will block until an event arrives, but doesn't remove
// it from the queue
let mut xev = unsafe { mem::uninitialized() };
unsafe { ffi::XPeekEvent(self.display, &mut xev) };
// calling poll_events()
let ev = self.poll_events();
if ev.len() >= 1 {
return ev;
}
}
}
pub fn make_current(&self) { pub fn make_current(&self) {
let res = unsafe { ffi::glXMakeCurrent(self.display, self.window, self.context) }; let res = unsafe { ffi::glXMakeCurrent(self.display, self.window, self.context) };
if res == 0 { if res == 0 {