diff options
Diffstat (limited to 'src/x11')
| -rw-r--r-- | src/x11/ffi.rs | 5 | ||||
| -rw-r--r-- | src/x11/mod.rs | 133 | 
2 files changed, 84 insertions, 54 deletions
| diff --git a/src/x11/ffi.rs b/src/x11/ffi.rs index 553c62e..4a72ca3 100644 --- a/src/x11/ffi.rs +++ b/src/x11/ffi.rs @@ -1311,6 +1311,10 @@ pub struct XButtonEvent {  #[link(name = "X11")]  extern "C" {      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,          visual: *mut Visual, alloc: libc::c_int) -> Colormap;      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 XNextEvent(display: *mut Display, event_return: *mut XEvent);      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,          count: libc::c_int) -> Status;      pub fn XStoreName(display: *mut Display, w: Window, window_name: *const libc::c_char); diff --git a/src/x11/mod.rs b/src/x11/mod.rs index a917fc1..cbb40d5 100644 --- a/src/x11/mod.rs +++ b/src/x11/mod.rs @@ -141,72 +141,97 @@ impl Window {      }      pub fn poll_events(&self) -> Vec<Event> { -        unimplemented!() -    } - -    pub fn wait_events(&self) -> Vec<Event> {          use std::mem; - -        let mut xev = unsafe { mem::uninitialized() }; -        unsafe { ffi::XNextEvent(self.display, &mut xev) }; - +                  let mut events = Vec::new(); -        match xev.type_ { -            ffi::ClientMessage => { -                use Closed; -                use std::sync::atomics::Relaxed; +        loop { +            use std::num::Bounded; -                let client_msg: &ffi::XClientMessageEvent = unsafe { mem::transmute(&xev) }; +            let mut xev = unsafe { mem::uninitialized() }; +            let res = unsafe { ffi::XCheckMaskEvent(self.display, Bounded::max_value(), &mut xev) }; -                if client_msg.l[0] == self.wm_delete_window as libc::c_long { -                    self.should_close.store(true, Relaxed); -                    events.push(Closed); -                } -            }, - -            ffi::ResizeRequest => { -                use SizeChanged; -                let rs_event: &ffi::XResizeRequestEvent = unsafe { mem::transmute(&xev) }; -                events.push(SizeChanged(rs_event.width as uint, rs_event.height as uint)); -            }, - -            ffi::MotionNotify => { -                use CursorPositionChanged; -                let event: &ffi::XMotionEvent = unsafe { mem::transmute(&xev) }; -                events.push(CursorPositionChanged(event.x as uint, event.y as uint)); -            }, - -            ffi::KeyPress | ffi::KeyRelease => { -                use {Pressed, Released}; -                let event: &ffi::XKeyEvent = unsafe { mem::transmute(&xev) }; - -                let keysym = unsafe { ffi::XKeycodeToKeysym(self.display, event.keycode as ffi::KeyCode, 0) }; - -                match events::keycode_to_element(keysym as libc::c_uint) { -                    Some(elem) if xev.type_ == ffi::KeyPress => { -                        events.push(Pressed(elem)); -                    }, -                    Some(elem) if xev.type_ == ffi::KeyRelease => { -                        events.push(Released(elem)); -                    }, -                    _ => () -                } -                // -            }, +            if res == 0 { +                let res = unsafe { ffi::XCheckTypedEvent(self.display, ffi::ClientMessage, &mut xev) }; -            ffi::ButtonPress | ffi::ButtonRelease => { -                use {Pressed, Released}; -                let event: &ffi::XButtonEvent = unsafe { mem::transmute(&xev) }; -                //events.push(CursorPositionChanged(event.x as uint, event.y as uint)); -            }, +                if res == 0 { +                    break +                } +            } -            _ => () +            match xev.type_ { +                ffi::ClientMessage => { +                    use Closed; +                    use std::sync::atomics::Relaxed; + +                    let client_msg: &ffi::XClientMessageEvent = unsafe { mem::transmute(&xev) }; + +                    if client_msg.l[0] == self.wm_delete_window as libc::c_long { +                        self.should_close.store(true, Relaxed); +                        events.push(Closed); +                    } +                }, + +                ffi::ResizeRequest => { +                    use SizeChanged; +                    let rs_event: &ffi::XResizeRequestEvent = unsafe { mem::transmute(&xev) }; +                    events.push(SizeChanged(rs_event.width as uint, rs_event.height as uint)); +                }, + +                ffi::MotionNotify => { +                    use CursorPositionChanged; +                    let event: &ffi::XMotionEvent = unsafe { mem::transmute(&xev) }; +                    events.push(CursorPositionChanged(event.x as uint, event.y as uint)); +                }, + +                ffi::KeyPress | ffi::KeyRelease => { +                    use {Pressed, Released}; +                    let event: &ffi::XKeyEvent = unsafe { mem::transmute(&xev) }; + +                    let keysym = unsafe { ffi::XKeycodeToKeysym(self.display, event.keycode as ffi::KeyCode, 0) }; + +                    match events::keycode_to_element(keysym as libc::c_uint) { +                        Some(elem) if xev.type_ == ffi::KeyPress => { +                            events.push(Pressed(elem)); +                        }, +                        Some(elem) if xev.type_ == ffi::KeyRelease => { +                            events.push(Released(elem)); +                        }, +                        _ => () +                    } +                    // +                }, + +                ffi::ButtonPress | ffi::ButtonRelease => { +                    use {Pressed, Released}; +                    let event: &ffi::XButtonEvent = unsafe { mem::transmute(&xev) }; +                    //events.push(CursorPositionChanged(event.x as uint, event.y as uint)); +                }, + +                _ => () +            }          }          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) {          let res = unsafe { ffi::glXMakeCurrent(self.display, self.window, self.context) };          if res == 0 { | 
