mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-11 13:31:29 +11:00
api/wayland: Reset to empty API.
In order to build the whole new structure.
This commit is contained in:
parent
ae7638b995
commit
fad2e77a36
36
Cargo.toml
36
Cargo.toml
|
@ -82,42 +82,42 @@ dwmapi-sys = "0.1"
|
|||
|
||||
[target.i686-unknown-linux-gnu.dependencies]
|
||||
osmesa-sys = "0.0.5"
|
||||
wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.2.0"
|
||||
wayland-window = "0.1.0"
|
||||
wayland-client = { version = "0.4.3", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.3.1"
|
||||
wayland-window = "0.2.0"
|
||||
x11-dl = "~2.2"
|
||||
|
||||
[target.x86_64-unknown-linux-gnu.dependencies]
|
||||
osmesa-sys = "0.0.5"
|
||||
wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.2.0"
|
||||
wayland-window = "0.1.0"
|
||||
wayland-client = { version = "0.4.3", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.3.1"
|
||||
wayland-window = "0.2.0"
|
||||
x11-dl = "~2.2"
|
||||
|
||||
[target.arm-unknown-linux-gnueabihf.dependencies]
|
||||
osmesa-sys = "0.0.5"
|
||||
wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.2.0"
|
||||
wayland-window = "0.1.0"
|
||||
wayland-client = { version = "0.4.3", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.3.1"
|
||||
wayland-window = "0.2.0"
|
||||
x11-dl = "~2.2"
|
||||
|
||||
[target.aarch64-unknown-linux-gnu.dependencies]
|
||||
osmesa-sys = "0.0.5"
|
||||
wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.2.0"
|
||||
wayland-window = "0.1.0"
|
||||
wayland-client = { version = "0.4.3", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.3.1"
|
||||
wayland-window = "0.2.0"
|
||||
x11-dl = "~2.2"
|
||||
|
||||
[target.x86_64-unknown-dragonfly.dependencies]
|
||||
osmesa-sys = "0.0.5"
|
||||
wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.2.0"
|
||||
wayland-window = "0.1.0"
|
||||
wayland-client = { version = "0.4.3", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.3.1"
|
||||
wayland-window = "0.2.0"
|
||||
x11-dl = "~2.2"
|
||||
|
||||
[target.x86_64-unknown-freebsd.dependencies]
|
||||
osmesa-sys = "0.0.5"
|
||||
wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.2.0"
|
||||
wayland-window = "0.1.0"
|
||||
wayland-client = { version = "0.4.3", features = ["egl", "dlopen"] }
|
||||
wayland-kbd = "0.3.1"
|
||||
wayland-window = "0.2.0"
|
||||
x11-dl = "~2.2"
|
||||
|
|
|
@ -1,228 +0,0 @@
|
|||
use super::wayland::core::{default_display, Display, Registry};
|
||||
use super::wayland::core::compositor::{Compositor, SurfaceId, WSurface};
|
||||
use super::wayland::core::output::Output;
|
||||
use super::wayland::core::seat::{ButtonState, Seat, Pointer, Keyboard, KeyState};
|
||||
use super::wayland::core::shell::Shell;
|
||||
use super::wayland_kbd::MappedKeyboard;
|
||||
use super::keyboard::keycode_to_vkey;
|
||||
|
||||
|
||||
use std::collections::{VecDeque, HashMap};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use Event;
|
||||
use MouseButton;
|
||||
use ElementState;
|
||||
|
||||
enum AnyKeyboard {
|
||||
RawKeyBoard(Keyboard),
|
||||
XKB(MappedKeyboard)
|
||||
}
|
||||
|
||||
pub struct WaylandContext {
|
||||
pub display: Display,
|
||||
pub registry: Registry,
|
||||
pub compositor: Compositor,
|
||||
pub shell: Shell,
|
||||
pub seat: Seat,
|
||||
pointer: Option<Mutex<Pointer<WSurface>>>,
|
||||
keyboard: Option<AnyKeyboard>,
|
||||
windows_event_queues: Arc<Mutex<HashMap<SurfaceId, Arc<Mutex<VecDeque<Event>>>>>>,
|
||||
current_pointer_surface: Arc<Mutex<Option<SurfaceId>>>,
|
||||
current_keyboard_surface: Arc<Mutex<Option<SurfaceId>>>,
|
||||
pub outputs: Vec<Arc<Output>>
|
||||
}
|
||||
|
||||
impl WaylandContext {
|
||||
pub fn new() -> Option<WaylandContext> {
|
||||
let display = match default_display() {
|
||||
Some(d) => d,
|
||||
None => return None,
|
||||
};
|
||||
let registry = display.get_registry();
|
||||
// let the registry get its events
|
||||
display.sync_roundtrip();
|
||||
let compositor = match registry.get_compositor() {
|
||||
Some(c) => c,
|
||||
None => return None,
|
||||
};
|
||||
let shell = match registry.get_shell() {
|
||||
Some(s) => s,
|
||||
None => return None,
|
||||
};
|
||||
let seat = match registry.get_seats().into_iter().next() {
|
||||
Some(s) => s,
|
||||
None => return None,
|
||||
};
|
||||
let outputs = registry.get_outputs().into_iter().map(Arc::new).collect::<Vec<_>>();
|
||||
// let the other globals get their events
|
||||
display.sync_roundtrip();
|
||||
|
||||
let current_pointer_surface = Arc::new(Mutex::new(None));
|
||||
|
||||
// rustc has trouble finding the correct type here, so we explicit it.
|
||||
let windows_event_queues = Arc::new(Mutex::new(
|
||||
HashMap::<SurfaceId, Arc<Mutex<VecDeque<Event>>>>::new()
|
||||
));
|
||||
|
||||
// handle pointer inputs
|
||||
let mut pointer = seat.get_pointer();
|
||||
if let Some(ref mut p) = pointer {
|
||||
// set the enter/leave callbacks
|
||||
let current_surface = current_pointer_surface.clone();
|
||||
p.set_enter_action(move |_, _, sid, x, y| {
|
||||
*current_surface.lock().unwrap() = Some(sid);
|
||||
});
|
||||
let current_surface = current_pointer_surface.clone();
|
||||
p.set_leave_action(move |_, _, sid| {
|
||||
*current_surface.lock().unwrap() = None;
|
||||
});
|
||||
// set the events callbacks
|
||||
let current_surface = current_pointer_surface.clone();
|
||||
let event_queues = windows_event_queues.clone();
|
||||
p.set_motion_action(move |_, _, x, y| {
|
||||
// dispatch to the appropriate queue
|
||||
let sid = *current_surface.lock().unwrap();
|
||||
if let Some(sid) = sid {
|
||||
let map = event_queues.lock().unwrap();
|
||||
if let Some(queue) = map.get(&sid) {
|
||||
queue.lock().unwrap().push_back(Event::MouseMoved((x as i32,y as i32)))
|
||||
}
|
||||
}
|
||||
});
|
||||
let current_surface = current_pointer_surface.clone();
|
||||
let event_queues = windows_event_queues.clone();
|
||||
p.set_button_action(move |_, _, sid, b, s| {
|
||||
let button = match b {
|
||||
0x110 => MouseButton::Left,
|
||||
0x111 => MouseButton::Right,
|
||||
0x112 => MouseButton::Middle,
|
||||
_ => return
|
||||
};
|
||||
let state = match s {
|
||||
ButtonState::Released => ElementState::Released,
|
||||
ButtonState::Pressed => ElementState::Pressed
|
||||
};
|
||||
// dispatch to the appropriate queue
|
||||
let sid = *current_surface.lock().unwrap();
|
||||
if let Some(sid) = sid {
|
||||
let map = event_queues.lock().unwrap();
|
||||
if let Some(queue) = map.get(&sid) {
|
||||
queue.lock().unwrap().push_back(Event::MouseInput(state, button))
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// handle keyboard inputs
|
||||
let mut keyboard = None;
|
||||
let current_keyboard_surface = Arc::new(Mutex::new(None));
|
||||
if let Some(mut wkbd) = seat.get_keyboard() {
|
||||
display.sync_roundtrip();
|
||||
|
||||
let current_surface = current_keyboard_surface.clone();
|
||||
wkbd.set_enter_action(move |_, _, sid, _| {
|
||||
*current_surface.lock().unwrap() = Some(sid);
|
||||
});
|
||||
let current_surface = current_keyboard_surface.clone();
|
||||
wkbd.set_leave_action(move |_, _, sid| {
|
||||
*current_surface.lock().unwrap() = None;
|
||||
});
|
||||
|
||||
let kbd = match MappedKeyboard::new(wkbd) {
|
||||
Ok(mkbd) => {
|
||||
// We managed to load a keymap
|
||||
let current_surface = current_keyboard_surface.clone();
|
||||
let event_queues = windows_event_queues.clone();
|
||||
mkbd.set_key_action(move |state, _, _, _, keycode, keystate| {
|
||||
let kstate = match keystate {
|
||||
KeyState::Released => ElementState::Released,
|
||||
KeyState::Pressed => ElementState::Pressed
|
||||
};
|
||||
let mut events = Vec::new();
|
||||
// key event
|
||||
events.push(Event::KeyboardInput(
|
||||
kstate,
|
||||
(keycode & 0xff) as u8,
|
||||
keycode_to_vkey(state, keycode)
|
||||
));
|
||||
// utf8 events
|
||||
if kstate == ElementState::Pressed {
|
||||
if let Some(txt) = state.get_utf8(keycode) {
|
||||
events.extend(
|
||||
txt.chars().map(Event::ReceivedCharacter)
|
||||
);
|
||||
}
|
||||
}
|
||||
// dispatch to the appropriate queue
|
||||
let sid = *current_surface.lock().unwrap();
|
||||
if let Some(sid) = sid {
|
||||
let map = event_queues.lock().unwrap();
|
||||
if let Some(queue) = map.get(&sid) {
|
||||
queue.lock().unwrap().extend(events.into_iter());
|
||||
}
|
||||
}
|
||||
});
|
||||
AnyKeyboard::XKB(mkbd)
|
||||
},
|
||||
Err(mut rkbd) => {
|
||||
// fallback to raw inputs, no virtual keycodes
|
||||
let current_surface = current_keyboard_surface.clone();
|
||||
let event_queues = windows_event_queues.clone();
|
||||
rkbd.set_key_action(move |_, _, _, keycode, keystate| {
|
||||
let kstate = match keystate {
|
||||
KeyState::Released => ElementState::Released,
|
||||
KeyState::Pressed => ElementState::Pressed
|
||||
};
|
||||
let event = Event::KeyboardInput(kstate, (keycode & 0xff) as u8, None);
|
||||
// dispatch to the appropriate queue
|
||||
let sid = *current_surface.lock().unwrap();
|
||||
if let Some(sid) = sid {
|
||||
let map = event_queues.lock().unwrap();
|
||||
if let Some(queue) = map.get(&sid) {
|
||||
queue.lock().unwrap().push_back(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
AnyKeyboard::RawKeyBoard(rkbd)
|
||||
}
|
||||
};
|
||||
keyboard = Some(kbd);
|
||||
}
|
||||
|
||||
Some(WaylandContext {
|
||||
display: display,
|
||||
registry: registry,
|
||||
compositor: compositor,
|
||||
shell: shell,
|
||||
seat: seat,
|
||||
pointer: pointer.map(|p| Mutex::new(p)),
|
||||
keyboard: keyboard,
|
||||
windows_event_queues: windows_event_queues,
|
||||
current_pointer_surface: current_pointer_surface,
|
||||
current_keyboard_surface: current_keyboard_surface,
|
||||
outputs: outputs
|
||||
})
|
||||
}
|
||||
|
||||
pub fn register_surface(&self, sid: SurfaceId, queue: Arc<Mutex<VecDeque<Event>>>) {
|
||||
self.windows_event_queues.lock().unwrap().insert(sid, queue);
|
||||
if let Some(ref p) = self.pointer {
|
||||
p.lock().unwrap().add_handled_surface(sid);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deregister_surface(&self, sid: SurfaceId) {
|
||||
self.windows_event_queues.lock().unwrap().remove(&sid);
|
||||
if let Some(ref p) = self.pointer {
|
||||
p.lock().unwrap().remove_handled_surface(sid);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_event_for(&self, sid: SurfaceId, evt: Event) {
|
||||
let mut guard = self.windows_event_queues.lock().unwrap();
|
||||
if let Some(queue) = guard.get(&sid) {
|
||||
queue.lock().unwrap().push_back(evt);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
use super::wayland_kbd::{KbState, keysyms};
|
||||
|
||||
use VirtualKeyCode;
|
||||
|
||||
pub fn keycode_to_vkey(state: &KbState, keycode: u32) -> Option<VirtualKeyCode> {
|
||||
// first line is hard-coded because it must be case insensitive
|
||||
// and is a linux constant anyway
|
||||
match keycode {
|
||||
1 => return Some(VirtualKeyCode::Escape),
|
||||
2 => return Some(VirtualKeyCode::Key1),
|
||||
3 => return Some(VirtualKeyCode::Key2),
|
||||
4 => return Some(VirtualKeyCode::Key3),
|
||||
5 => return Some(VirtualKeyCode::Key4),
|
||||
6 => return Some(VirtualKeyCode::Key5),
|
||||
7 => return Some(VirtualKeyCode::Key6),
|
||||
8 => return Some(VirtualKeyCode::Key7),
|
||||
9 => return Some(VirtualKeyCode::Key8),
|
||||
10 => return Some(VirtualKeyCode::Key9),
|
||||
11 => return Some(VirtualKeyCode::Key0),
|
||||
_ => {}
|
||||
}
|
||||
// for other keys, we use the keysym
|
||||
return match state.get_one_sym(keycode) {
|
||||
// letters
|
||||
keysyms::XKB_KEY_A | keysyms::XKB_KEY_a => Some(VirtualKeyCode::A),
|
||||
keysyms::XKB_KEY_B | keysyms::XKB_KEY_b => Some(VirtualKeyCode::B),
|
||||
keysyms::XKB_KEY_C | keysyms::XKB_KEY_c => Some(VirtualKeyCode::C),
|
||||
keysyms::XKB_KEY_D | keysyms::XKB_KEY_d => Some(VirtualKeyCode::D),
|
||||
keysyms::XKB_KEY_E | keysyms::XKB_KEY_e => Some(VirtualKeyCode::E),
|
||||
keysyms::XKB_KEY_F | keysyms::XKB_KEY_f => Some(VirtualKeyCode::F),
|
||||
keysyms::XKB_KEY_G | keysyms::XKB_KEY_g => Some(VirtualKeyCode::G),
|
||||
keysyms::XKB_KEY_H | keysyms::XKB_KEY_h => Some(VirtualKeyCode::H),
|
||||
keysyms::XKB_KEY_I | keysyms::XKB_KEY_i => Some(VirtualKeyCode::I),
|
||||
keysyms::XKB_KEY_J | keysyms::XKB_KEY_j => Some(VirtualKeyCode::J),
|
||||
keysyms::XKB_KEY_K | keysyms::XKB_KEY_k => Some(VirtualKeyCode::K),
|
||||
keysyms::XKB_KEY_L | keysyms::XKB_KEY_l => Some(VirtualKeyCode::L),
|
||||
keysyms::XKB_KEY_M | keysyms::XKB_KEY_m => Some(VirtualKeyCode::M),
|
||||
keysyms::XKB_KEY_N | keysyms::XKB_KEY_n => Some(VirtualKeyCode::N),
|
||||
keysyms::XKB_KEY_O | keysyms::XKB_KEY_o => Some(VirtualKeyCode::O),
|
||||
keysyms::XKB_KEY_P | keysyms::XKB_KEY_p => Some(VirtualKeyCode::P),
|
||||
keysyms::XKB_KEY_Q | keysyms::XKB_KEY_q => Some(VirtualKeyCode::Q),
|
||||
keysyms::XKB_KEY_R | keysyms::XKB_KEY_r => Some(VirtualKeyCode::R),
|
||||
keysyms::XKB_KEY_S | keysyms::XKB_KEY_s => Some(VirtualKeyCode::S),
|
||||
keysyms::XKB_KEY_T | keysyms::XKB_KEY_t => Some(VirtualKeyCode::T),
|
||||
keysyms::XKB_KEY_U | keysyms::XKB_KEY_u => Some(VirtualKeyCode::U),
|
||||
keysyms::XKB_KEY_V | keysyms::XKB_KEY_v => Some(VirtualKeyCode::V),
|
||||
keysyms::XKB_KEY_W | keysyms::XKB_KEY_w => Some(VirtualKeyCode::W),
|
||||
keysyms::XKB_KEY_X | keysyms::XKB_KEY_x => Some(VirtualKeyCode::X),
|
||||
keysyms::XKB_KEY_Y | keysyms::XKB_KEY_y => Some(VirtualKeyCode::Y),
|
||||
keysyms::XKB_KEY_Z | keysyms::XKB_KEY_z => Some(VirtualKeyCode::Z),
|
||||
// F--
|
||||
keysyms::XKB_KEY_F1 => Some(VirtualKeyCode::F1),
|
||||
keysyms::XKB_KEY_F2 => Some(VirtualKeyCode::F2),
|
||||
keysyms::XKB_KEY_F3 => Some(VirtualKeyCode::F3),
|
||||
keysyms::XKB_KEY_F4 => Some(VirtualKeyCode::F4),
|
||||
keysyms::XKB_KEY_F5 => Some(VirtualKeyCode::F5),
|
||||
keysyms::XKB_KEY_F6 => Some(VirtualKeyCode::F6),
|
||||
keysyms::XKB_KEY_F7 => Some(VirtualKeyCode::F7),
|
||||
keysyms::XKB_KEY_F8 => Some(VirtualKeyCode::F8),
|
||||
keysyms::XKB_KEY_F9 => Some(VirtualKeyCode::F9),
|
||||
keysyms::XKB_KEY_F10 => Some(VirtualKeyCode::F10),
|
||||
keysyms::XKB_KEY_F11 => Some(VirtualKeyCode::F11),
|
||||
keysyms::XKB_KEY_F12 => Some(VirtualKeyCode::F12),
|
||||
keysyms::XKB_KEY_F13 => Some(VirtualKeyCode::F13),
|
||||
keysyms::XKB_KEY_F14 => Some(VirtualKeyCode::F14),
|
||||
keysyms::XKB_KEY_F15 => Some(VirtualKeyCode::F15),
|
||||
// flow control
|
||||
keysyms::XKB_KEY_Print => Some(VirtualKeyCode::Snapshot),
|
||||
keysyms::XKB_KEY_Scroll_Lock => Some(VirtualKeyCode::Scroll),
|
||||
keysyms::XKB_KEY_Pause => Some(VirtualKeyCode::Pause),
|
||||
keysyms::XKB_KEY_Insert => Some(VirtualKeyCode::Insert),
|
||||
keysyms::XKB_KEY_Home => Some(VirtualKeyCode::Home),
|
||||
keysyms::XKB_KEY_Delete => Some(VirtualKeyCode::Delete),
|
||||
keysyms::XKB_KEY_End => Some(VirtualKeyCode::End),
|
||||
keysyms::XKB_KEY_Page_Down => Some(VirtualKeyCode::PageDown),
|
||||
keysyms::XKB_KEY_Page_Up => Some(VirtualKeyCode::PageUp),
|
||||
// arrows
|
||||
keysyms::XKB_KEY_Left => Some(VirtualKeyCode::Left),
|
||||
keysyms::XKB_KEY_Up => Some(VirtualKeyCode::Up),
|
||||
keysyms::XKB_KEY_Right => Some(VirtualKeyCode::Right),
|
||||
keysyms::XKB_KEY_Down => Some(VirtualKeyCode::Down),
|
||||
//
|
||||
keysyms::XKB_KEY_BackSpace => Some(VirtualKeyCode::Back),
|
||||
keysyms::XKB_KEY_Return => Some(VirtualKeyCode::Return),
|
||||
keysyms::XKB_KEY_space => Some(VirtualKeyCode::Space),
|
||||
// keypad
|
||||
keysyms::XKB_KEY_Num_Lock => Some(VirtualKeyCode::Numlock),
|
||||
keysyms::XKB_KEY_KP_0 => Some(VirtualKeyCode::Numpad0),
|
||||
keysyms::XKB_KEY_KP_1 => Some(VirtualKeyCode::Numpad1),
|
||||
keysyms::XKB_KEY_KP_2 => Some(VirtualKeyCode::Numpad2),
|
||||
keysyms::XKB_KEY_KP_3 => Some(VirtualKeyCode::Numpad3),
|
||||
keysyms::XKB_KEY_KP_4 => Some(VirtualKeyCode::Numpad4),
|
||||
keysyms::XKB_KEY_KP_5 => Some(VirtualKeyCode::Numpad5),
|
||||
keysyms::XKB_KEY_KP_6 => Some(VirtualKeyCode::Numpad6),
|
||||
keysyms::XKB_KEY_KP_7 => Some(VirtualKeyCode::Numpad7),
|
||||
keysyms::XKB_KEY_KP_8 => Some(VirtualKeyCode::Numpad8),
|
||||
keysyms::XKB_KEY_KP_9 => Some(VirtualKeyCode::Numpad9),
|
||||
// misc
|
||||
// => Some(VirtualKeyCode::AbntC1),
|
||||
// => Some(VirtualKeyCode::AbntC2),
|
||||
keysyms::XKB_KEY_plus => Some(VirtualKeyCode::Add),
|
||||
keysyms::XKB_KEY_apostrophe => Some(VirtualKeyCode::Apostrophe),
|
||||
// => Some(VirtualKeyCode::Apps),
|
||||
// => Some(VirtualKeyCode::At),
|
||||
// => Some(VirtualKeyCode::Ax),
|
||||
keysyms::XKB_KEY_backslash => Some(VirtualKeyCode::Backslash),
|
||||
// => Some(VirtualKeyCode::Calculator),
|
||||
// => Some(VirtualKeyCode::Capital),
|
||||
keysyms::XKB_KEY_colon => Some(VirtualKeyCode::Colon),
|
||||
keysyms::XKB_KEY_comma => Some(VirtualKeyCode::Comma),
|
||||
// => Some(VirtualKeyCode::Convert),
|
||||
// => Some(VirtualKeyCode::Decimal),
|
||||
// => Some(VirtualKeyCode::Divide),
|
||||
keysyms::XKB_KEY_equal => Some(VirtualKeyCode::Equals),
|
||||
// => Some(VirtualKeyCode::Grave),
|
||||
// => Some(VirtualKeyCode::Kana),
|
||||
// => Some(VirtualKeyCode::Kanji),
|
||||
keysyms::XKB_KEY_Alt_L => Some(VirtualKeyCode::LAlt),
|
||||
// => Some(VirtualKeyCode::LBracket),
|
||||
keysyms::XKB_KEY_Control_L => Some(VirtualKeyCode::LControl),
|
||||
// => Some(VirtualKeyCode::LMenu),
|
||||
keysyms::XKB_KEY_Shift_L => Some(VirtualKeyCode::LShift),
|
||||
// => Some(VirtualKeyCode::LWin),
|
||||
// => Some(VirtualKeyCode::Mail),
|
||||
// => Some(VirtualKeyCode::MediaSelect),
|
||||
// => Some(VirtualKeyCode::MediaStop),
|
||||
keysyms::XKB_KEY_minus => Some(VirtualKeyCode::Minus),
|
||||
keysyms::XKB_KEY_asterisk => Some(VirtualKeyCode::Multiply),
|
||||
// => Some(VirtualKeyCode::Mute),
|
||||
// => Some(VirtualKeyCode::MyComputer),
|
||||
// => Some(VirtualKeyCode::NextTrack),
|
||||
// => Some(VirtualKeyCode::NoConvert),
|
||||
keysyms::XKB_KEY_KP_Separator => Some(VirtualKeyCode::NumpadComma),
|
||||
keysyms::XKB_KEY_KP_Enter => Some(VirtualKeyCode::NumpadEnter),
|
||||
keysyms::XKB_KEY_KP_Equal => Some(VirtualKeyCode::NumpadEquals),
|
||||
// => Some(VirtualKeyCode::OEM102),
|
||||
// => Some(VirtualKeyCode::Period),
|
||||
// => Some(VirtualKeyCode::Playpause),
|
||||
// => Some(VirtualKeyCode::Power),
|
||||
// => Some(VirtualKeyCode::Prevtrack),
|
||||
keysyms::XKB_KEY_Alt_R => Some(VirtualKeyCode::RAlt),
|
||||
// => Some(VirtualKeyCode::RBracket),
|
||||
keysyms::XKB_KEY_Control_R => Some(VirtualKeyCode::RControl),
|
||||
// => Some(VirtualKeyCode::RMenu),
|
||||
keysyms::XKB_KEY_Shift_R => Some(VirtualKeyCode::RShift),
|
||||
// => Some(VirtualKeyCode::RWin),
|
||||
keysyms::XKB_KEY_semicolon => Some(VirtualKeyCode::Semicolon),
|
||||
keysyms::XKB_KEY_slash => Some(VirtualKeyCode::Slash),
|
||||
// => Some(VirtualKeyCode::Sleep),
|
||||
// => Some(VirtualKeyCode::Stop),
|
||||
// => Some(VirtualKeyCode::Subtract),
|
||||
// => Some(VirtualKeyCode::Sysrq),
|
||||
keysyms::XKB_KEY_Tab => Some(VirtualKeyCode::Tab),
|
||||
// => Some(VirtualKeyCode::Underline),
|
||||
// => Some(VirtualKeyCode::Unlabeled),
|
||||
keysyms::XKB_KEY_XF86AudioLowerVolume => Some(VirtualKeyCode::VolumeDown),
|
||||
keysyms::XKB_KEY_XF86AudioRaiseVolume => Some(VirtualKeyCode::VolumeUp),
|
||||
// => Some(VirtualKeyCode::Wake),
|
||||
// => Some(VirtualKeyCode::Webback),
|
||||
// => Some(VirtualKeyCode::WebFavorites),
|
||||
// => Some(VirtualKeyCode::WebForward),
|
||||
// => Some(VirtualKeyCode::WebHome),
|
||||
// => Some(VirtualKeyCode::WebRefresh),
|
||||
// => Some(VirtualKeyCode::WebSearch),
|
||||
// => Some(VirtualKeyCode::WebStop),
|
||||
// => Some(VirtualKeyCode::Yen),
|
||||
// fallback
|
||||
_ => None
|
||||
}
|
||||
}
|
|
@ -1,17 +1,6 @@
|
|||
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"))]
|
||||
#![allow(unused_variables, dead_code)]
|
||||
|
||||
use self::wayland::egl::{EGLSurface, is_egl_available};
|
||||
use self::wayland::core::Surface;
|
||||
use self::wayland::core::output::Output;
|
||||
use self::wayland::core::shell::{ShellSurface, ShellFullscreenMethod};
|
||||
|
||||
use self::wayland_window::{DecoratedSurface, SurfaceGuard, substract_borders};
|
||||
|
||||
use libc;
|
||||
use api::dlopen;
|
||||
use api::egl;
|
||||
use api::egl::Context as EglContext;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use ContextError;
|
||||
use CreationError;
|
||||
|
@ -24,187 +13,56 @@ use GlContext;
|
|||
use PixelFormatRequirements;
|
||||
use WindowAttributes;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::ffi::CString;
|
||||
|
||||
use api::egl::Context as EglContext;
|
||||
use libc;
|
||||
use platform::MonitorId as PlatformMonitorId;
|
||||
|
||||
use self::context::WaylandContext;
|
||||
|
||||
extern crate wayland_client as wayland;
|
||||
extern crate wayland_kbd;
|
||||
extern crate wayland_window;
|
||||
|
||||
mod context;
|
||||
mod keyboard;
|
||||
|
||||
lazy_static! {
|
||||
static ref WAYLAND_CONTEXT: Option<WaylandContext> = {
|
||||
WaylandContext::new()
|
||||
};
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_available() -> bool {
|
||||
WAYLAND_CONTEXT.is_some()
|
||||
}
|
||||
|
||||
enum ShellWindow {
|
||||
Plain(ShellSurface<EGLSurface>),
|
||||
Decorated(DecoratedSurface<EGLSurface>)
|
||||
}
|
||||
|
||||
impl ShellWindow {
|
||||
#[inline]
|
||||
fn get_shell(&mut self) -> ShellGuard {
|
||||
match self {
|
||||
&mut ShellWindow::Plain(ref mut s) => {
|
||||
ShellGuard::Plain(s)
|
||||
},
|
||||
&mut ShellWindow::Decorated(ref mut s) => {
|
||||
ShellGuard::Decorated(s.get_shell())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resize(&mut self, w: i32, h: i32, x: i32, y: i32) {
|
||||
match self {
|
||||
&mut ShellWindow::Plain(ref s) => s.resize(w, h, x, y),
|
||||
&mut ShellWindow::Decorated(ref mut s) => {
|
||||
s.resize(w, h);
|
||||
s.get_shell().resize(w, h, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_cfg_callback(&mut self, arc: Arc<Mutex<(i32, i32, bool)>>) {
|
||||
match self {
|
||||
&mut ShellWindow::Decorated(ref mut s) => {
|
||||
s.get_shell().set_configure_callback(move |_, w, h| {
|
||||
let (w, h) = substract_borders(w, h);
|
||||
let mut guard = arc.lock().unwrap();
|
||||
*guard = (w, h, true);
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ShellGuard<'a> {
|
||||
Plain(&'a mut ShellSurface<EGLSurface>),
|
||||
Decorated(SurfaceGuard<'a, EGLSurface>)
|
||||
}
|
||||
|
||||
impl<'a> Deref for ShellGuard<'a> {
|
||||
type Target = ShellSurface<EGLSurface>;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &ShellSurface<EGLSurface> {
|
||||
match self {
|
||||
&ShellGuard::Plain(ref s) => s,
|
||||
&ShellGuard::Decorated(ref s) => s.deref()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DerefMut for ShellGuard<'a> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut ShellSurface<EGLSurface> {
|
||||
match self {
|
||||
&mut ShellGuard::Plain(ref mut s) => s,
|
||||
&mut ShellGuard::Decorated(ref mut s) => s.deref_mut()
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub struct Window {
|
||||
shell_window: Mutex<ShellWindow>,
|
||||
pending_events: Arc<Mutex<VecDeque<Event>>>,
|
||||
need_resize: Arc<Mutex<(i32, i32, bool)>>,
|
||||
resize_callback: Option<fn(u32, u32)>,
|
||||
pub context: EglContext,
|
||||
}
|
||||
|
||||
// private methods of wayalnd windows
|
||||
|
||||
impl Window {
|
||||
fn resize_if_needed(&self) -> bool {
|
||||
let mut guard = self.need_resize.lock().unwrap();
|
||||
let (w, h, b) = *guard;
|
||||
*guard = (0, 0, false);
|
||||
if b {
|
||||
let mut guard = self.shell_window.lock().unwrap();
|
||||
guard.resize(w, h, 0, 0);
|
||||
if let Some(f) = self.resize_callback {
|
||||
f(w as u32, h as u32);
|
||||
}
|
||||
if let Some(ref ctxt) = *WAYLAND_CONTEXT {
|
||||
let mut window_guard = self.shell_window.lock().unwrap();
|
||||
ctxt.push_event_for(
|
||||
window_guard.get_shell().get_wsurface().get_id(),
|
||||
Event::Resized(w as u32, h as u32)
|
||||
);
|
||||
}
|
||||
}
|
||||
b
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WindowProxy;
|
||||
|
||||
impl WindowProxy {
|
||||
#[inline]
|
||||
pub fn wakeup_event_loop(&self) {
|
||||
if let Some(ref ctxt) = *WAYLAND_CONTEXT {
|
||||
ctxt.display.sync();
|
||||
}
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MonitorId {
|
||||
output: Arc<Output>
|
||||
}
|
||||
pub struct MonitorId;
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors() -> VecDeque<MonitorId> {
|
||||
WAYLAND_CONTEXT.as_ref().unwrap().outputs.iter().map(|o| MonitorId::new(o.clone())).collect()
|
||||
unimplemented!()
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_primary_monitor() -> MonitorId {
|
||||
match WAYLAND_CONTEXT.as_ref().unwrap().outputs.iter().next() {
|
||||
Some(o) => MonitorId::new(o.clone()),
|
||||
None => panic!("No monitor is available.")
|
||||
}
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
impl MonitorId {
|
||||
fn new(output: Arc<Output>) -> MonitorId {
|
||||
MonitorId {
|
||||
output: output
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> Option<String> {
|
||||
Some(format!("{} - {}", self.output.manufacturer(), self.output.model()))
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_native_identifier(&self) -> ::native_monitor::NativeMonitorId {
|
||||
::native_monitor::NativeMonitorId::Unavailable
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn get_dimensions(&self) -> (u32, u32) {
|
||||
let (w, h) = self.output.modes()
|
||||
.into_iter()
|
||||
.find(|m| m.is_current())
|
||||
.map(|m| (m.width, m.height))
|
||||
.unwrap();
|
||||
(w as u32, h as u32)
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,14 +75,7 @@ impl<'a> Iterator for PollEventsIterator<'a> {
|
|||
type Item = Event;
|
||||
|
||||
fn next(&mut self) -> Option<Event> {
|
||||
if let Some(ref ctxt) = *WAYLAND_CONTEXT {
|
||||
ctxt.display.dispatch_pending();
|
||||
}
|
||||
if self.window.resize_if_needed() {
|
||||
Some(Event::Refresh)
|
||||
} else {
|
||||
self.window.pending_events.lock().unwrap().pop_front()
|
||||
}
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,18 +87,7 @@ impl<'a> Iterator for WaitEventsIterator<'a> {
|
|||
type Item = Event;
|
||||
|
||||
fn next(&mut self) -> Option<Event> {
|
||||
let mut evt = None;
|
||||
while evt.is_none() {
|
||||
if let Some(ref ctxt) = *WAYLAND_CONTEXT {
|
||||
ctxt.display.dispatch();
|
||||
}
|
||||
evt = if self.window.resize_if_needed() {
|
||||
Some(Event::Refresh)
|
||||
} else {
|
||||
self.window.pending_events.lock().unwrap().pop_front()
|
||||
};
|
||||
}
|
||||
evt
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,140 +95,49 @@ impl Window {
|
|||
pub fn new(window: &WindowAttributes, pf_reqs: &PixelFormatRequirements,
|
||||
opengl: &GlAttributes<&Window>) -> Result<Window, CreationError>
|
||||
{
|
||||
use self::wayland::internals::FFI;
|
||||
|
||||
// not implemented
|
||||
assert!(window.min_dimensions.is_none());
|
||||
assert!(window.max_dimensions.is_none());
|
||||
|
||||
let wayland_context = match *WAYLAND_CONTEXT {
|
||||
Some(ref c) => c,
|
||||
None => return Err(CreationError::NotSupported),
|
||||
};
|
||||
|
||||
if !is_egl_available() { return Err(CreationError::NotSupported) }
|
||||
|
||||
let (w, h) = window.dimensions.unwrap_or((800, 600));
|
||||
|
||||
let surface = EGLSurface::new(
|
||||
wayland_context.compositor.create_surface(),
|
||||
w as i32,
|
||||
h as i32
|
||||
);
|
||||
|
||||
let mut shell_window = if let Some(PlatformMonitorId::Wayland(ref monitor)) = window.monitor {
|
||||
let shell_surface = wayland_context.shell.get_shell_surface(surface);
|
||||
shell_surface.set_fullscreen(ShellFullscreenMethod::Default, Some(&monitor.output));
|
||||
ShellWindow::Plain(shell_surface)
|
||||
} else {
|
||||
if window.decorations {
|
||||
ShellWindow::Decorated(match DecoratedSurface::new(
|
||||
surface,
|
||||
w as i32,
|
||||
h as i32,
|
||||
&wayland_context.registry,
|
||||
Some(&wayland_context.seat)
|
||||
) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return Err(CreationError::NotSupported)
|
||||
})
|
||||
} else {
|
||||
ShellWindow::Plain(wayland_context.shell.get_shell_surface(surface))
|
||||
}
|
||||
};
|
||||
|
||||
let context = {
|
||||
let libegl = unsafe { dlopen::dlopen(b"libEGL.so\0".as_ptr() as *const _, dlopen::RTLD_NOW) };
|
||||
if libegl.is_null() {
|
||||
return Err(CreationError::NotSupported);
|
||||
}
|
||||
let egl = ::api::egl::ffi::egl::Egl::load_with(|sym| {
|
||||
let sym = CString::new(sym).unwrap();
|
||||
unsafe { dlopen::dlsym(libegl, sym.as_ptr()) }
|
||||
});
|
||||
try!(EglContext::new(
|
||||
egl,
|
||||
pf_reqs, &opengl.clone().map_sharing(|_| unimplemented!()), // TODO:
|
||||
egl::NativeDisplay::Wayland(Some(wayland_context.display.ptr() as *const _)))
|
||||
.and_then(|p| p.finish((**shell_window.get_shell()).ptr() as *const _))
|
||||
)
|
||||
};
|
||||
|
||||
// create a queue already containing a refresh event to trigger first draw
|
||||
// it's harmless and a removes the need to do a first swap_buffers() before
|
||||
// starting the event loop
|
||||
let events = Arc::new(Mutex::new({
|
||||
let mut v = VecDeque::new();
|
||||
v.push_back(Event::Refresh);
|
||||
v
|
||||
}));
|
||||
|
||||
wayland_context.register_surface(shell_window.get_shell().get_wsurface().get_id(),
|
||||
events.clone());
|
||||
|
||||
let need_resize = Arc::new(Mutex::new((0, 0, false)));
|
||||
|
||||
shell_window.set_cfg_callback(need_resize.clone());
|
||||
|
||||
wayland_context.display.flush().unwrap();
|
||||
|
||||
Ok(Window {
|
||||
shell_window: Mutex::new(shell_window),
|
||||
pending_events: events,
|
||||
need_resize: need_resize,
|
||||
resize_callback: None,
|
||||
context: context
|
||||
})
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn set_title(&self, title: &str) {
|
||||
let ctitle = CString::new(title).unwrap();
|
||||
// intermediate variable is forced,
|
||||
// see https://github.com/rust-lang/rust/issues/22921
|
||||
let mut guard = self.shell_window.lock().unwrap();
|
||||
guard.get_shell().set_title(&ctitle);
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show(&self) {
|
||||
// TODO
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide(&self) {
|
||||
// TODO
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> Option<(i32, i32)> {
|
||||
// not available with wayland
|
||||
None
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_position(&self, _x: i32, _y: i32) {
|
||||
// not available with wayland
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn get_inner_size(&self) -> Option<(u32, u32)> {
|
||||
// intermediate variables are forced,
|
||||
// see https://github.com/rust-lang/rust/issues/22921
|
||||
let mut guard = self.shell_window.lock().unwrap();
|
||||
let shell = guard.get_shell();
|
||||
let (w, h) = shell.get_attached_size();
|
||||
Some((w as u32, h as u32))
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_outer_size(&self) -> Option<(u32, u32)> {
|
||||
// maybe available if we draw the border ourselves ?
|
||||
// but for now, no.
|
||||
None
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_inner_size(&self, x: u32, y: u32) {
|
||||
self.shell_window.lock().unwrap().resize(x as i32, y as i32, 0, 0)
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -412,18 +161,17 @@ impl Window {
|
|||
|
||||
#[inline]
|
||||
pub fn set_window_resize_callback(&mut self, callback: Option<fn(u32, u32)>) {
|
||||
self.resize_callback = callback;
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
||||
// TODO
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
|
||||
// TODO
|
||||
Ok(())
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -433,8 +181,7 @@ impl Window {
|
|||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
|
||||
// TODO
|
||||
Ok(())
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -479,17 +226,3 @@ impl GlContext for Window {
|
|||
self.context.get_pixel_format().clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Window {
|
||||
fn drop(&mut self) {
|
||||
if let Some(ref ctxt) = *WAYLAND_CONTEXT {
|
||||
// intermediate variable is forced,
|
||||
// see https://github.com/rust-lang/rust/issues/22921
|
||||
let mut guard = self.shell_window.lock().unwrap();
|
||||
let shell = guard.get_shell();
|
||||
ctxt.deregister_surface(
|
||||
shell.get_wsurface().get_id()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,9 @@ extern crate core_foundation;
|
|||
extern crate core_graphics;
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly"))]
|
||||
extern crate x11_dl;
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[macro_use(wayland_env)]
|
||||
extern crate wayland_client;
|
||||
|
||||
pub use events::*;
|
||||
pub use headless::{HeadlessRendererBuilder, HeadlessContext};
|
||||
|
|
Loading…
Reference in a new issue