api/wayland: Reset to empty API.

In order to build the whole new structure.
This commit is contained in:
Victor Berger 2015-12-04 20:39:52 +01:00
parent ae7638b995
commit fad2e77a36
5 changed files with 47 additions and 709 deletions

View file

@ -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"

View file

@ -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);
}
}
}

View file

@ -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
}
}

View file

@ -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()
)
}
}
}

View file

@ -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};