wayland: remove old code for new backend

This commit is contained in:
Victor Berger 2016-10-07 19:52:19 +02:00
parent fdf8a21125
commit c991172a28
9 changed files with 83 additions and 834 deletions

View file

@ -39,7 +39,7 @@ kernel32-sys = "0.2"
dwmapi-sys = "0.1" dwmapi-sys = "0.1"
[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))'.dependencies] [target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))'.dependencies]
wayland-client = { version = "0.5.4", features = ["dlopen"] } wayland-client = { version = "0.7.1", features = ["dlopen"] }
wayland-kbd = "0.3.3" wayland-kbd = "0.6"
wayland-window = "0.2.2" wayland-window = "0.4"
x11-dl = "2.8" x11-dl = "2.8"

View file

@ -1,211 +1,46 @@
use Event as GlutinEvent; use std::collections::VecDeque;
use std::collections::{HashMap, VecDeque, HashSet}; use wayland_client::protocol::{wl_compositor, wl_seat, wl_shell, wl_shm, wl_subcompositor};
use std::sync::{Arc, Mutex};
use libc::c_void;
use wayland_client::{EventIterator, Proxy, ProxyId};
use wayland_client::wayland::get_display;
use wayland_client::wayland::compositor::{WlCompositor, WlSurface};
use wayland_client::wayland::output::WlOutput;
use wayland_client::wayland::seat::{WlSeat, WlPointer};
use wayland_client::wayland::shell::{WlShell, WlShellSurface};
use wayland_client::wayland::shm::WlShm;
use wayland_client::wayland::subcompositor::WlSubcompositor;
use super::wayland_kbd::MappedKeyboard;
use super::wayland_window::DecoratedSurface;
lazy_static! {
pub static ref WAYLAND_CONTEXT: Option<WaylandContext> = {
WaylandContext::init()
};
}
wayland_env!(InnerEnv, wayland_env!(InnerEnv,
compositor: WlCompositor, compositor: wl_compositor::WlCompositor,
seat: WlSeat, seat: wl_seat::WlSeat,
shell: WlShell, shell: wl_shell::WlShell,
shm: WlShm, shm: wl_shm::WlShm,
subcompositor: WlSubcompositor subcompositor: wl_subcompositor::WlSubcompositor
); );
pub struct WaylandFocuses {
pub pointer: Option<WlPointer>,
pub pointer_on: Option<ProxyId>,
pub pointer_at: Option<(f64, f64)>,
pub keyboard: Option<MappedKeyboard>,
pub keyboard_on: Option<ProxyId>
}
pub struct WaylandContext { pub struct WaylandContext {
inner: InnerEnv,
iterator: Mutex<EventIterator>,
monitors: Vec<(WlOutput, u32, u32, String)>,
queues: Mutex<HashMap<ProxyId, Arc<Mutex<VecDeque<GlutinEvent>>>>>,
known_surfaces: Mutex<HashSet<ProxyId>>,
focuses: Mutex<WaylandFocuses>
} }
impl WaylandContext { impl WaylandContext {
fn init() -> Option<WaylandContext> { pub fn init() -> Option<WaylandContext> {
let display = match get_display() {
Some(display) => display,
None => return None
};
let (mut inner_env, iterator) = InnerEnv::init(display);
let outputs_events = EventIterator::new();
let mut monitors = inner_env.globals.iter()
.flat_map(|&(id, _, _)| inner_env.rebind_id::<WlOutput>(id))
.map(|(mut monitor, _)| {
monitor.set_evt_iterator(&outputs_events);
(monitor, 0, 0, String::new())
}).collect();
inner_env.display.sync_roundtrip().unwrap();
super::monitor::init_monitors(&mut monitors, outputs_events);
Some(WaylandContext {
inner: inner_env,
iterator: Mutex::new(iterator),
monitors: monitors,
queues: Mutex::new(HashMap::new()),
known_surfaces: Mutex::new(HashSet::new()),
focuses: Mutex::new(WaylandFocuses {
pointer: None,
pointer_on: None,
pointer_at: None,
keyboard: None,
keyboard_on: None
})
})
}
pub fn new_surface(&self) -> Option<(WlSurface, Arc<Mutex<VecDeque<GlutinEvent>>>)> {
self.inner.compositor.as_ref().map(|c| {
let s = c.0.create_surface();
let id = s.id();
let queue = {
let mut q = VecDeque::new();
q.push_back(GlutinEvent::Refresh);
Arc::new(Mutex::new(q))
};
self.queues.lock().unwrap().insert(id, queue.clone());
self.known_surfaces.lock().unwrap().insert(id);
(s, queue)
})
}
pub fn dropped_surface(&self, id: ProxyId) {
self.queues.lock().unwrap().remove(&id);
self.known_surfaces.lock().unwrap().remove(&id);
}
pub fn decorated_from(&self, surface: &WlSurface, width: i32, height: i32) -> Option<DecoratedSurface> {
let inner = &self.inner;
match (&inner.compositor, &inner.subcompositor, &inner.shm, &inner.shell) {
(&Some(ref compositor), &Some(ref subcompositor), &Some(ref shm), &Some(ref shell)) => {
DecoratedSurface::new(
surface, width, height,
&compositor.0, &subcompositor.0, &shm.0, &shell.0,
self.inner.rebind::<WlSeat>().map(|(seat, _)| seat)
).ok()
}
_ => None
}
}
pub fn plain_from(&self, surface: &WlSurface, fullscreen: Option<ProxyId>) -> Option<WlShellSurface> {
use wayland_client::wayland::shell::WlShellSurfaceFullscreenMethod;
let inner = &self.inner;
if let Some((ref shell, _)) = inner.shell {
let shell_surface = shell.get_shell_surface(surface);
if let Some(monitor_id) = fullscreen {
for m in &self.monitors {
if m.0.id() == monitor_id {
shell_surface.set_fullscreen(
WlShellSurfaceFullscreenMethod::Default,
0,
Some(&m.0)
);
return Some(shell_surface)
}
}
}
shell_surface.set_toplevel();
Some(shell_surface)
} else {
None
}
}
pub fn display_ptr(&self) -> *const c_void {
self.inner.display.ptr() as *const _
}
pub fn dispatch_events(&self) {
self.inner.display.dispatch_pending().unwrap();
let mut iterator = self.iterator.lock().unwrap();
let mut focuses = self.focuses.lock().unwrap();
let known_surfaces = self.known_surfaces.lock().unwrap();
let queues = self.queues.lock().unwrap();
// first, keyboard events
let kdb_evts = super::keyboard::translate_kbd_events(&mut *focuses, &known_surfaces);
for (evt, id) in kdb_evts {
if let Some(q) = queues.get(&id) {
q.lock().unwrap().push_back(evt);
}
}
// then, the rest
for evt in &mut *iterator {
if let Some((evt, id)) = super::events::translate_event(
evt, &mut *focuses, &known_surfaces,
self.inner.seat.as_ref().map(|s| &s.0))
{
if let Some(q) = queues.get(&id) {
q.lock().unwrap().push_back(evt);
}
}
}
}
pub fn flush_events(&self) -> ::std::io::Result<i32> {
self.inner.display.flush()
}
pub fn read_events(&self) -> ::std::io::Result<Option<i32>> {
let guard = match self.inner.display.prepare_read() {
Some(g) => g,
None => return Ok(None)
};
return guard.read_events().map(|i| Some(i));
}
pub fn monitor_ids(&self) -> Vec<ProxyId> {
self.monitors.iter().map(|o| o.0.id()).collect()
}
pub fn monitor_name(&self, pid: ProxyId) -> Option<String> {
for o in &self.monitors {
if o.0.id() == pid {
return Some(o.3.clone())
}
}
None None
} }
pub fn monitor_dimensions(&self, pid: ProxyId) -> Option<(u32, u32)> { pub fn get_primary_monitor(&self) -> MonitorId {
for o in &self.monitors { unimplemented!()
if o.0.id() == pid { }
return Some((o.1, o.2))
} pub fn get_available_monitors(&self) -> VecDeque<MonitorId> {
} unimplemented!()
None }
}
#[derive(Clone)]
pub struct MonitorId;
impl MonitorId {
pub fn get_name(&self) -> Option<String> {
unimplemented!()
}
#[inline]
pub fn get_native_identifier(&self) -> ::native_monitor::NativeMonitorId {
::native_monitor::NativeMonitorId::Unavailable
}
pub fn get_dimensions(&self) -> (u32, u32) {
unimplemented!()
} }
} }

View file

@ -1,112 +0,0 @@
use std::collections::HashSet;
use TouchPhase;
use Event as GlutinEvent;
use ElementState;
use MouseButton;
use MouseScrollDelta;
use wayland_client::Event as WaylandEvent;
use wayland_client::ProxyId;
use wayland_client::wayland::WaylandProtocolEvent as WPE;
use wayland_client::wayland::seat::{WlSeat, WlSeatEvent, WlPointerEvent,
WlPointerButtonState,
WlPointerAxis, WlSeatCapability};
use super::wayland_kbd::MappedKeyboard;
use super::context::WaylandFocuses;
pub fn translate_event(
evt: WaylandEvent,
focuses: &mut WaylandFocuses,
known_surfaces: &HashSet<ProxyId>,
seat: Option<&WlSeat>,
) -> Option<(GlutinEvent, ProxyId)>
{
let WaylandEvent::Wayland(wayland_evt) = evt;
match wayland_evt {
WPE::WlSeat(_, seat_evt) => match seat_evt {
WlSeatEvent::Capabilities(cap) => {
if cap.contains(WlSeatCapability::Pointer) && focuses.pointer.is_none() {
if let Some(seat) = seat {
focuses.pointer = Some(seat.get_pointer());
}
}
if cap.contains(WlSeatCapability::Keyboard) && focuses.keyboard.is_none() {
if let Some(seat) = seat {
match MappedKeyboard::new(seat) {
Ok(mk) => {
focuses.keyboard = Some(mk)
},
Err(_) => {}
}
}
}
None
},
_ => None
},
WPE::WlPointer(_, pointer_evt) => match pointer_evt {
WlPointerEvent::Enter(_, surface, x, y) => {
if known_surfaces.contains(&surface) {
focuses.pointer_on = Some(surface);
focuses.pointer_at = Some((x, y));
Some((GlutinEvent::MouseMoved(x as i32, y as i32), surface))
} else {
None
}
}
WlPointerEvent::Leave(_, _) => {
focuses.pointer_on = None;
focuses.pointer_at = None;
None
}
WlPointerEvent::Motion(_, x, y) => {
if let Some(surface) = focuses.pointer_on {
focuses.pointer_at = Some((x, y));
Some((GlutinEvent::MouseMoved(x as i32, y as i32), surface))
} else {
None
}
}
WlPointerEvent::Button(_, _, button, state) => {
if let Some(surface) = focuses.pointer_on {
Some((GlutinEvent::MouseInput(
match state {
WlPointerButtonState::Pressed => ElementState::Pressed,
WlPointerButtonState::Released => ElementState::Released
},
match button {
0x110 => MouseButton::Left,
0x111 => MouseButton::Right,
0x112 => MouseButton::Middle,
// TODO figure out the translation ?
_ => return None
}
), surface))
} else {
None
}
}
WlPointerEvent::Axis(_, axis, amplitude) => {
if let Some(surface) = focuses.pointer_on {
Some((GlutinEvent::MouseWheel(
match axis {
WlPointerAxis::VerticalScroll => {
MouseScrollDelta::PixelDelta(amplitude as f32, 0.0)
}
WlPointerAxis::HorizontalScroll => {
MouseScrollDelta::PixelDelta(0.0, amplitude as f32)
}
},
TouchPhase::Moved
), surface))
} else {
None
}
}
},
_ => None
}
}

View file

@ -1,229 +0,0 @@
use std::collections::HashSet;
use Event as GlutinEvent;
use ElementState;
use VirtualKeyCode;
use wayland_client::ProxyId;
use wayland_client::wayland::seat::{WlKeyboardEvent,WlKeyboardKeyState};
use super::wayland_kbd::MappedKeyboardEvent;
use super::context::WaylandFocuses;
pub fn translate_kbd_events(
focuses: &mut WaylandFocuses,
known_surfaces: &HashSet<ProxyId>,
) -> Vec<(GlutinEvent, ProxyId)> {
let mut out = Vec::new();
if let Some(mkbd) = focuses.keyboard.as_mut() {
for evt in mkbd {
match evt {
MappedKeyboardEvent::KeyEvent(kevt) => {
if let Some(surface) = focuses.keyboard_on {
let vkcode = match kevt.keycode {
1 => Some(VirtualKeyCode::Escape),
2 => Some(VirtualKeyCode::Key1),
3 => Some(VirtualKeyCode::Key2),
4 => Some(VirtualKeyCode::Key3),
5 => Some(VirtualKeyCode::Key4),
6 => Some(VirtualKeyCode::Key5),
7 => Some(VirtualKeyCode::Key6),
8 => Some(VirtualKeyCode::Key7),
9 => Some(VirtualKeyCode::Key8),
10 => Some(VirtualKeyCode::Key9),
11 => Some(VirtualKeyCode::Key0),
_ => kevt.as_symbol().and_then(keysym_to_vkey)
};
let text = kevt.as_utf8();
out.push((
GlutinEvent::KeyboardInput(
match kevt.keystate {
WlKeyboardKeyState::Pressed => ElementState::Pressed,
WlKeyboardKeyState::Released =>ElementState::Released
},
(kevt.keycode & 0xff) as u8,
vkcode
),
surface
));
if let Some(c) = text.and_then(|s| s.chars().next()) {
out.push((
GlutinEvent::ReceivedCharacter(c),
surface
));
}
}
}
MappedKeyboardEvent::Other(oevt) => match oevt {
WlKeyboardEvent::Enter(_, surface, _) => {
if known_surfaces.contains(&surface) {
focuses.keyboard_on = Some(surface);
out.push((GlutinEvent::Focused(true), surface));
}
},
WlKeyboardEvent::Leave(_, surface) => {
if known_surfaces.contains(&surface) {
focuses.keyboard_on = None;
out.push((GlutinEvent::Focused(false), surface));
}
}
_ => {}
}
}
}
}
out
}
pub fn keysym_to_vkey(keysym: u32) -> Option<VirtualKeyCode> {
use super::wayland_kbd::keysyms;
match keysym {
// 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,18 +1,10 @@
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))] #![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
pub use self::monitor::{MonitorId, get_available_monitors, get_primary_monitor};
pub use self::window::{PollEventsIterator, WaitEventsIterator, Window, WindowProxy}; pub use self::window::{PollEventsIterator, WaitEventsIterator, Window, WindowProxy};
pub use self::context::{WaylandContext,MonitorId};
extern crate wayland_kbd; extern crate wayland_kbd;
extern crate wayland_window; extern crate wayland_window;
mod context; mod context;
mod events;
mod keyboard;
mod monitor;
mod window; mod window;
#[inline]
pub fn is_available() -> bool {
context::WAYLAND_CONTEXT.is_some()
}

View file

@ -1,75 +0,0 @@
use std::collections::VecDeque;
use wayland_client::{ProxyId, EventIterator};
use wayland_client::wayland::output::WlOutput;
use super::context::WAYLAND_CONTEXT;
#[derive(Clone)]
pub struct MonitorId(ProxyId);
#[inline]
pub fn get_available_monitors() -> VecDeque<MonitorId> {
WAYLAND_CONTEXT.as_ref().map(|ctxt|
ctxt.monitor_ids().into_iter().map(MonitorId).collect()
).unwrap_or(VecDeque::new())
}
#[inline]
pub fn get_primary_monitor() -> MonitorId {
WAYLAND_CONTEXT.as_ref().and_then(|ctxt|
ctxt.monitor_ids().into_iter().next().map(MonitorId)
).expect("wayland: No monitor available.")
}
impl MonitorId {
pub fn get_name(&self) -> Option<String> {
WAYLAND_CONTEXT.as_ref().and_then(|ctxt| ctxt.monitor_name(self.0))
}
#[inline]
pub fn get_native_identifier(&self) -> ::native_monitor::NativeMonitorId {
::native_monitor::NativeMonitorId::Unavailable
}
pub fn get_dimensions(&self) -> (u32, u32) {
WAYLAND_CONTEXT.as_ref().and_then(|ctxt| ctxt.monitor_dimensions(self.0)).unwrap()
}
}
pub fn proxid_from_monitorid(x: &MonitorId) -> ProxyId {
x.0
}
pub fn init_monitors(outputs: &mut Vec<(WlOutput, u32, u32, String)>, evts: EventIterator) {
use wayland_client::{Event, Proxy};
use wayland_client::wayland::WaylandProtocolEvent;
use wayland_client::wayland::output::{WlOutputEvent, WlOutputMode};
for evt in evts {
match evt {
Event::Wayland(WaylandProtocolEvent::WlOutput(pid, oevt)) => match oevt {
WlOutputEvent::Geometry(_, _, _, _, _, maker, model, _) => {
for o in outputs.iter_mut() {
if o.0.id() == pid {
o.3 = format!("{} - {}", maker, model);
break
}
}
},
WlOutputEvent::Mode(flags, width, height, _) => {
if flags.contains(WlOutputMode::Current) {
for o in outputs.iter_mut() {
if o.0.id() == pid {
o.1 = width as u32;
o.2 = height as u32;
break
}
}
}
},
_ => {}
},
_ => {}
}
}
}

