mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31:30 +11:00
commit
7eeaddebd4
|
@ -1,23 +0,0 @@
|
||||||
#![allow(non_camel_case_types)]
|
|
||||||
|
|
||||||
use libc;
|
|
||||||
|
|
||||||
pub type caca_display_t = libc::c_void;
|
|
||||||
pub type caca_canvas_t = libc::c_void;
|
|
||||||
pub type caca_dither_t = libc::c_void;
|
|
||||||
|
|
||||||
shared_library!(LibCaca, "libcaca.so.0",
|
|
||||||
pub fn caca_create_display(cv: *mut caca_canvas_t) -> *mut caca_display_t,
|
|
||||||
pub fn caca_free_display(dp: *mut caca_display_t) -> libc::c_int,
|
|
||||||
pub fn caca_get_canvas(dp: *mut caca_display_t) -> *mut caca_canvas_t,
|
|
||||||
pub fn caca_refresh_display(dp: *mut caca_display_t) -> libc::c_int,
|
|
||||||
pub fn caca_dither_bitmap(cv: *mut caca_canvas_t, x: libc::c_int, y: libc::c_int,
|
|
||||||
w: libc::c_int, h: libc::c_int, d: *const caca_dither_t,
|
|
||||||
pixels: *const libc::c_void) -> libc::c_int,
|
|
||||||
pub fn caca_free_dither(d: *mut caca_dither_t) -> libc::c_int,
|
|
||||||
pub fn caca_create_dither(bpp: libc::c_int, w: libc::c_int, h: libc::c_int,
|
|
||||||
pitch: libc::c_int, rmask: libc::uint32_t, gmask: libc::uint32_t,
|
|
||||||
bmask: libc::uint32_t, amask: libc::uint32_t) -> *mut caca_dither_t,
|
|
||||||
pub fn caca_get_canvas_width(cv: *mut caca_canvas_t) -> libc::c_int,
|
|
||||||
pub fn caca_get_canvas_height(cv: *mut caca_canvas_t) -> libc::c_int,
|
|
||||||
);
|
|
|
@ -1,297 +0,0 @@
|
||||||
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"))]
|
|
||||||
#![allow(unused_variables, dead_code)]
|
|
||||||
|
|
||||||
use libc;
|
|
||||||
use api::osmesa::{OsMesaContext, OsMesaCreationError};
|
|
||||||
|
|
||||||
use Api;
|
|
||||||
use ContextError;
|
|
||||||
use CreationError;
|
|
||||||
use Event;
|
|
||||||
use GlAttributes;
|
|
||||||
use GlContext;
|
|
||||||
use PixelFormat;
|
|
||||||
use PixelFormatRequirements;
|
|
||||||
use CursorState;
|
|
||||||
use MouseCursor;
|
|
||||||
use WindowAttributes;
|
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::ptr;
|
|
||||||
|
|
||||||
mod ffi;
|
|
||||||
|
|
||||||
pub struct Window {
|
|
||||||
libcaca: ffi::LibCaca,
|
|
||||||
display: *mut ffi::caca_display_t,
|
|
||||||
opengl: OsMesaContext,
|
|
||||||
dither: *mut ffi::caca_dither_t,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct WindowProxy;
|
|
||||||
|
|
||||||
impl WindowProxy {
|
|
||||||
#[inline]
|
|
||||||
pub fn wakeup_event_loop(&self) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MonitorId;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_available_monitors() -> VecDeque<MonitorId> {
|
|
||||||
VecDeque::new()
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn get_primary_monitor() -> MonitorId {
|
|
||||||
MonitorId
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MonitorId {
|
|
||||||
#[inline]
|
|
||||||
pub fn get_name(&self) -> Option<String> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_native_identifier(&self) -> ::native_monitor::NativeMonitorId {
|
|
||||||
::native_monitor::NativeMonitorId::Unavailable
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_dimensions(&self) -> (u32, u32) {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PollEventsIterator<'a> {
|
|
||||||
window: &'a Window,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for PollEventsIterator<'a> {
|
|
||||||
type Item = Event;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<Event> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct WaitEventsIterator<'a> {
|
|
||||||
window: &'a Window,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for WaitEventsIterator<'a> {
|
|
||||||
type Item = Event;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<Event> {
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Window {
|
|
||||||
pub fn new(window: &WindowAttributes, pf_reqs: &PixelFormatRequirements,
|
|
||||||
opengl: &GlAttributes<&Window>) -> Result<Window, CreationError>
|
|
||||||
{
|
|
||||||
let opengl = opengl.clone().map_sharing(|w| &w.opengl);
|
|
||||||
|
|
||||||
let opengl = match OsMesaContext::new(window.dimensions.unwrap_or((800, 600)), pf_reqs,
|
|
||||||
&opengl)
|
|
||||||
{
|
|
||||||
Err(OsMesaCreationError::NotSupported) => return Err(CreationError::NotSupported),
|
|
||||||
Err(OsMesaCreationError::CreationError(e)) => return Err(e),
|
|
||||||
Ok(c) => c
|
|
||||||
};
|
|
||||||
|
|
||||||
let opengl_dimensions = opengl.get_dimensions();
|
|
||||||
|
|
||||||
let libcaca = match ffi::LibCaca::open(&Path::new("libcaca.so.0")) {
|
|
||||||
Err(_) => return Err(CreationError::NotSupported),
|
|
||||||
Ok(l) => l
|
|
||||||
};
|
|
||||||
|
|
||||||
let display = unsafe { (libcaca.caca_create_display)(ptr::null_mut()) };
|
|
||||||
|
|
||||||
if display.is_null() {
|
|
||||||
return Err(CreationError::OsError("caca_create_display failed".to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
let dither = unsafe {
|
|
||||||
#[cfg(target_endian = "little")]
|
|
||||||
fn get_masks() -> (u32, u32, u32, u32) { (0xff, 0xff00, 0xff0000, 0xff000000) }
|
|
||||||
#[cfg(target_endian = "big")]
|
|
||||||
fn get_masks() -> (u32, u32, u32, u32) { (0xff000000, 0xff0000, 0xff00, 0xff) }
|
|
||||||
|
|
||||||
let masks = get_masks();
|
|
||||||
(libcaca.caca_create_dither)(32, opengl_dimensions.0 as libc::c_int,
|
|
||||||
opengl_dimensions.1 as libc::c_int,
|
|
||||||
opengl_dimensions.0 as libc::c_int * 4,
|
|
||||||
masks.0, masks.1, masks.2, masks.3)
|
|
||||||
};
|
|
||||||
|
|
||||||
if dither.is_null() {
|
|
||||||
unsafe { (libcaca.caca_free_display)(display) };
|
|
||||||
return Err(CreationError::OsError("caca_create_dither failed".to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Window {
|
|
||||||
libcaca: libcaca,
|
|
||||||
display: display,
|
|
||||||
opengl: opengl,
|
|
||||||
dither: dither,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set_title(&self, title: &str) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn show(&self) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn hide(&self) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_position(&self) -> Option<(i32, i32)> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set_position(&self, x: i32, y: i32) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_inner_size(&self) -> Option<(u32, u32)> {
|
|
||||||
Some(self.opengl.get_dimensions())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_outer_size(&self) -> Option<(u32, u32)> {
|
|
||||||
self.get_inner_size()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set_inner_size(&self, _x: u32, _y: u32) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn create_window_proxy(&self) -> WindowProxy {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn poll_events(&self) -> PollEventsIterator {
|
|
||||||
PollEventsIterator {
|
|
||||||
window: self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn wait_events(&self) -> WaitEventsIterator {
|
|
||||||
WaitEventsIterator {
|
|
||||||
window: self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn platform_display(&self) -> *mut libc::c_void {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn platform_window(&self) -> *mut libc::c_void {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_pixel_format(&self) -> PixelFormat {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn hidpi_factor(&self) -> f32 {
|
|
||||||
1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GlContext for Window {
|
|
||||||
#[inline]
|
|
||||||
unsafe fn make_current(&self) -> Result<(), ContextError> {
|
|
||||||
self.opengl.make_current()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_current(&self) -> bool {
|
|
||||||
self.opengl.is_current()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_proc_address(&self, addr: &str) -> *const () {
|
|
||||||
self.opengl.get_proc_address(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn swap_buffers(&self) -> Result<(), ContextError> {
|
|
||||||
unsafe {
|
|
||||||
let canvas = (self.libcaca.caca_get_canvas)(self.display);
|
|
||||||
let width = (self.libcaca.caca_get_canvas_width)(canvas);
|
|
||||||
let height = (self.libcaca.caca_get_canvas_height)(canvas);
|
|
||||||
|
|
||||||
let buffer = self.opengl.get_framebuffer().chunks(self.opengl.get_dimensions().0 as usize)
|
|
||||||
.flat_map(|i| i.iter().cloned()).rev().collect::<Vec<u32>>();
|
|
||||||
|
|
||||||
(self.libcaca.caca_dither_bitmap)(canvas, 0, 0, width as libc::c_int,
|
|
||||||
height as libc::c_int, self.dither,
|
|
||||||
buffer.as_ptr() as *const _);
|
|
||||||
(self.libcaca.caca_refresh_display)(self.display);
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_api(&self) -> Api {
|
|
||||||
self.opengl.get_api()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_pixel_format(&self) -> PixelFormat {
|
|
||||||
self.opengl.get_pixel_format()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Window {
|
|
||||||
#[inline]
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
(self.libcaca.caca_free_dither)(self.dither);
|
|
||||||
(self.libcaca.caca_free_display)(self.display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
pub mod android;
|
pub mod android;
|
||||||
pub mod caca;
|
|
||||||
pub mod cocoa;
|
pub mod cocoa;
|
||||||
pub mod dlopen;
|
pub mod dlopen;
|
||||||
pub mod emscripten;
|
pub mod emscripten;
|
||||||
|
|
|
@ -4,11 +4,8 @@ use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
|
|
||||||
use {ContextError, CreationError, CursorState, Event, GlAttributes, GlContext,
|
use {CreationError, CursorState, Event, MouseCursor, WindowAttributes};
|
||||||
MouseCursor, PixelFormat, PixelFormatRequirements, WindowAttributes};
|
|
||||||
use api::dlopen;
|
use api::dlopen;
|
||||||
use api::egl;
|
|
||||||
use api::egl::Context as EglContext;
|
|
||||||
use platform::MonitorId as PlatformMonitorId;
|
use platform::MonitorId as PlatformMonitorId;
|
||||||
|
|
||||||
use wayland_client::EventIterator;
|
use wayland_client::EventIterator;
|
||||||
|
@ -34,7 +31,6 @@ pub struct Window {
|
||||||
evt_queue: Arc<Mutex<VecDeque<Event>>>,
|
evt_queue: Arc<Mutex<VecDeque<Event>>>,
|
||||||
inner_size: Mutex<(i32, i32)>,
|
inner_size: Mutex<(i32, i32)>,
|
||||||
resize_callback: Option<fn(u32, u32)>,
|
resize_callback: Option<fn(u32, u32)>,
|
||||||
pub context: EglContext,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -137,8 +133,7 @@ enum ShellWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new(window: &WindowAttributes, pf_reqs: &PixelFormatRequirements,
|
pub fn new(window: &WindowAttributes) -> Result<Window, CreationError>
|
||||||
opengl: &GlAttributes<&Window>) -> Result<Window, CreationError>
|
|
||||||
{
|
{
|
||||||
use wayland_client::Proxy;
|
use wayland_client::Proxy;
|
||||||
// not implemented
|
// not implemented
|
||||||
|
@ -163,23 +158,6 @@ impl Window {
|
||||||
|
|
||||||
let egl_surface = wegl::WlEglSurface::new(surface, w as i32, h as i32);
|
let egl_surface = wegl::WlEglSurface::new(surface, w as i32, h as i32);
|
||||||
|
|
||||||
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(unsafe { egl_surface.egl_surfaceptr() } as *const _))
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let shell_window = if let Some(PlatformMonitorId::Wayland(ref monitor_id)) = window.monitor {
|
let shell_window = if let Some(PlatformMonitorId::Wayland(ref monitor_id)) = window.monitor {
|
||||||
let pid = super::monitor::proxid_from_monitorid(monitor_id);
|
let pid = super::monitor::proxid_from_monitorid(monitor_id);
|
||||||
match wayland_context.plain_from(&egl_surface, Some(pid)) {
|
match wayland_context.plain_from(&egl_surface, Some(pid)) {
|
||||||
|
@ -213,7 +191,6 @@ impl Window {
|
||||||
evt_queue: evt_queue,
|
evt_queue: evt_queue,
|
||||||
inner_size: Mutex::new((w as i32, h as i32)),
|
inner_size: Mutex::new((w as i32, h as i32)),
|
||||||
resize_callback: None,
|
resize_callback: None,
|
||||||
context: context
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,38 +307,6 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlContext for Window {
|
|
||||||
#[inline]
|
|
||||||
unsafe fn make_current(&self) -> Result<(), ContextError> {
|
|
||||||
self.context.make_current()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_current(&self) -> bool {
|
|
||||||
self.context.is_current()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_proc_address(&self, addr: &str) -> *const () {
|
|
||||||
self.context.get_proc_address(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn swap_buffers(&self) -> Result<(), ContextError> {
|
|
||||||
self.context.swap_buffers()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_api(&self) -> ::Api {
|
|
||||||
self.context.get_api()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_pixel_format(&self) -> PixelFormat {
|
|
||||||
self.context.get_pixel_format().clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Window {
|
impl Drop for Window {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
use wayland_client::Proxy;
|
use wayland_client::Proxy;
|
||||||
|
|
|
@ -4,17 +4,4 @@ pub use x11_dl::xf86vmode::*;
|
||||||
pub use x11_dl::xlib::*;
|
pub use x11_dl::xlib::*;
|
||||||
pub use x11_dl::xinput::*;
|
pub use x11_dl::xinput::*;
|
||||||
pub use x11_dl::xinput2::*;
|
pub use x11_dl::xinput2::*;
|
||||||
|
|
||||||
pub use x11_dl::error::OpenError;
|
pub use x11_dl::error::OpenError;
|
||||||
|
|
||||||
pub use self::glx::types::GLXContext;
|
|
||||||
|
|
||||||
/// GLX bindings
|
|
||||||
pub mod glx {
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/glx_bindings.rs"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Functions that are not necessarly always available
|
|
||||||
pub mod glx_extra {
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/glx_extra_bindings.rs"));
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"))]
|
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"))]
|
||||||
|
|
||||||
pub use self::monitor::{MonitorId, get_available_monitors, get_primary_monitor};
|
pub use self::monitor::{MonitorId, get_available_monitors, get_primary_monitor};
|
||||||
pub use self::window::{Window, XWindow, PollEventsIterator, WaitEventsIterator, Context, WindowProxy};
|
pub use self::window::{Window, XWindow, PollEventsIterator, WaitEventsIterator, WindowProxy};
|
||||||
pub use self::xdisplay::{XConnection, XNotSupported, XError};
|
pub use self::xdisplay::{XConnection, XNotSupported, XError};
|
||||||
|
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
|
|
|
@ -12,20 +12,9 @@ use std::os::raw::c_long;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use Api;
|
|
||||||
use ContextError;
|
|
||||||
use CursorState;
|
use CursorState;
|
||||||
use GlAttributes;
|
|
||||||
use GlContext;
|
|
||||||
use GlRequest;
|
|
||||||
use PixelFormat;
|
|
||||||
use PixelFormatRequirements;
|
|
||||||
use WindowAttributes;
|
use WindowAttributes;
|
||||||
|
|
||||||
use api::glx::Context as GlxContext;
|
|
||||||
use api::egl;
|
|
||||||
use api::egl::Context as EglContext;
|
|
||||||
|
|
||||||
use platform::MonitorId as PlatformMonitorId;
|
use platform::MonitorId as PlatformMonitorId;
|
||||||
|
|
||||||
use super::input::XInputEventHandler;
|
use super::input::XInputEventHandler;
|
||||||
|
@ -54,22 +43,14 @@ unsafe impl Send for WindowProxyData {}
|
||||||
pub struct XWindow {
|
pub struct XWindow {
|
||||||
display: Arc<XConnection>,
|
display: Arc<XConnection>,
|
||||||
window: ffi::Window,
|
window: ffi::Window,
|
||||||
pub context: Context,
|
|
||||||
is_fullscreen: bool,
|
is_fullscreen: bool,
|
||||||
screen_id: libc::c_int,
|
screen_id: libc::c_int,
|
||||||
xf86_desk_mode: Option<ffi::XF86VidModeModeInfo>,
|
xf86_desk_mode: Option<ffi::XF86VidModeModeInfo>,
|
||||||
ic: ffi::XIC,
|
ic: ffi::XIC,
|
||||||
im: ffi::XIM,
|
im: ffi::XIM,
|
||||||
colormap: ffi::Colormap,
|
|
||||||
window_proxy_data: Arc<Mutex<Option<WindowProxyData>>>,
|
window_proxy_data: Arc<Mutex<Option<WindowProxyData>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Context {
|
|
||||||
Glx(GlxContext),
|
|
||||||
Egl(EglContext),
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for XWindow {}
|
unsafe impl Send for XWindow {}
|
||||||
unsafe impl Sync for XWindow {}
|
unsafe impl Sync for XWindow {}
|
||||||
|
|
||||||
|
@ -83,10 +64,6 @@ impl Drop for XWindow {
|
||||||
// are no longer able to send messages to this window.
|
// are no longer able to send messages to this window.
|
||||||
*self.window_proxy_data.lock().unwrap() = None;
|
*self.window_proxy_data.lock().unwrap() = None;
|
||||||
|
|
||||||
// we don't call MakeCurrent(0, 0) because we are not sure that the context
|
|
||||||
// is still the current one
|
|
||||||
self.context = Context::None;
|
|
||||||
|
|
||||||
let _lock = GLOBAL_XOPENIM_LOCK.lock().unwrap();
|
let _lock = GLOBAL_XOPENIM_LOCK.lock().unwrap();
|
||||||
|
|
||||||
if self.is_fullscreen {
|
if self.is_fullscreen {
|
||||||
|
@ -99,7 +76,6 @@ impl Drop for XWindow {
|
||||||
(self.display.xlib.XDestroyIC)(self.ic);
|
(self.display.xlib.XDestroyIC)(self.ic);
|
||||||
(self.display.xlib.XCloseIM)(self.im);
|
(self.display.xlib.XCloseIM)(self.im);
|
||||||
(self.display.xlib.XDestroyWindow)(self.display.display, self.window);
|
(self.display.xlib.XDestroyWindow)(self.display.display, self.window);
|
||||||
(self.display.xlib.XFreeColormap)(self.display.display, self.colormap);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,8 +282,7 @@ pub struct Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new(display: &Arc<XConnection>, window_attrs: &WindowAttributes,
|
pub fn new(display: &Arc<XConnection>, window_attrs: &WindowAttributes)
|
||||||
pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&Window>)
|
|
||||||
-> Result<Window, CreationError>
|
-> Result<Window, CreationError>
|
||||||
{
|
{
|
||||||
let dimensions = window_attrs.dimensions.unwrap_or((800, 600));
|
let dimensions = window_attrs.dimensions.unwrap_or((800, 600));
|
||||||
|
@ -353,76 +328,14 @@ impl Window {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// start the context building process
|
|
||||||
enum Prototype<'a> {
|
|
||||||
Glx(::api::glx::ContextPrototype<'a>),
|
|
||||||
Egl(::api::egl::ContextPrototype<'a>),
|
|
||||||
}
|
|
||||||
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, pf_reqs, &builder_clone_opengl_glx, display.display, screen_id)))
|
|
||||||
} else if let Some(ref egl) = display.egl {
|
|
||||||
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(), pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _)))))
|
|
||||||
} else {
|
|
||||||
return Err(CreationError::NotSupported);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
GlRequest::Specific(_, _) => {
|
|
||||||
return Err(CreationError::NotSupported);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// getting the `visual_infos` (a struct that contains information about the visual to use)
|
|
||||||
let visual_infos = match context {
|
|
||||||
Prototype::Glx(ref p) => p.get_visual_infos().clone(),
|
|
||||||
Prototype::Egl(ref p) => {
|
|
||||||
unsafe {
|
|
||||||
let mut template: ffi::XVisualInfo = mem::zeroed();
|
|
||||||
template.visualid = p.get_native_visual_id() as ffi::VisualID;
|
|
||||||
|
|
||||||
let mut num_visuals = 0;
|
|
||||||
let vi = (display.xlib.XGetVisualInfo)(display.display, ffi::VisualIDMask,
|
|
||||||
&mut template, &mut num_visuals);
|
|
||||||
display.check_errors().expect("Failed to call XGetVisualInfo");
|
|
||||||
assert!(!vi.is_null());
|
|
||||||
assert!(num_visuals == 1);
|
|
||||||
|
|
||||||
let vi_copy = ptr::read(vi as *const _);
|
|
||||||
(display.xlib.XFree)(vi as *mut _);
|
|
||||||
vi_copy
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// getting the root window
|
// getting the root window
|
||||||
let root = unsafe { (display.xlib.XDefaultRootWindow)(display.display) };
|
let root = unsafe { (display.xlib.XDefaultRootWindow)(display.display) };
|
||||||
display.check_errors().expect("Failed to get root window");
|
display.check_errors().expect("Failed to get root window");
|
||||||
|
|
||||||
// creating the color map
|
|
||||||
let cmap = unsafe {
|
|
||||||
let cmap = (display.xlib.XCreateColormap)(display.display, root,
|
|
||||||
visual_infos.visual as *mut _,
|
|
||||||
ffi::AllocNone);
|
|
||||||
display.check_errors().expect("Failed to call XCreateColormap");
|
|
||||||
cmap
|
|
||||||
};
|
|
||||||
|
|
||||||
// creating
|
// creating
|
||||||
let mut set_win_attr = {
|
let mut set_win_attr = {
|
||||||
let mut swa: ffi::XSetWindowAttributes = unsafe { mem::zeroed() };
|
let mut swa: ffi::XSetWindowAttributes = unsafe { mem::zeroed() };
|
||||||
swa.colormap = cmap;
|
swa.colormap = 0;
|
||||||
swa.event_mask = ffi::ExposureMask | ffi::StructureNotifyMask |
|
swa.event_mask = ffi::ExposureMask | ffi::StructureNotifyMask |
|
||||||
ffi::VisibilityChangeMask | ffi::KeyPressMask | ffi::PointerMotionMask |
|
ffi::VisibilityChangeMask | ffi::KeyPressMask | ffi::PointerMotionMask |
|
||||||
ffi::KeyReleaseMask | ffi::ButtonPressMask |
|
ffi::KeyReleaseMask | ffi::ButtonPressMask |
|
||||||
|
@ -444,8 +357,8 @@ impl Window {
|
||||||
// finally creating the window
|
// finally creating the window
|
||||||
let window = unsafe {
|
let window = unsafe {
|
||||||
let win = (display.xlib.XCreateWindow)(display.display, root, 0, 0, dimensions.0 as libc::c_uint,
|
let win = (display.xlib.XCreateWindow)(display.display, root, 0, 0, dimensions.0 as libc::c_uint,
|
||||||
dimensions.1 as libc::c_uint, 0, visual_infos.depth, ffi::InputOutput as libc::c_uint,
|
dimensions.1 as libc::c_uint, 0, ffi::CopyFromParent, ffi::InputOutput as libc::c_uint,
|
||||||
visual_infos.visual as *mut _, window_attributes,
|
ffi::CopyFromParent as *mut _, window_attributes,
|
||||||
&mut set_win_attr);
|
&mut set_win_attr);
|
||||||
display.check_errors().expect("Failed to call XCreateWindow");
|
display.check_errors().expect("Failed to call XCreateWindow");
|
||||||
win
|
win
|
||||||
|
@ -591,19 +504,6 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// finish creating the OpenGL context
|
|
||||||
let context = match context {
|
|
||||||
Prototype::Glx(ctxt) => {
|
|
||||||
Context::Glx(try!(ctxt.finish(window)))
|
|
||||||
},
|
|
||||||
Prototype::Egl(ctxt) => {
|
|
||||||
Context::Egl(try!(ctxt.finish(window as *const libc::c_void)))
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// creating the OpenGL can produce errors, but since everything is checked we ignore
|
|
||||||
display.ignore_error();
|
|
||||||
|
|
||||||
// creating the window object
|
// creating the window object
|
||||||
let window_proxy_data = WindowProxyData {
|
let window_proxy_data = WindowProxyData {
|
||||||
display: display.clone(),
|
display: display.clone(),
|
||||||
|
@ -617,11 +517,9 @@ impl Window {
|
||||||
window: window,
|
window: window,
|
||||||
im: im,
|
im: im,
|
||||||
ic: ic,
|
ic: ic,
|
||||||
context: context,
|
|
||||||
screen_id: screen_id,
|
screen_id: screen_id,
|
||||||
is_fullscreen: is_fullscreen,
|
is_fullscreen: is_fullscreen,
|
||||||
xf86_desk_mode: xf86_desk_mode,
|
xf86_desk_mode: xf86_desk_mode,
|
||||||
colormap: cmap,
|
|
||||||
window_proxy_data: window_proxy_data,
|
window_proxy_data: window_proxy_data,
|
||||||
}),
|
}),
|
||||||
is_closed: AtomicBool::new(false),
|
is_closed: AtomicBool::new(false),
|
||||||
|
@ -906,59 +804,3 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlContext for Window {
|
|
||||||
#[inline]
|
|
||||||
unsafe fn make_current(&self) -> Result<(), ContextError> {
|
|
||||||
match self.x.context {
|
|
||||||
Context::Glx(ref ctxt) => ctxt.make_current(),
|
|
||||||
Context::Egl(ref ctxt) => ctxt.make_current(),
|
|
||||||
Context::None => Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_current(&self) -> bool {
|
|
||||||
match self.x.context {
|
|
||||||
Context::Glx(ref ctxt) => ctxt.is_current(),
|
|
||||||
Context::Egl(ref ctxt) => ctxt.is_current(),
|
|
||||||
Context::None => panic!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_proc_address(&self, addr: &str) -> *const () {
|
|
||||||
match self.x.context {
|
|
||||||
Context::Glx(ref ctxt) => ctxt.get_proc_address(addr),
|
|
||||||
Context::Egl(ref ctxt) => ctxt.get_proc_address(addr),
|
|
||||||
Context::None => ptr::null()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn swap_buffers(&self) -> Result<(), ContextError> {
|
|
||||||
match self.x.context {
|
|
||||||
Context::Glx(ref ctxt) => ctxt.swap_buffers(),
|
|
||||||
Context::Egl(ref ctxt) => ctxt.swap_buffers(),
|
|
||||||
Context::None => Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_api(&self) -> Api {
|
|
||||||
match self.x.context {
|
|
||||||
Context::Glx(ref ctxt) => ctxt.get_api(),
|
|
||||||
Context::Egl(ref ctxt) => ctxt.get_api(),
|
|
||||||
Context::None => panic!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_pixel_format(&self) -> PixelFormat {
|
|
||||||
match self.x.context {
|
|
||||||
Context::Glx(ref ctxt) => ctxt.get_pixel_format(),
|
|
||||||
Context::Egl(ref ctxt) => ctxt.get_pixel_format(),
|
|
||||||
Context::None => panic!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ use std::sync::Mutex;
|
||||||
use libc;
|
use libc;
|
||||||
|
|
||||||
use super::ffi;
|
use super::ffi;
|
||||||
use api::egl::ffi::egl::Egl;
|
|
||||||
use api::dlopen;
|
use api::dlopen;
|
||||||
|
|
||||||
/// A connection to an X server.
|
/// A connection to an X server.
|
||||||
|
@ -16,8 +15,6 @@ pub struct XConnection {
|
||||||
pub xf86vmode: ffi::Xf86vmode,
|
pub xf86vmode: ffi::Xf86vmode,
|
||||||
pub xcursor: ffi::Xcursor,
|
pub xcursor: ffi::Xcursor,
|
||||||
pub xinput2: ffi::XInput2,
|
pub xinput2: ffi::XInput2,
|
||||||
pub glx: Option<ffi::glx::Glx>,
|
|
||||||
pub egl: Option<Egl>,
|
|
||||||
pub display: *mut ffi::Display,
|
pub display: *mut ffi::Display,
|
||||||
pub latest_error: Mutex<Option<XError>>,
|
pub latest_error: Mutex<Option<XError>>,
|
||||||
}
|
}
|
||||||
|
@ -38,40 +35,6 @@ impl XConnection {
|
||||||
unsafe { (xlib.XInitThreads)() };
|
unsafe { (xlib.XInitThreads)() };
|
||||||
unsafe { (xlib.XSetErrorHandler)(error_handler) };
|
unsafe { (xlib.XSetErrorHandler)(error_handler) };
|
||||||
|
|
||||||
// TODO: use something safer than raw "dlopen"
|
|
||||||
let glx = {
|
|
||||||
let mut libglx = unsafe { dlopen::dlopen(b"libGL.so.1\0".as_ptr() as *const _, dlopen::RTLD_NOW) };
|
|
||||||
if libglx.is_null() {
|
|
||||||
libglx = unsafe { dlopen::dlopen(b"libGL.so\0".as_ptr() as *const _, dlopen::RTLD_NOW) };
|
|
||||||
}
|
|
||||||
|
|
||||||
if libglx.is_null() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(ffi::glx::Glx::load_with(|sym| {
|
|
||||||
let sym = CString::new(sym).unwrap();
|
|
||||||
unsafe { dlopen::dlsym(libglx, sym.as_ptr()) }
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: use something safer than raw "dlopen"
|
|
||||||
let egl = {
|
|
||||||
let mut libegl = unsafe { dlopen::dlopen(b"libEGL.so.1\0".as_ptr() as *const _, dlopen::RTLD_NOW) };
|
|
||||||
if libegl.is_null() {
|
|
||||||
libegl = unsafe { dlopen::dlopen(b"libEGL.so\0".as_ptr() as *const _, dlopen::RTLD_NOW) };
|
|
||||||
}
|
|
||||||
|
|
||||||
if libegl.is_null() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(Egl::load_with(|sym| {
|
|
||||||
let sym = CString::new(sym).unwrap();
|
|
||||||
unsafe { dlopen::dlsym(libegl, sym.as_ptr()) }
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// calling XOpenDisplay
|
// calling XOpenDisplay
|
||||||
let display = unsafe {
|
let display = unsafe {
|
||||||
let display = (xlib.XOpenDisplay)(ptr::null());
|
let display = (xlib.XOpenDisplay)(ptr::null());
|
||||||
|
@ -86,8 +49,6 @@ impl XConnection {
|
||||||
xf86vmode: xf86vmode,
|
xf86vmode: xf86vmode,
|
||||||
xcursor: xcursor,
|
xcursor: xcursor,
|
||||||
xinput2: xinput2,
|
xinput2: xinput2,
|
||||||
glx: glx,
|
|
||||||
egl: egl,
|
|
||||||
display: display,
|
display: display,
|
||||||
latest_error: Mutex::new(None),
|
latest_error: Mutex::new(None),
|
||||||
})
|
})
|
||||||
|
|
|
@ -45,5 +45,5 @@ pub trait WindowBuilderExt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WindowBuilderExt for WindowBuilder<'a> {
|
impl WindowBuilderExt for WindowBuilder {
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,10 @@ pub use api::x11::{WaitEventsIterator, PollEventsIterator};*/
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ContextError;
|
|
||||||
use CreationError;
|
use CreationError;
|
||||||
use CursorState;
|
use CursorState;
|
||||||
use Event;
|
use Event;
|
||||||
use GlAttributes;
|
|
||||||
use GlContext;
|
|
||||||
use MouseCursor;
|
use MouseCursor;
|
||||||
use PixelFormat;
|
|
||||||
use PixelFormatRequirements;
|
|
||||||
use WindowAttributes;
|
use WindowAttributes;
|
||||||
use libc;
|
use libc;
|
||||||
|
|
||||||
|
@ -174,30 +169,22 @@ impl<'a> Iterator for WaitEventsIterator<'a> {
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(window: &WindowAttributes, pf_reqs: &PixelFormatRequirements,
|
pub fn new(window: &WindowAttributes, _: &PlatformSpecificWindowBuilderAttributes)
|
||||||
opengl: &GlAttributes<&Window>, _: &PlatformSpecificWindowBuilderAttributes)
|
|
||||||
-> Result<Window, CreationError>
|
-> Result<Window, CreationError>
|
||||||
{
|
{
|
||||||
match *BACKEND {
|
match *BACKEND {
|
||||||
Backend::Wayland => {
|
Backend::Wayland => {
|
||||||
let opengl = opengl.clone().map_sharing(|w| match w {
|
wayland::Window::new(window).map(Window::Wayland)
|
||||||
&Window::Wayland(ref w) => w,
|
|
||||||
_ => panic!() // TODO: return an error
|
|
||||||
});
|
|
||||||
|
|
||||||
wayland::Window::new(window, pf_reqs, &opengl).map(Window::Wayland)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
Backend::X(ref connec) => {
|
Backend::X(ref connec) => {
|
||||||
let opengl = opengl.clone().map_sharing(|w| match w {
|
x11::Window::new(connec, window).map(Window::X)
|
||||||
&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())))
|
Backend::Error(ref error) => {
|
||||||
|
panic!() // FIXME: supposed to return an error
|
||||||
|
//Err(CreationError::NoBackendAvailable(Box::new(error.clone())))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,56 +333,6 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlContext for Window {
|
|
||||||
#[inline]
|
|
||||||
unsafe fn make_current(&self) -> Result<(), ContextError> {
|
|
||||||
match self {
|
|
||||||
&Window::X(ref w) => w.make_current(),
|
|
||||||
&Window::Wayland(ref w) => w.make_current()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_current(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
&Window::X(ref w) => w.is_current(),
|
|
||||||
&Window::Wayland(ref w) => w.is_current()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_proc_address(&self, addr: &str) -> *const () {
|
|
||||||
match self {
|
|
||||||
&Window::X(ref w) => w.get_proc_address(addr),
|
|
||||||
&Window::Wayland(ref w) => w.get_proc_address(addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn swap_buffers(&self) -> Result<(), ContextError> {
|
|
||||||
match self {
|
|
||||||
&Window::X(ref w) => w.swap_buffers(),
|
|
||||||
&Window::Wayland(ref w) => w.swap_buffers()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_api(&self) -> ::Api {
|
|
||||||
match self {
|
|
||||||
&Window::X(ref w) => w.get_api(),
|
|
||||||
&Window::Wayland(ref w) => w.get_api()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_pixel_format(&self) -> PixelFormat {
|
|
||||||
match self {
|
|
||||||
&Window::X(ref w) => w.get_pixel_format(),
|
|
||||||
&Window::Wayland(ref w) => w.get_pixel_format()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe extern "C" fn x_error_callback(dpy: *mut x11::ffi::Display, event: *mut x11::ffi::XErrorEvent)
|
unsafe extern "C" fn x_error_callback(dpy: *mut x11::ffi::Display, event: *mut x11::ffi::XErrorEvent)
|
||||||
-> libc::c_int
|
-> libc::c_int
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,71 +1,7 @@
|
||||||
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"))]
|
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"))]
|
||||||
|
|
||||||
use Api;
|
|
||||||
use ContextError;
|
|
||||||
use CreationError;
|
|
||||||
use GlAttributes;
|
|
||||||
use GlContext;
|
|
||||||
use PixelFormat;
|
|
||||||
use PixelFormatRequirements;
|
|
||||||
|
|
||||||
use api::osmesa::{self, OsMesaContext};
|
|
||||||
|
|
||||||
pub use self::api_dispatch::{Window, WindowProxy, MonitorId, get_available_monitors, get_primary_monitor};
|
pub use self::api_dispatch::{Window, WindowProxy, MonitorId, get_available_monitors, get_primary_monitor};
|
||||||
pub use self::api_dispatch::{WaitEventsIterator, PollEventsIterator};
|
pub use self::api_dispatch::{WaitEventsIterator, PollEventsIterator};
|
||||||
pub use self::api_dispatch::PlatformSpecificWindowBuilderAttributes;
|
pub use self::api_dispatch::PlatformSpecificWindowBuilderAttributes;
|
||||||
|
|
||||||
mod api_dispatch;
|
mod api_dispatch;
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct PlatformSpecificHeadlessBuilderAttributes;
|
|
||||||
|
|
||||||
pub struct HeadlessContext(OsMesaContext);
|
|
||||||
|
|
||||||
impl HeadlessContext {
|
|
||||||
pub fn new(dimensions: (u32, u32), pf_reqs: &PixelFormatRequirements,
|
|
||||||
opengl: &GlAttributes<&HeadlessContext>,
|
|
||||||
_: &PlatformSpecificHeadlessBuilderAttributes)
|
|
||||||
-> Result<HeadlessContext, CreationError>
|
|
||||||
{
|
|
||||||
let opengl = opengl.clone().map_sharing(|c| &c.0);
|
|
||||||
|
|
||||||
match OsMesaContext::new(dimensions, pf_reqs, &opengl) {
|
|
||||||
Ok(c) => return Ok(HeadlessContext(c)),
|
|
||||||
Err(osmesa::OsMesaCreationError::NotSupported) => (),
|
|
||||||
Err(osmesa::OsMesaCreationError::CreationError(e)) => return Err(e),
|
|
||||||
};
|
|
||||||
|
|
||||||
Err(CreationError::NotSupported)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GlContext for HeadlessContext {
|
|
||||||
#[inline]
|
|
||||||
unsafe fn make_current(&self) -> Result<(), ContextError> {
|
|
||||||
self.0.make_current()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_current(&self) -> bool {
|
|
||||||
self.0.is_current()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_proc_address(&self, addr: &str) -> *const () {
|
|
||||||
self.0.get_proc_address(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn swap_buffers(&self) -> Result<(), ContextError> {
|
|
||||||
self.0.swap_buffers()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_api(&self) -> Api {
|
|
||||||
self.0.get_api()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_pixel_format(&self) -> PixelFormat {
|
|
||||||
self.0.get_pixel_format()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue