diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/api/glx/mod.rs | 11 | ||||
| -rw-r--r-- | src/api/wayland/mod.rs | 4 | ||||
| -rw-r--r-- | src/api/x11/mod.rs | 12 | ||||
| -rw-r--r-- | src/platform/linux/api_dispatch.rs | 324 | ||||
| -rw-r--r-- | src/platform/linux/mod.rs | 6 | 
5 files changed, 347 insertions, 10 deletions
| diff --git a/src/api/glx/mod.rs b/src/api/glx/mod.rs index 9cda90e..3c0c8a0 100644 --- a/src/api/glx/mod.rs +++ b/src/api/glx/mod.rs @@ -14,6 +14,8 @@ use std::{mem, ptr};  use api::x11::ffi; +use platform::Window as PlatformWindow; +  pub struct Context {      glx: ffi::glx::Glx,      display: *mut ffi::Display, @@ -80,9 +82,12 @@ impl Context {              });              let share = if let Some(win) = builder.sharing { -                match win.x.context { -                    ::api::x11::Context::Glx(ref c) => c.context, -                    _ => panic!("Cannot share contexts between different APIs") +                match win { +                    &PlatformWindow::X(ref win) => match win.x.context { +                        ::api::x11::Context::Glx(ref c) => c.context, +                        _ => panic!("Cannot share contexts between different APIs") +                    }, +                    _ => panic!("Cannot use glx on a non-X11 window.")                  }              } else {                  ptr::null() diff --git a/src/api/wayland/mod.rs b/src/api/wayland/mod.rs index f70d62e..4fd0357 100644 --- a/src/api/wayland/mod.rs +++ b/src/api/wayland/mod.rs @@ -147,6 +147,10 @@ lazy_static! {      };  } +pub fn is_available() -> bool { +    WAYLAND_CONTEXT.is_some() +} +  pub struct Window {      shell_surface: ShellSurface<EGLSurface>,      pending_events: Arc<Mutex<VecDeque<Event>>>, diff --git a/src/api/x11/mod.rs b/src/api/x11/mod.rs index 0dcf85b..30adadc 100644 --- a/src/api/x11/mod.rs +++ b/src/api/x11/mod.rs @@ -21,6 +21,8 @@ use api::dlopen;  use api::glx::Context as GlxContext;  use api::egl::Context as EglContext; +use platform::MonitorID as PlatformMonitorID; +  pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};  mod events; @@ -310,9 +312,9 @@ pub struct Window {  impl Window {      pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> { -        let xlib = ffi::Xlib::open().unwrap();        // FIXME: gracious handling -        let xcursor = ffi::Xcursor::open().unwrap();        // FIXME: gracious handling -        let xf86vmode = ffi::Xf86vmode::open().unwrap();        // FIXME: gracious handling +        let xlib = try!(ffi::Xlib::open().map_err(|_| CreationError::NotSupported)); +        let xcursor = try!(ffi::Xcursor::open().map_err(|_| CreationError::NotSupported)); +        let xf86vmode = try!(ffi::Xf86vmode::open().map_err(|_| CreationError::NotSupported));          let glx = {              let mut libglx = unsafe { dlopen::dlopen(b"libGL.so.1\0".as_ptr() as *const _, dlopen::RTLD_NOW) }; @@ -342,8 +344,8 @@ impl Window {          };          let screen_id = match builder.monitor { -            Some(MonitorID(monitor)) => monitor as i32, -            None => unsafe { (xlib.XDefaultScreen)(display) }, +            Some(PlatformMonitorID::X(MonitorID(monitor))) => monitor as i32, +            _ => unsafe { (xlib.XDefaultScreen)(display) },          };          // getting the FBConfig diff --git a/src/platform/linux/api_dispatch.rs b/src/platform/linux/api_dispatch.rs new file mode 100644 index 0000000..c77c464 --- /dev/null +++ b/src/platform/linux/api_dispatch.rs @@ -0,0 +1,324 @@ +/*#[cfg(feature = "window")] +pub use api::x11::{Window, WindowProxy, MonitorID, get_available_monitors, get_primary_monitor}; +#[cfg(feature = "window")] +pub use api::x11::{WaitEventsIterator, PollEventsIterator};*/ + +use std::collections::VecDeque; + +use BuilderAttribs; +use CreationError; +use CursorState; +use Event; +use GlContext; +use MouseCursor; +use PixelFormat; +use libc; + +use api::wayland; +use api::x11; + +pub enum Window { +    #[doc(hidden)] +    X(x11::Window), +    #[doc(hidden)] +    Wayland(wayland::Window) +} + +#[derive(Clone)] +pub enum WindowProxy { +    #[doc(hidden)] +    X(x11::WindowProxy), +    #[doc(hidden)] +    Wayland(wayland::WindowProxy) +} + +impl WindowProxy { +    pub fn wakeup_event_loop(&self) { +        match self { +            &WindowProxy::X(ref wp) => wp.wakeup_event_loop(), +            &WindowProxy::Wayland(ref wp) => wp.wakeup_event_loop() +        } +    } +} + +pub enum MonitorID { +    #[doc(hidden)] +    X(x11::MonitorID), +    #[doc(hidden)] +    Wayland(wayland::MonitorID) +} + +pub fn get_available_monitors() -> VecDeque<MonitorID> { +    if wayland::is_available() { +        // We are doing wayland +        wayland::get_available_monitors() +            .into_iter() +            .map(|m| MonitorID::Wayland(m)) +            .collect() +    } else { +        // Fallback on X +        x11::get_available_monitors() +            .into_iter() +            .map(|m| MonitorID::X(m)) +            .collect() +    } +} +pub fn get_primary_monitor() -> MonitorID { +    if wayland::is_available() { +        MonitorID::Wayland(wayland::get_primary_monitor()) +    } else { +        MonitorID::X(x11::get_primary_monitor()) +    } +} + +impl MonitorID { +    pub fn get_name(&self) -> Option<String> { +        match self { +            &MonitorID::X(ref m) => m.get_name(), +            &MonitorID::Wayland(ref m) => m.get_name() +        } +    } + +    pub fn get_native_identifier(&self) -> ::native_monitor::NativeMonitorId { +        match self { +            &MonitorID::X(ref m) => m.get_native_identifier(), +            &MonitorID::Wayland(ref m) => m.get_native_identifier() +        } +    } + +    pub fn get_dimensions(&self) -> (u32, u32) { +        match self { +            &MonitorID::X(ref m) => m.get_dimensions(), +            &MonitorID::Wayland(ref m) => m.get_dimensions() +        } +    } +} + + +pub enum PollEventsIterator<'a> { +    #[doc(hidden)] +    X(x11::PollEventsIterator<'a>), +    #[doc(hidden)] +    Wayland(wayland::PollEventsIterator<'a>) +} + +impl<'a> Iterator for PollEventsIterator<'a> { +    type Item = Event; + +    fn next(&mut self) -> Option<Event> { +        match self { +            &mut PollEventsIterator::X(ref mut it) => it.next(), +            &mut PollEventsIterator::Wayland(ref mut it) => it.next() +        } +    } +} + +pub enum WaitEventsIterator<'a> { +    #[doc(hidden)] +    X(x11::WaitEventsIterator<'a>), +    #[doc(hidden)] +    Wayland(wayland::WaitEventsIterator<'a>) +} + +impl<'a> Iterator for WaitEventsIterator<'a> { +    type Item = Event; + +    fn next(&mut self) -> Option<Event> { +        match self { +            &mut WaitEventsIterator::X(ref mut it) => it.next(), +            &mut WaitEventsIterator::Wayland(ref mut it) => it.next() +        } +    } +} + +impl Window { +    pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> { +        if wayland::is_available() { +            // we have a wayland connection, go for it +            let window = try!(wayland::Window::new(builder)); +            Ok(Window::Wayland(window)) +        } else { +            // fallback on X +            let window = try!(x11::Window::new(builder)); +            Ok(Window::X(window)) +        } +    } + +    pub fn is_closed(&self) -> bool { +        match self { +            &Window::X(ref w) => w.is_closed(), +            &Window::Wayland(ref w) => w.is_closed() +        } +    } + +    pub fn set_title(&self, title: &str) { +        match self { +            &Window::X(ref w) => w.set_title(title), +            &Window::Wayland(ref w) => w.set_title(title) +        } +    } + +    pub fn show(&self) { +        match self { +            &Window::X(ref w) => w.show(), +            &Window::Wayland(ref w) => w.show() +        } +    } + +    pub fn hide(&self) { +        match self { +            &Window::X(ref w) => w.hide(), +            &Window::Wayland(ref w) => w.hide() +        } +    } + +    pub fn get_position(&self) -> Option<(i32, i32)> { +        match self { +            &Window::X(ref w) => w.get_position(), +            &Window::Wayland(ref w) => w.get_position() +        } +    } + +    pub fn set_position(&self, x: i32, y: i32) { +        match self { +            &Window::X(ref w) => w.set_position(x, y), +            &Window::Wayland(ref w) => w.set_position(x, y) +        } +    } + +    pub fn get_inner_size(&self) -> Option<(u32, u32)> { +        match self { +            &Window::X(ref w) => w.get_inner_size(), +            &Window::Wayland(ref w) => w.get_inner_size() +        } +    } + +    pub fn get_outer_size(&self) -> Option<(u32, u32)> { +        match self { +            &Window::X(ref w) => w.get_outer_size(), +            &Window::Wayland(ref w) => w.get_outer_size() +        } +    } + +    pub fn set_inner_size(&self, x: u32, y: u32) { +        match self { +            &Window::X(ref w) => w.set_inner_size(x, y), +            &Window::Wayland(ref w) => w.set_inner_size(x, y) +        } +    } + +    pub fn create_window_proxy(&self) -> WindowProxy { +        match self { +            &Window::X(ref w) => WindowProxy::X(w.create_window_proxy()), +            &Window::Wayland(ref w) => WindowProxy::Wayland(w.create_window_proxy()) +        } +    } + +    pub fn poll_events(&self) -> PollEventsIterator { +        match self { +            &Window::X(ref w) => PollEventsIterator::X(w.poll_events()), +            &Window::Wayland(ref w) => PollEventsIterator::Wayland(w.poll_events()) +        } +    } + +    pub fn wait_events(&self) -> WaitEventsIterator { +        match self { +            &Window::X(ref w) => WaitEventsIterator::X(w.wait_events()), +            &Window::Wayland(ref w) => WaitEventsIterator::Wayland(w.wait_events()) +        } +    } + +    pub fn set_window_resize_callback(&mut self, callback: Option<fn(u32, u32)>) { +        match self { +            &mut Window::X(ref mut w) => w.set_window_resize_callback(callback), +            &mut Window::Wayland(ref mut w) => w.set_window_resize_callback(callback) +        } +    } + +    pub fn set_cursor(&self, cursor: MouseCursor) { +        match self { +            &Window::X(ref w) => w.set_cursor(cursor), +            &Window::Wayland(ref w) => w.set_cursor(cursor) +        } +    } + +    pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> { +        match self { +            &Window::X(ref w) => w.set_cursor_state(state), +            &Window::Wayland(ref w) => w.set_cursor_state(state) +        } +    } + +    pub fn hidpi_factor(&self) -> f32 { +       match self { +            &Window::X(ref w) => w.hidpi_factor(), +            &Window::Wayland(ref w) => w.hidpi_factor() +        } +    } + +    pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> { +        match self { +            &Window::X(ref w) => w.set_cursor_position(x, y), +            &Window::Wayland(ref w) => w.set_cursor_position(x, y) +        } +    } + +    pub fn platform_display(&self) -> *mut libc::c_void { +        match self { +            &Window::X(ref w) => w.platform_display(), +            &Window::Wayland(ref w) => w.platform_display() +        } +    } + +    pub fn platform_window(&self) -> *mut libc::c_void { +        match self { +            &Window::X(ref w) => w.platform_window(), +            &Window::Wayland(ref w) => w.platform_window() +        } +    } +} + +impl GlContext for Window { + +    unsafe fn make_current(&self) { +        match self { +            &Window::X(ref w) => w.make_current(), +            &Window::Wayland(ref w) => w.make_current() +        } +    } + +    fn is_current(&self) -> bool { +        match self { +            &Window::X(ref w) => w.is_current(), +            &Window::Wayland(ref w) => w.is_current() +        } +    } + +    fn get_proc_address(&self, addr: &str) -> *const libc::c_void { +        match self { +            &Window::X(ref w) => w.get_proc_address(addr), +            &Window::Wayland(ref w) => w.get_proc_address(addr) +        } +    } + +    fn swap_buffers(&self) { +        match self { +            &Window::X(ref w) => w.swap_buffers(), +            &Window::Wayland(ref w) => w.swap_buffers() +        } +    } + +    fn get_api(&self) -> ::Api { +        match self { +            &Window::X(ref w) => w.get_api(), +            &Window::Wayland(ref w) => w.get_api() +        } +    } + +    fn get_pixel_format(&self) -> PixelFormat { +        match self { +            &Window::X(ref w) => w.get_pixel_format(), +            &Window::Wayland(ref w) => w.get_pixel_format() +        } +    } +}
\ No newline at end of file diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 1e12a80..323a21a 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -10,9 +10,11 @@ use libc;  use api::osmesa::{self, OsMesaContext};  #[cfg(feature = "window")] -pub use api::x11::{Window, WindowProxy, MonitorID, get_available_monitors, get_primary_monitor}; +pub use self::api_dispatch::{Window, WindowProxy, MonitorID, get_available_monitors, get_primary_monitor};  #[cfg(feature = "window")] -pub use api::x11::{WaitEventsIterator, PollEventsIterator}; +pub use self::api_dispatch::{WaitEventsIterator, PollEventsIterator}; +#[cfg(feature = "window")] +mod api_dispatch;  #[cfg(not(feature = "window"))]  pub type Window = ();       // TODO: hack to make things work | 