View file

@ -1,16 +1,10 @@
use std::collections::VecDeque; use std::sync::Arc;
use std::sync::{Arc, Mutex};
use libc; use wayland_client::protocol::{wl_display,wl_surface};
use {CreationError, CursorState, Event, MouseCursor, WindowAttributes}; use {CreationError, MouseCursor, CursorState, Event, WindowAttributes};
use platform::MonitorId as PlatformMonitorId;
use wayland_client::EventIterator; use super::WaylandContext;
use wayland_client::wayland::compositor::WlSurface;
use wayland_client::wayland::shell::WlShellSurface;
use super::wayland_window::{DecoratedSurface, add_borders, substract_borders};
use super::context::{WaylandContext, WAYLAND_CONTEXT};
#[derive(Clone)] #[derive(Clone)]
pub struct WindowProxy; pub struct WindowProxy;
@ -23,61 +17,7 @@ impl WindowProxy {
} }
pub struct Window { pub struct Window {
wayland_context: &'static WaylandContext, resize_callback: Option<fn(u32,u32)>
surface: WlSurface,
shell_window: Mutex<ShellWindow>,
evt_queue: Arc<Mutex<VecDeque<Event>>>,
inner_size: Mutex<(i32, i32)>,
resize_callback: Option<fn(u32, u32)>,
}
impl Window {
fn next_event(&self) -> Option<Event> {
use wayland_client::Event as WEvent;
use wayland_client::wayland::WaylandProtocolEvent;
use wayland_client::wayland::shell::WlShellSurfaceEvent;
let mut newsize = None;
let mut evt_queue_guard = self.evt_queue.lock().unwrap();
let mut shell_window_guard = self.shell_window.lock().unwrap();
match *shell_window_guard {
ShellWindow::Decorated(ref mut deco) => {
for (_, w, h) in deco {
newsize = Some((w, h));
}
},
ShellWindow::Plain(ref plain, ref mut evtiter) => {
for evt in evtiter {
if let WEvent::Wayland(WaylandProtocolEvent::WlShellSurface(_, ssevt)) = evt {
match ssevt {
WlShellSurfaceEvent::Ping(u) => {
plain.pong(u);
},
WlShellSurfaceEvent::Configure(_, w, h) => {
newsize = Some((w, h));
},
_ => {}
}
}
}
}
}
if let Some((w, h)) = newsize {
let (w, h) = substract_borders(w, h);
*self.inner_size.lock().unwrap() = (w, h);
if let ShellWindow::Decorated(ref mut deco) = *shell_window_guard {
deco.resize(w, h);
}
if let Some(f) = self.resize_callback {
f(w as u32, h as u32);
}
Some(Event::Resized(w as u32, h as u32))
} else {
evt_queue_guard.pop_front()
}
}
} }
pub struct PollEventsIterator<'a> { pub struct PollEventsIterator<'a> {
@ -88,13 +28,7 @@ impl<'a> Iterator for PollEventsIterator<'a> {
type Item = Event; type Item = Event;
fn next(&mut self) -> Option<Event> { fn next(&mut self) -> Option<Event> {
match self.window.next_event() { unimplemented!()
Some(evt) => return Some(evt),
None => {}
}
// the queue was empty, try a dispatch and see the result
self.window.wayland_context.dispatch_events();
return self.window.next_event();
} }
} }
@ -106,91 +40,18 @@ impl<'a> Iterator for WaitEventsIterator<'a> {
type Item = Event; type Item = Event;
fn next(&mut self) -> Option<Event> { fn next(&mut self) -> Option<Event> {
loop { unimplemented!()
match self.window.next_event() {
Some(evt) => return Some(evt),
None => {}
}
// the queue was empty, try a dispatch & read and see the result
self.window.wayland_context.flush_events().expect("Connexion with the wayland compositor lost.");
match self.window.wayland_context.read_events() {
Ok(_) => {
// events were read or dispatch is needed, in both cases, we dispatch
self.window.wayland_context.dispatch_events()
}
Err(_) => panic!("Connexion with the wayland compositor lost.")
}
}
} }
} }
enum ShellWindow {
Plain(WlShellSurface, EventIterator),
Decorated(DecoratedSurface)
}
impl Window { impl Window {
pub fn new(window: &WindowAttributes) -> Result<Window, CreationError> pub fn new(ctxt: Arc<WaylandContext>, attributes: &WindowAttributes) -> Result<Window, CreationError>
{ {
use wayland_client::Proxy; unimplemented!()
// 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),
};
let (w, h) = window.dimensions.unwrap_or((800, 600));
let (surface, evt_queue) = match wayland_context.new_surface() {
Some(t) => t,
None => return Err(CreationError::NotSupported)
};
let shell_window = if let Some(PlatformMonitorId::Wayland(ref monitor_id)) = window.monitor {
let pid = super::monitor::proxid_from_monitorid(monitor_id);
match wayland_context.plain_from(&surface, Some(pid)) {
Some(mut s) => {
let iter = EventIterator::new();
s.set_evt_iterator(&iter);
ShellWindow::Plain(s, iter)
},
None => return Err(CreationError::NotSupported)
}
} else if window.decorations {
match wayland_context.decorated_from(&surface, w as i32, h as i32) {
Some(s) => ShellWindow::Decorated(s),
None => return Err(CreationError::NotSupported)
}
} else {
match wayland_context.plain_from(&surface, None) {
Some(mut s) => {
let iter = EventIterator::new();
s.set_evt_iterator(&iter);
ShellWindow::Plain(s, iter)
},
None => return Err(CreationError::NotSupported)
}
};
Ok(Window {
wayland_context: wayland_context,
surface: surface,
shell_window: Mutex::new(shell_window),
evt_queue: evt_queue,
inner_size: Mutex::new((w as i32, h as i32)),
resize_callback: None,
})
} }
pub fn set_title(&self, title: &str) { pub fn set_title(&self, title: &str) {
let guard = self.shell_window.lock().unwrap(); // TODO
match *guard {
ShellWindow::Plain(ref plain, _) => { plain.set_title(title.into()); },
ShellWindow::Decorated(ref deco) => { deco.set_title(title.into()); }
}
} }
#[inline] #[inline]
@ -215,24 +76,19 @@ impl Window {
} }
pub fn get_inner_size(&self) -> Option<(u32, u32)> { pub fn get_inner_size(&self) -> Option<(u32, u32)> {
let (w, h) = *self.inner_size.lock().unwrap(); // TODO
Some((w as u32, h as u32)) None
} }
#[inline] #[inline]
pub fn get_outer_size(&self) -> Option<(u32, u32)> { pub fn get_outer_size(&self) -> Option<(u32, u32)> {
let (w, h) = *self.inner_size.lock().unwrap(); // TODO
let (w, h) = add_borders(w, h); None
Some((w as u32, h as u32))
} }
#[inline] #[inline]
pub fn set_inner_size(&self, x: u32, y: u32) { pub fn set_inner_size(&self, x: u32, y: u32) {
let mut guard = self.shell_window.lock().unwrap(); // TODO
match *guard {
ShellWindow::Decorated(ref mut deco) => { deco.resize(x as i32, y as i32); },
_ => {}
}
} }
#[inline] #[inline]
@ -277,6 +133,7 @@ impl Window {
#[inline] #[inline]
pub fn hidpi_factor(&self) -> f32 { pub fn hidpi_factor(&self) -> f32 {
// TODO
1.0 1.0
} }
@ -286,34 +143,17 @@ impl Window {
Err(()) Err(())
} }
#[inline] pub fn get_display(&self) -> &wl_display::WlDisplay {
pub fn get_wayland_display(&self) -> *mut libc::c_void { unimplemented!()
WAYLAND_CONTEXT.as_ref().unwrap() // context exists if window was created
.display_ptr() as *mut libc::c_void
} }
#[inline] pub fn get_surface(&self) -> &wl_surface::WlSurface {
pub fn get_wayland_surface(&self) -> *mut libc::c_void { unimplemented!()
use wayland_client::Proxy;
self.surface.ptr() as *mut libc::c_void
}
#[inline]
pub fn platform_display(&self) -> *mut libc::c_void {
WAYLAND_CONTEXT.as_ref().unwrap() // context exists if window was created
.display_ptr() as *mut libc::c_void
}
#[inline]
pub fn platform_window(&self) -> *mut libc::c_void {
use wayland_client::Proxy;
self.surface.ptr() as *mut libc::c_void
} }
} }
impl Drop for Window { impl Drop for Window {
fn drop(&mut self) { fn drop(&mut self) {
use wayland_client::Proxy; // TODO
self.wayland_context.dropped_surface(self.surface.id());
} }
} }

