diff options
| -rw-r--r-- | src/api/wayland/mod.rs | 16 | ||||
| -rw-r--r-- | src/api/x11/window.rs | 41 | ||||
| -rw-r--r-- | src/platform/linux/api_dispatch.rs | 24 | 
3 files changed, 55 insertions, 26 deletions
| diff --git a/src/api/wayland/mod.rs b/src/api/wayland/mod.rs index 56b9218..10d2acb 100644 --- a/src/api/wayland/mod.rs +++ b/src/api/wayland/mod.rs @@ -13,14 +13,16 @@ use api::dlopen;  use api::egl;  use api::egl::Context as EglContext; -use BuilderAttribs;  use ContextError;  use CreationError;  use Event;  use PixelFormat;  use CursorState;  use MouseCursor; +use GlAttributes;  use GlContext; +use PixelFormatRequirements; +use WindowAttributes;  use std::collections::VecDeque;  use std::ops::{Deref, DerefMut}; @@ -241,7 +243,9 @@ impl<'a> Iterator for WaitEventsIterator<'a> {  }  impl Window { -    pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> { +    pub fn new(window: &WindowAttributes, pf_reqs: &PixelFormatRequirements, +               opengl: &GlAttributes<&Window>) -> Result<Window, CreationError> +    {          use self::wayland::internals::FFI;          let wayland_context = match *WAYLAND_CONTEXT { @@ -251,7 +255,7 @@ impl Window {          if !is_egl_available() { return Err(CreationError::NotSupported) } -        let (w, h) = builder.window.dimensions.unwrap_or((800, 600)); +        let (w, h) = window.dimensions.unwrap_or((800, 600));          let surface = EGLSurface::new(              wayland_context.compositor.create_surface(), @@ -259,12 +263,12 @@ impl Window {              h as i32          ); -        let mut shell_window = if let Some(PlatformMonitorID::Wayland(ref monitor)) = builder.window.monitor { +        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 builder.window.decorations { +            if window.decorations {                  ShellWindow::Decorated(match DecoratedSurface::new(                      surface,                      w as i32, @@ -291,7 +295,7 @@ impl Window {              });              try!(EglContext::new(                  egl, -                &builder.pf_reqs, &builder.opengl.clone().map_sharing(|_| unimplemented!()),        // TODO:  +                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 _))              ) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index 8447c7f..3032bfd 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -1,4 +1,4 @@ -use {Event, BuilderAttribs, MouseCursor}; +use {Event, MouseCursor};  use CreationError;  use CreationError::OsError;  use libc; @@ -12,9 +12,12 @@ use std::sync::{Arc, Mutex};  use Api;  use ContextError;  use CursorState; +use GlAttributes;  use GlContext;  use GlRequest;  use PixelFormat; +use PixelFormatRequirements; +use WindowAttributes;  use api::glx::Context as GlxContext;  use api::egl; @@ -295,10 +298,13 @@ pub struct Window {  }  impl Window { -    pub fn new(display: &Arc<XConnection>, builder: BuilderAttribs) -> Result<Window, CreationError> { -        let dimensions = builder.window.dimensions.unwrap_or((800, 600)); +    pub fn new(display: &Arc<XConnection>, window_attrs: &WindowAttributes, +               pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&Window>) +               -> Result<Window, CreationError> +    { +        let dimensions = window_attrs.dimensions.unwrap_or((800, 600)); -        let screen_id = match builder.window.monitor { +        let screen_id = match window_attrs.monitor {              Some(PlatformMonitorID::X(MonitorID(_, monitor))) => monitor as i32,              _ => unsafe { (display.xlib.XDefaultScreen)(display.display) },          }; @@ -316,7 +322,7 @@ impl Window {              // FIXME: `XF86VidModeModeInfo` is missing its `hskew` field. Therefore we point to              //        `vsyncstart` instead of `vdisplay` as a temporary hack. -            let mode_to_switch_to = if builder.window.monitor.is_some() { +            let mode_to_switch_to = if window_attrs.monitor.is_some() {                  let matching_mode = (0 .. mode_num).map(|i| {                      let m: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(i as isize) as *const _); m                  }).find(|m| m.hdisplay == dimensions.0 as u16 && m.vsyncstart == dimensions.1 as u16); @@ -348,24 +354,23 @@ impl Window {              Glx(::api::glx::ContextPrototype<'a>),              Egl(::api::egl::ContextPrototype<'a>),          } -        let builder_clone = builder.clone(); -        let builder_clone_opengl_glx = builder_clone.opengl.clone().map_sharing(|_| unimplemented!());      // FIXME:  -        let builder_clone_opengl_egl = builder_clone.opengl.clone().map_sharing(|_| unimplemented!());      // FIXME:  -        let context = match builder.opengl.version { +        let builder_clone_opengl_glx = opengl.clone().map_sharing(|_| unimplemented!());      // FIXME:  +        let builder_clone_opengl_egl = opengl.clone().map_sharing(|_| unimplemented!());      // FIXME:  +        let context = match opengl.version {              GlRequest::Latest | GlRequest::Specific(Api::OpenGl, _) | GlRequest::GlThenGles { .. } => {                  // GLX should be preferred over EGL, otherwise crashes may occur                  // on X11 – issue #314                  if let Some(ref glx) = display.glx { -                    Prototype::Glx(try!(GlxContext::new(glx.clone(), &display.xlib, &builder_clone.pf_reqs, &builder_clone_opengl_glx, display.display))) +                    Prototype::Glx(try!(GlxContext::new(glx.clone(), &display.xlib, pf_reqs, &builder_clone_opengl_glx, display.display)))                  } else if let Some(ref egl) = display.egl { -                    Prototype::Egl(try!(EglContext::new(egl.clone(), &builder_clone.pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _))))) +                    Prototype::Egl(try!(EglContext::new(egl.clone(), pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _)))))                  } else {                      return Err(CreationError::NotSupported);                  }              },              GlRequest::Specific(Api::OpenGlEs, _) => {                  if let Some(ref egl) = display.egl { -                    Prototype::Egl(try!(EglContext::new(egl.clone(), &builder_clone.pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _))))) +                    Prototype::Egl(try!(EglContext::new(egl.clone(), pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _)))))                  } else {                      return Err(CreationError::NotSupported);                  } @@ -417,7 +422,7 @@ impl Window {                  ffi::KeyReleaseMask | ffi::ButtonPressMask |                  ffi::ButtonReleaseMask | ffi::KeymapStateMask;              swa.border_pixel = 0; -            if builder.window.transparent { +            if window_attrs.transparent {                  swa.background_pixel = 0;              }              swa.override_redirect = 0; @@ -426,7 +431,7 @@ impl Window {          let mut window_attributes = ffi::CWBorderPixel | ffi::CWColormap | ffi::CWEventMask; -        if builder.window.transparent { +        if window_attrs.transparent {              window_attributes |= ffi::CWBackPixel;          } @@ -450,7 +455,7 @@ impl Window {          };          // set visibility -        if builder.window.visible { +        if window_attrs.visible {              unsafe {                  (display.xlib.XMapRaised)(display.display, window);                  (display.xlib.XFlush)(display.display); @@ -463,7 +468,7 @@ impl Window {                  (display.xlib.XInternAtom)(display.display, delete_window, 0)              );              (display.xlib.XSetWMProtocols)(display.display, window, &mut wm_delete_window, 1); -            with_c_str(&*builder.window.title, |title| {; +            with_c_str(&*window_attrs.title, |title| {;                  (display.xlib.XStoreName)(display.display, window, title);              });              (display.xlib.XFlush)(display.display); @@ -511,7 +516,7 @@ impl Window {          // Set ICCCM WM_CLASS property based on initial window title          unsafe { -            with_c_str(&*builder.window.title, |c_name| { +            with_c_str(&*window_attrs.title, |c_name| {                  let hint = (display.xlib.XAllocClassHint)();                  (*hint).res_name = c_name as *mut libc::c_char;                  (*hint).res_class = c_name as *mut libc::c_char; @@ -520,7 +525,7 @@ impl Window {              });          } -        let is_fullscreen = builder.window.monitor.is_some(); +        let is_fullscreen = window_attrs.monitor.is_some();          // finish creating the OpenGL context          let context = match context { diff --git a/src/platform/linux/api_dispatch.rs b/src/platform/linux/api_dispatch.rs index f25bda9..0fae6a0 100644 --- a/src/platform/linux/api_dispatch.rs +++ b/src/platform/linux/api_dispatch.rs @@ -162,9 +162,29 @@ impl<'a> Iterator for WaitEventsIterator<'a> {  impl Window {      pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> { +        let window = builder.window; +        let pf_reqs = builder.pf_reqs; +        let opengl = builder.opengl; +          match *BACKEND { -            Backend::Wayland => wayland::Window::new(builder).map(Window::Wayland), -            Backend::X(ref connec) => x11::Window::new(connec, builder).map(Window::X), +            Backend::Wayland => { +                let opengl = opengl.map_sharing(|w| match w { +                    &Window::Wayland(ref w) => w, +                    _ => panic!()       // TODO: return an error +                }); + +                wayland::Window::new(&window, &pf_reqs, &opengl).map(Window::Wayland) +            }, + +            Backend::X(ref connec) => { +                let opengl = opengl.map_sharing(|w| match w { +                    &Window::X(ref w) => w, +                    _ => panic!()       // TODO: return an error +                }); + +                x11::Window::new(connec, &window, &pf_reqs, &opengl).map(Window::X) +            }, +              Backend::Error(ref error) => Err(CreationError::NoBackendAvailable(Box::new(error.clone())))          }      } | 
