aboutsummaryrefslogtreecommitdiffstats
path: root/src/x11/window
diff options
context:
space:
mode:
Diffstat (limited to 'src/x11/window')
-rw-r--r--src/x11/window/mod.rs58
1 files changed, 47 insertions, 11 deletions
diff --git a/src/x11/window/mod.rs b/src/x11/window/mod.rs
index 99cbf9d..d69feab 100644
--- a/src/x11/window/mod.rs
+++ b/src/x11/window/mod.rs
@@ -1,6 +1,7 @@
-use {Event, WindowBuilder};
+use {Event, WindowBuilder, KeyModifiers};
use libc;
use std::{mem, ptr};
+use std::cell::Cell;
use std::sync::atomic::AtomicBool;
use super::ffi;
use sync::one::{Once, ONCE_INIT};
@@ -31,6 +32,7 @@ pub struct Window {
xf86_desk_mode: *mut ffi::XF86VidModeModeInfo,
screen_id: libc::c_int,
is_fullscreen: bool,
+ current_modifiers: Cell<KeyModifiers>,
}
impl Window {
@@ -95,7 +97,7 @@ impl Window {
best_mode = i;
}
};
- if best_mode == -1 {
+ if best_mode == -1 && builder.monitor.is_some() {
return Err(format!("Could not find a suitable graphics mode"));
}
@@ -168,7 +170,8 @@ impl Window {
let mut wm_delete_window = ffi::XInternAtom(display,
"WM_DELETE_WINDOW".to_c_str().as_ptr() as *const libc::c_char, 0);
ffi::XSetWMProtocols(display, window, &mut wm_delete_window, 1);
- ffi::XStoreName(display, window, mem::transmute(builder.title.as_slice().as_ptr()));
+ let c_title = builder.title.to_c_str();
+ ffi::XStoreName(display, window, c_title.as_ptr());
ffi::XFlush(display);
wm_delete_window
@@ -255,6 +258,7 @@ impl Window {
xf86_desk_mode: xf86_desk_mode,
screen_id: screen_id,
is_fullscreen: builder.monitor.is_some(),
+ current_modifiers: Cell::new(KeyModifiers::empty()),
};
// calling glViewport
@@ -277,9 +281,10 @@ impl Window {
}
pub fn set_title(&self, title: &str) {
+ let c_title = title.to_c_str();
unsafe {
- ffi::XStoreName(self.display, self.window,
- mem::transmute(title.as_slice().as_ptr()));
+ ffi::XStoreName(self.display, self.window, c_title.as_ptr());
+ ffi::XFlush(self.display);
}
}
@@ -375,7 +380,10 @@ impl Window {
},
ffi::KeyPress | ffi::KeyRelease => {
- use {KeyboardInput, Pressed, Released, ReceivedCharacter, KeyModifiers};
+ use {KeyboardInput, Pressed, Released, ReceivedCharacter};
+ use {LEFT_CONTROL_MODIFIER, RIGHT_CONTROL_MODIFIER};
+ use {LEFT_SHIFT_MODIFIER, RIGHT_SHIFT_MODIFIER};
+ use {LEFT_ALT_MODIFIER, RIGHT_ALT_MODIFIER, CAPS_LOCK_MODIFIER};
let event: &mut ffi::XKeyEvent = unsafe { mem::transmute(&xev) };
if event.type_ == ffi::KeyPress {
@@ -406,16 +414,38 @@ impl Window {
ffi::XKeycodeToKeysym(self.display, event.keycode as ffi::KeyCode, 0)
};
+ let modifier_flag = match keysym as u32 {
+ ffi::XK_Shift_L => Some(LEFT_SHIFT_MODIFIER),
+ ffi::XK_Shift_R => Some(RIGHT_SHIFT_MODIFIER),
+ ffi::XK_Control_L => Some(LEFT_CONTROL_MODIFIER),
+ ffi::XK_Control_R => Some(RIGHT_CONTROL_MODIFIER),
+ ffi::XK_Caps_Lock => Some(CAPS_LOCK_MODIFIER),
+ ffi::XK_Meta_L => Some(LEFT_ALT_MODIFIER),
+ ffi::XK_Meta_R => Some(RIGHT_ALT_MODIFIER),
+ _ => None,
+ };
+ match modifier_flag {
+ Some(flag) => {
+ let mut current_modifiers = self.current_modifiers.get();
+ match state {
+ Pressed => current_modifiers.insert(flag),
+ Released => current_modifiers.remove(flag),
+ }
+ self.current_modifiers.set(current_modifiers);
+ }
+ None => {}
+ }
+
let vkey = events::keycode_to_element(keysym as libc::c_uint);
events.push(KeyboardInput(state, event.keycode as u8,
- vkey, KeyModifiers::empty()));
+ vkey, self.current_modifiers.get()));
//
},
ffi::ButtonPress | ffi::ButtonRelease => {
- use {MouseInput, Pressed, Released};
- use {LeftMouseButton, RightMouseButton, MiddleMouseButton, OtherMouseButton};
+ use {MouseInput, MouseWheel, Pressed, Released};
+ use {LeftMouseButton, RightMouseButton, MiddleMouseButton};
let event: &ffi::XButtonEvent = unsafe { mem::transmute(&xev) };
let state = if xev.type_ == ffi::ButtonPress { Pressed } else { Released };
@@ -424,8 +454,14 @@ impl Window {
ffi::Button1 => Some(LeftMouseButton),
ffi::Button2 => Some(MiddleMouseButton),
ffi::Button3 => Some(RightMouseButton),
- ffi::Button4 => Some(OtherMouseButton(4)),
- ffi::Button5 => Some(OtherMouseButton(5)),
+ ffi::Button4 => {
+ events.push(MouseWheel(1));
+ None
+ }
+ ffi::Button5 => {
+ events.push(MouseWheel(-1));
+ None
+ }
_ => None
};