View file

@ -5,6 +5,9 @@ use Window;
use platform::Window as LinuxWindow; use platform::Window as LinuxWindow;
use WindowBuilder; use WindowBuilder;
use wayland_client::protocol::wl_display::WlDisplay;
use wayland_client::protocol::wl_surface::WlSurface;
/// Additional methods on `Window` that are specific to Unix. /// Additional methods on `Window` that are specific to Unix.
pub trait WindowExt { pub trait WindowExt {
/// Returns a pointer to the `Window` object of xlib that is used by this window. /// Returns a pointer to the `Window` object of xlib that is used by this window.
@ -29,19 +32,15 @@ pub trait WindowExt {
/// The pointer will become invalid when the glutin `Window` is destroyed. /// The pointer will become invalid when the glutin `Window` is destroyed.
fn get_xcb_connection(&self) -> Option<*mut libc::c_void>; fn get_xcb_connection(&self) -> Option<*mut libc::c_void>;
/// Returns a pointer to the `wl_surface` object of wayland that is used by this window. /// Returns a reference to the `WlSurface` object of wayland that is used by this window.
/// ///
/// Returns `None` if the window doesn't use wayland (if it uses xlib for example). /// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
/// fn get_wayland_surface(&self) -> Option<&WlSurface>;
/// The pointer will become invalid when the glutin `Window` is destroyed.
fn get_wayland_surface(&self) -> Option<*mut libc::c_void>;
/// Returns a pointer to the `wl_display` object of wayland that is used by this window. /// Returns a pointer to the `WlDisplay` object of wayland that is used by this window.
/// ///
/// Returns `None` if the window doesn't use wayland (if it uses xlib for example). /// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
/// fn get_wayland_display(&self) -> Option<&WlDisplay>;
/// The pointer will become invalid when the glutin `Window` is destroyed.
fn get_wayland_display(&self) -> Option<*mut libc::c_void>;
} }
impl WindowExt for Window { impl WindowExt for Window {
@ -69,17 +68,17 @@ impl WindowExt for Window {
} }
#[inline] #[inline]
fn get_wayland_surface(&self) -> Option<*mut libc::c_void> { fn get_wayland_surface(&self) -> Option<&WlSurface> {
match self.window { match self.window {
LinuxWindow::Wayland(ref w) => Some(w.get_wayland_surface()), LinuxWindow::Wayland(ref w) => Some(w.get_surface()),
_ => None _ => None
} }
} }
#[inline] #[inline]
fn get_wayland_display(&self) -> Option<*mut libc::c_void> { fn get_wayland_display(&self) -> Option<&WlDisplay> {
match self.window { match self.window {
LinuxWindow::Wayland(ref w) => Some(w.get_wayland_display()), LinuxWindow::Wayland(ref w) => Some(w.get_display()),
_ => None _ => None
} }
} }

View file

@ -1,6 +1,3 @@
/*pub use api::x11::{Window, WindowProxy, MonitorId, get_available_monitors, get_primary_monitor};
pub use api::x11::{WaitEventsIterator, PollEventsIterator};*/
use std::collections::VecDeque; use std::collections::VecDeque;
use std::sync::Arc; use std::sync::Arc;
@ -22,15 +19,15 @@ pub struct PlatformSpecificWindowBuilderAttributes;
enum Backend { enum Backend {
X(Arc<XConnection>), X(Arc<XConnection>),
Wayland, Wayland(Arc<wayland::WaylandContext>),
Error(XNotSupported), Error(XNotSupported),
} }
lazy_static!( lazy_static!(
static ref BACKEND: Backend = { static ref BACKEND: Backend = {
// Wayland backend is not production-ready yet so we disable it // Wayland backend is not production-ready yet so we disable it
if wayland::is_available() { if let Some(ctxt) = wayland::WaylandContext::init() {
Backend::Wayland Backend::Wayland(Arc::new(ctxt))
} else { } else {
match XConnection::new(Some(x_error_callback)) { match XConnection::new(Some(x_error_callback)) {
Ok(x) => Backend::X(Arc::new(x)), Ok(x) => Backend::X(Arc::new(x)),
@ -78,7 +75,7 @@ pub enum MonitorId {
#[inline] #[inline]
pub fn get_available_monitors() -> VecDeque<MonitorId> { pub fn get_available_monitors() -> VecDeque<MonitorId> {
match *BACKEND { match *BACKEND {
Backend::Wayland => wayland::get_available_monitors() Backend::Wayland(ref ctxt) => ctxt.get_available_monitors()
.into_iter() .into_iter()
.map(MonitorId::Wayland) .map(MonitorId::Wayland)
.collect(), .collect(),
@ -93,7 +90,7 @@ pub fn get_available_monitors() -> VecDeque<MonitorId> {
#[inline] #[inline]
pub fn get_primary_monitor() -> MonitorId { pub fn get_primary_monitor() -> MonitorId {
match *BACKEND { match *BACKEND {
Backend::Wayland => MonitorId::Wayland(wayland::get_primary_monitor()), Backend::Wayland(ref ctxt) => MonitorId::Wayland(ctxt.get_primary_monitor()),
Backend::X(ref connec) => MonitorId::X(x11::get_primary_monitor(connec)), Backend::X(ref connec) => MonitorId::X(x11::get_primary_monitor(connec)),
Backend::Error(_) => MonitorId::None, Backend::Error(_) => MonitorId::None,
} }
@ -173,8 +170,8 @@ impl Window {
-> Result<Window, CreationError> -> Result<Window, CreationError>
{ {
match *BACKEND { match *BACKEND {
Backend::Wayland => { Backend::Wayland(ref ctxt) => {
wayland::Window::new(window).map(Window::Wayland) wayland::Window::new(ctxt.clone(), window).map(Window::Wayland)
}, },
Backend::X(ref connec) => { Backend::X(ref connec) => {
@ -318,17 +315,19 @@ impl Window {
#[inline] #[inline]
pub fn platform_display(&self) -> *mut libc::c_void { pub fn platform_display(&self) -> *mut libc::c_void {
use wayland_client::Proxy;
match self { match self {
&Window::X(ref w) => w.platform_display(), &Window::X(ref w) => w.platform_display(),
&Window::Wayland(ref w) => w.platform_display() &Window::Wayland(ref w) => w.get_display().ptr() as *mut _
} }
} }
#[inline] #[inline]
pub fn platform_window(&self) -> *mut libc::c_void { pub fn platform_window(&self) -> *mut libc::c_void {
use wayland_client::Proxy;
match self { match self {
&Window::X(ref w) => w.platform_window(), &Window::X(ref w) => w.platform_window(),
&Window::Wayland(ref w) => w.platform_window() &Window::Wayland(ref w) => w.get_surface().ptr() as *mut _
} }
} }
} }