use {Frame, IncompatibleOpenGl, SwapBuffersError};
use debug;
use context;
use backend::{self, Backend};
use std::rc::Rc;
use std::ops::Deref;
use std::os::raw::c_void;
use super::glutin;
use super::glutin::GlContext;
pub struct Headless {
context: Rc<context::Context>,
glutin: Rc<glutin::HeadlessContext>,
}
pub struct GlutinBackend(Rc<glutin::HeadlessContext>);
impl Deref for Headless {
type Target = context::Context;
fn deref(&self) -> &context::Context {
&self.context
}
}
impl Deref for GlutinBackend {
type Target = glutin::HeadlessContext;
fn deref(&self) -> &glutin::HeadlessContext {
&self.0
}
}
unsafe impl Backend for GlutinBackend {
#[inline]
fn swap_buffers(&self) -> Result<(), SwapBuffersError> {
Ok(())
}
#[inline]
unsafe fn get_proc_address(&self, symbol: &str) -> *const c_void {
self.0.get_proc_address(symbol) as *const _
}
#[inline]
fn get_framebuffer_dimensions(&self) -> (u32, u32) {
(800, 600) }
#[inline]
fn is_current(&self) -> bool {
self.0.is_current()
}
#[inline]
unsafe fn make_current(&self) {
self.0.make_current().unwrap();
}
}
impl backend::Facade for Headless {
#[inline]
fn get_context(&self) -> &Rc<context::Context> {
&self.context
}
}
impl Headless {
pub fn new(context: glutin::HeadlessContext) -> Result<Self, IncompatibleOpenGl> {
Self::with_debug(context, Default::default())
}
pub unsafe fn unchecked(context: glutin::HeadlessContext) -> Result<Self, IncompatibleOpenGl> {
Self::unchecked_with_debug(context, Default::default())
}
pub fn with_debug(context: glutin::HeadlessContext, debug: debug::DebugCallbackBehavior)
-> Result<Self, IncompatibleOpenGl>
{
Self::new_inner(context, debug, true)
}
pub unsafe fn unchecked_with_debug(
context: glutin::HeadlessContext,
debug: debug::DebugCallbackBehavior,
) -> Result<Self, IncompatibleOpenGl>
{
Self::new_inner(context, debug, false)
}
fn new_inner(
context: glutin::HeadlessContext,
debug: debug::DebugCallbackBehavior,
checked: bool,
) -> Result<Self, IncompatibleOpenGl>
{
let glutin_context = Rc::new(context);
let glutin_backend = GlutinBackend(glutin_context.clone());
let context = try!(unsafe { context::Context::new(glutin_backend, checked, debug) });
Ok(Headless { context: context, glutin: glutin_context })
}
#[inline]
pub fn draw(&self) -> Frame {
Frame::new(self.context.clone(), self.get_framebuffer_dimensions())
}
}