mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
Better events handling on X11
This commit is contained in:
parent
c1da2b1273
commit
67349d717a
|
@ -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);
|
||||||
|
|
139
src/x11/mod.rs
139
src/x11/mod.rs
|
@ -141,70 +141,95 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_events(&self) -> Vec<Event> {
|
pub fn poll_events(&self) -> Vec<Event> {
|
||||||
unimplemented!()
|
use std::mem;
|
||||||
|
|
||||||
|
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_ {
|
||||||
|
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> {
|
pub fn wait_events(&self) -> Vec<Event> {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
let mut xev = unsafe { mem::uninitialized() };
|
loop {
|
||||||
unsafe { ffi::XNextEvent(self.display, &mut xev) };
|
// 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) };
|
||||||
|
|
||||||
let mut events = Vec::new();
|
// calling poll_events()
|
||||||
|
let ev = self.poll_events();
|
||||||
match xev.type_ {
|
if ev.len() >= 1 {
|
||||||
ffi::ClientMessage => {
|
return ev;
|
||||||
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 make_current(&self) {
|
pub fn make_current(&self) {
|
||||||
|
|
Loading…
Reference in a new issue