Added better error handling
This commit is contained in:
parent
e4b1917333
commit
dc6fc474be
8 changed files with 136 additions and 105 deletions
|
|
@ -6,6 +6,7 @@ authors = ["David Johnson <john01dav@gmail.com>"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
thiserror = "1.0.30"
|
||||||
raw-window-handle = "0.4.2"
|
raw-window-handle = "0.4.2"
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
|
|
|
||||||
28
README.md
28
README.md
|
|
@ -52,15 +52,15 @@ For now, the priority for new platforms is:
|
||||||
Example
|
Example
|
||||||
==
|
==
|
||||||
```no_run
|
```no_run
|
||||||
|
use softbuffer::GraphicsContext;
|
||||||
use winit::event::{Event, WindowEvent};
|
use winit::event::{Event, WindowEvent};
|
||||||
use winit::event_loop::{ControlFlow, EventLoop};
|
use winit::event_loop::{ControlFlow, EventLoop};
|
||||||
use winit::window::WindowBuilder;
|
use winit::window::WindowBuilder;
|
||||||
use softbuffer::GraphicsContext;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
let mut graphics_context = unsafe { GraphicsContext::new(window) };
|
let mut graphics_context = unsafe { GraphicsContext::new(window) }.unwrap();
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
*control_flow = ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
|
|
@ -71,26 +71,28 @@ fn main() {
|
||||||
let size = graphics_context.window().inner_size();
|
let size = graphics_context.window().inner_size();
|
||||||
(size.width, size.height)
|
(size.width, size.height)
|
||||||
};
|
};
|
||||||
let buffer = (0..((width*height) as usize)).map(|index|{
|
let buffer = (0..((width * height) as usize))
|
||||||
let y = index / (width as usize);
|
.map(|index| {
|
||||||
let x = index % (width as usize);
|
let y = index / (width as usize);
|
||||||
let red = x % 255;
|
let x = index % (width as usize);
|
||||||
let green = y % 255;
|
let red = x % 255;
|
||||||
let blue = (x*y) % 255;
|
let green = y % 255;
|
||||||
|
let blue = (x * y) % 255;
|
||||||
|
|
||||||
let color = blue | (green << 8) | (red << 16);
|
let color = blue | (green << 8) | (red << 16);
|
||||||
|
|
||||||
color as u32
|
color as u32
|
||||||
}).collect::<Vec<_>>();
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
graphics_context.set_buffer(&buffer, width as u16, height as u16);
|
graphics_context.set_buffer(&buffer, width as u16, height as u16);
|
||||||
}
|
}
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
event: WindowEvent::CloseRequested,
|
event: WindowEvent::CloseRequested,
|
||||||
window_id
|
window_id,
|
||||||
} if window_id == graphics_context.window().id() => {
|
} if window_id == graphics_context.window().id() => {
|
||||||
*control_flow = ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
},
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
|
use softbuffer::GraphicsContext;
|
||||||
use winit::event::{Event, WindowEvent};
|
use winit::event::{Event, WindowEvent};
|
||||||
use winit::event_loop::{ControlFlow, EventLoop};
|
use winit::event_loop::{ControlFlow, EventLoop};
|
||||||
use winit::window::WindowBuilder;
|
use winit::window::WindowBuilder;
|
||||||
use softbuffer::GraphicsContext;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
let mut graphics_context = unsafe { GraphicsContext::new(window) };
|
let mut graphics_context = unsafe { GraphicsContext::new(window) }.unwrap();
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
*control_flow = ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
|
|
@ -17,27 +17,29 @@ fn main() {
|
||||||
let size = graphics_context.window().inner_size();
|
let size = graphics_context.window().inner_size();
|
||||||
(size.width, size.height)
|
(size.width, size.height)
|
||||||
};
|
};
|
||||||
let buffer = (0..((width*height) as usize)).map(|index|{
|
let buffer = (0..((width * height) as usize))
|
||||||
let y = index / (width as usize);
|
.map(|index| {
|
||||||
let x = index % (width as usize);
|
let y = index / (width as usize);
|
||||||
let red = x % 255;
|
let x = index % (width as usize);
|
||||||
let green = y % 255;
|
let red = x % 255;
|
||||||
let blue = (x*y) % 255;
|
let green = y % 255;
|
||||||
|
let blue = (x * y) % 255;
|
||||||
|
|
||||||
let color = blue | (green << 8) | (red << 16);
|
let color = blue | (green << 8) | (red << 16);
|
||||||
|
|
||||||
color as u32
|
color as u32
|
||||||
}).collect::<Vec<_>>();
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
graphics_context.set_buffer(&buffer, width as u16, height as u16);
|
graphics_context.set_buffer(&buffer, width as u16, height as u16);
|
||||||
}
|
}
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
event: WindowEvent::CloseRequested,
|
event: WindowEvent::CloseRequested,
|
||||||
window_id
|
window_id,
|
||||||
} if window_id == graphics_context.window().id() => {
|
} if window_id == graphics_context.window().id() => {
|
||||||
*control_flow = ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
},
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
use softbuffer::GraphicsContext;
|
||||||
use winit::event::{Event, WindowEvent};
|
use winit::event::{Event, WindowEvent};
|
||||||
use winit::event_loop::{ControlFlow, EventLoop};
|
use winit::event_loop::{ControlFlow, EventLoop};
|
||||||
use winit::window::WindowBuilder;
|
use winit::window::WindowBuilder;
|
||||||
use softbuffer::GraphicsContext;
|
|
||||||
|
|
||||||
const BUFFER_WIDTH: usize = 256;
|
const BUFFER_WIDTH: usize = 256;
|
||||||
const BUFFER_HEIGHT: usize = 128;
|
const BUFFER_HEIGHT: usize = 128;
|
||||||
|
|
@ -9,34 +9,36 @@ const BUFFER_HEIGHT: usize = 128;
|
||||||
fn main() {
|
fn main() {
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
let mut graphics_context = unsafe { GraphicsContext::new(window) };
|
let mut graphics_context = unsafe { GraphicsContext::new(window) }.unwrap();
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
*control_flow = ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::RedrawRequested(window_id) if window_id == graphics_context.window().id() => {
|
Event::RedrawRequested(window_id) if window_id == graphics_context.window().id() => {
|
||||||
let buffer = (0..((BUFFER_WIDTH*BUFFER_HEIGHT) as usize)).map(|index|{
|
let buffer = (0..((BUFFER_WIDTH * BUFFER_HEIGHT) as usize))
|
||||||
let y = index / (BUFFER_WIDTH as usize);
|
.map(|index| {
|
||||||
let x = index % (BUFFER_WIDTH as usize);
|
let y = index / (BUFFER_WIDTH as usize);
|
||||||
let red = x % 255;
|
let x = index % (BUFFER_WIDTH as usize);
|
||||||
let green = y % 255;
|
let red = x % 255;
|
||||||
let blue = (x*y) % 255;
|
let green = y % 255;
|
||||||
|
let blue = (x * y) % 255;
|
||||||
|
|
||||||
let color = blue | (green << 8) | (red << 16);
|
let color = blue | (green << 8) | (red << 16);
|
||||||
|
|
||||||
color as u32
|
color as u32
|
||||||
}).collect::<Vec<_>>();
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
graphics_context.set_buffer(&buffer, BUFFER_WIDTH as u16, BUFFER_HEIGHT as u16);
|
graphics_context.set_buffer(&buffer, BUFFER_WIDTH as u16, BUFFER_HEIGHT as u16);
|
||||||
}
|
}
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
event: WindowEvent::CloseRequested,
|
event: WindowEvent::CloseRequested,
|
||||||
window_id
|
window_id,
|
||||||
} if window_id == graphics_context.window().id() => {
|
} if window_id == graphics_context.window().id() => {
|
||||||
*control_flow = ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
},
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
src/error.rs
Normal file
17
src/error.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
use std::error::Error;
|
||||||
|
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum SoftBufferError<W: HasRawWindowHandle> {
|
||||||
|
#[error(
|
||||||
|
"The provided window returned an unsupported platform: {human_readable_platform_name}."
|
||||||
|
)]
|
||||||
|
UnsupportedPlatform {
|
||||||
|
window: W,
|
||||||
|
human_readable_platform_name: &'static str,
|
||||||
|
handle: RawWindowHandle,
|
||||||
|
},
|
||||||
|
#[error("Platform error")]
|
||||||
|
PlatformError(Option<String>, Option<Box<dyn Error>>)
|
||||||
|
}
|
||||||
51
src/lib.rs
51
src/lib.rs
|
|
@ -1,9 +1,12 @@
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
mod x11;
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
mod win32;
|
mod win32;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
mod x11;
|
||||||
|
|
||||||
|
mod error;
|
||||||
|
pub use error::SoftBufferError;
|
||||||
|
|
||||||
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
||||||
|
|
||||||
|
|
@ -11,43 +14,46 @@ use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
||||||
/// write to a window on that platform. This struct owns the window that this data corresponds to
|
/// write to a window on that platform. This struct owns the window that this data corresponds to
|
||||||
/// to ensure safety, as that data must be destroyed before the window itself is destroyed. You may
|
/// to ensure safety, as that data must be destroyed before the window itself is destroyed. You may
|
||||||
/// access the underlying window via [`window`](Self::window) and [`window_mut`](Self::window_mut).
|
/// access the underlying window via [`window`](Self::window) and [`window_mut`](Self::window_mut).
|
||||||
pub struct GraphicsContext<W: HasRawWindowHandle>{
|
pub struct GraphicsContext<W: HasRawWindowHandle> {
|
||||||
window: W,
|
window: W,
|
||||||
graphics_context_impl: Box<dyn GraphicsContextImpl>
|
graphics_context_impl: Box<dyn GraphicsContextImpl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: HasRawWindowHandle> GraphicsContext<W> {
|
impl<W: HasRawWindowHandle> GraphicsContext<W> {
|
||||||
|
|
||||||
/// Creates a new instance of this struct, consuming the given window.
|
/// Creates a new instance of this struct, consuming the given window.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// - Ensure that the passed object is valid to draw a 2D buffer to
|
/// - Ensure that the passed object is valid to draw a 2D buffer to
|
||||||
pub unsafe fn new(window: W) -> Self{
|
pub unsafe fn new(window: W) -> Result<Self, SoftBufferError<W>> {
|
||||||
let raw_handle = window.raw_window_handle();
|
let raw_handle = window.raw_window_handle();
|
||||||
let imple = match raw_handle{
|
let imple = match raw_handle {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
RawWindowHandle::Xlib(xlib_handle) => Box::new(x11::X11Impl::new(xlib_handle)),
|
RawWindowHandle::Xlib(xlib_handle) => Box::new(x11::X11Impl::new(xlib_handle)?),
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
RawWindowHandle::Win32(win32_handle) => Box::new(win32::Win32Impl::new(&win32_handle)),
|
RawWindowHandle::Win32(win32_handle) => Box::new(win32::Win32Impl::new(&win32_handle)?),
|
||||||
unimplemented_handle_type => unimplemented!("Unsupported window handle type: {}.", window_handle_type_name(&unimplemented_handle_type))
|
unimplemented_handle_type => return Err(SoftBufferError::UnsupportedPlatform {
|
||||||
|
window,
|
||||||
|
human_readable_platform_name: window_handle_type_name(&unimplemented_handle_type),
|
||||||
|
handle: unimplemented_handle_type,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
Self{
|
Ok(Self {
|
||||||
window,
|
window,
|
||||||
graphics_context_impl: imple
|
graphics_context_impl: imple,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets shared access to the underlying window
|
/// Gets shared access to the underlying window
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn window(&self) -> &W{
|
pub fn window(&self) -> &W {
|
||||||
&self.window
|
&self.window
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets mut/exclusive access to the underlying window
|
/// Gets mut/exclusive access to the underlying window
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn window_mut(&mut self) -> &mut W{
|
pub fn window_mut(&mut self) -> &mut W {
|
||||||
&mut self.window
|
&mut self.window
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,8 +81,8 @@ impl<W: HasRawWindowHandle> GraphicsContext<W> {
|
||||||
/// G: Green channel
|
/// G: Green channel
|
||||||
/// B: Blue channel
|
/// B: Blue channel
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16){
|
pub fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) {
|
||||||
if (width as usize)*(height as usize) != buffer.len(){
|
if (width as usize) * (height as usize) != buffer.len() {
|
||||||
panic!("The size of the passed buffer is not the correct size. Its length must be exactly width*height.");
|
panic!("The size of the passed buffer is not the correct size. Its length must be exactly width*height.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -84,15 +90,14 @@ impl<W: HasRawWindowHandle> GraphicsContext<W> {
|
||||||
self.graphics_context_impl.set_buffer(buffer, width, height);
|
self.graphics_context_impl.set_buffer(buffer, width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait GraphicsContextImpl{
|
trait GraphicsContextImpl {
|
||||||
unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16);
|
unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window_handle_type_name(handle: &RawWindowHandle) -> &'static str{
|
fn window_handle_type_name(handle: &RawWindowHandle) -> &'static str {
|
||||||
match handle{
|
match handle {
|
||||||
RawWindowHandle::Xlib(_) => "Xlib",
|
RawWindowHandle::Xlib(_) => "Xlib",
|
||||||
RawWindowHandle::Win32(_) => "Win32",
|
RawWindowHandle::Win32(_) => "Win32",
|
||||||
RawWindowHandle::WinRt(_) => "WinRt",
|
RawWindowHandle::WinRt(_) => "WinRt",
|
||||||
|
|
@ -102,6 +107,6 @@ fn window_handle_type_name(handle: &RawWindowHandle) -> &'static str{
|
||||||
RawWindowHandle::AppKit(_) => "AppKit",
|
RawWindowHandle::AppKit(_) => "AppKit",
|
||||||
RawWindowHandle::Orbital(_) => "Orbital",
|
RawWindowHandle::Orbital(_) => "Orbital",
|
||||||
RawWindowHandle::UiKit(_) => "UiKit",
|
RawWindowHandle::UiKit(_) => "UiKit",
|
||||||
_ => "Unknown Name" //don't completely fail to compile if there is a new raw window handle type that's added at some point
|
_ => "Unknown Name", //don't completely fail to compile if there is a new raw window handle type that's added at some point
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
37
src/win32.rs
37
src/win32.rs
|
|
@ -1,13 +1,13 @@
|
||||||
|
use crate::{GraphicsContextImpl, SoftBufferError};
|
||||||
|
use raw_window_handle::{HasRawWindowHandle, Win32Handle};
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
use raw_window_handle::Win32Handle;
|
use winapi::shared::windef::{HDC, HWND};
|
||||||
use crate::GraphicsContextImpl;
|
use winapi::um::wingdi::{StretchDIBits, BITMAPINFOHEADER, BI_BITFIELDS, RGBQUAD};
|
||||||
use winapi::um::wingdi::{BITMAPINFOHEADER, BI_BITFIELDS, RGBQUAD, StretchDIBits};
|
use winapi::um::winuser::{GetDC, ValidateRect};
|
||||||
use winapi::um::winuser::{ValidateRect, GetDC};
|
|
||||||
use winapi::shared::windef::{HWND, HDC};
|
|
||||||
|
|
||||||
pub struct Win32Impl{
|
pub struct Win32Impl {
|
||||||
window: HWND,
|
window: HWND,
|
||||||
dc: HDC
|
dc: HDC,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap this so we can have a proper number of bmiColors to write in
|
// Wrap this so we can have a proper number of bmiColors to write in
|
||||||
|
|
@ -19,15 +19,20 @@ struct BitmapInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Win32Impl {
|
impl Win32Impl {
|
||||||
|
pub unsafe fn new<W: HasRawWindowHandle>(handle: &Win32Handle) -> Result<Self, crate::SoftBufferError<W>> {
|
||||||
pub unsafe fn new(handle: &Win32Handle) -> Self{
|
|
||||||
let dc = GetDC(handle.hwnd as HWND);
|
let dc = GetDC(handle.hwnd as HWND);
|
||||||
Self{
|
|
||||||
dc,
|
|
||||||
window: handle.hwnd as HWND
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if dc.is_null(){
|
||||||
|
return Err(SoftBufferError::PlatformError(Some("Device Context is null".into()), None));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
Self {
|
||||||
|
dc,
|
||||||
|
window: handle.hwnd as HWND,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GraphicsContextImpl for Win32Impl {
|
impl GraphicsContextImpl for Win32Impl {
|
||||||
|
|
@ -57,9 +62,9 @@ impl GraphicsContextImpl for Win32Impl {
|
||||||
std::mem::transmute(buffer.as_ptr()),
|
std::mem::transmute(buffer.as_ptr()),
|
||||||
std::mem::transmute(&bitmap_info),
|
std::mem::transmute(&bitmap_info),
|
||||||
winapi::um::wingdi::DIB_RGB_COLORS,
|
winapi::um::wingdi::DIB_RGB_COLORS,
|
||||||
winapi::um::wingdi::SRCCOPY
|
winapi::um::wingdi::SRCCOPY,
|
||||||
);
|
);
|
||||||
|
|
||||||
ValidateRect(self.window, std::ptr::null_mut());
|
ValidateRect(self.window, std::ptr::null_mut());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
47
src/x11.rs
47
src/x11.rs
|
|
@ -1,38 +1,40 @@
|
||||||
|
use crate::{GraphicsContextImpl, SoftBufferError};
|
||||||
|
use raw_window_handle::{HasRawWindowHandle, XlibHandle};
|
||||||
use std::os::raw::{c_char, c_uint};
|
use std::os::raw::{c_char, c_uint};
|
||||||
use raw_window_handle::XlibHandle;
|
use x11_dl::xlib::{Display, Visual, Xlib, ZPixmap, GC};
|
||||||
use x11_dl::xlib::{Display, GC, Visual, Xlib, ZPixmap};
|
|
||||||
use crate::GraphicsContextImpl;
|
|
||||||
|
|
||||||
pub struct X11Impl{
|
pub struct X11Impl {
|
||||||
handle: XlibHandle,
|
handle: XlibHandle,
|
||||||
lib: Xlib,
|
lib: Xlib,
|
||||||
gc: GC,
|
gc: GC,
|
||||||
visual: *mut Visual,
|
visual: *mut Visual,
|
||||||
depth: i32
|
depth: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl X11Impl {
|
impl X11Impl {
|
||||||
|
pub unsafe fn new<W: HasRawWindowHandle>(handle: XlibHandle) -> Result<Self, SoftBufferError<W>> {
|
||||||
pub unsafe fn new(handle: XlibHandle) -> Self{
|
let lib = match Xlib::open() {
|
||||||
let lib = Xlib::open().unwrap();
|
Ok(lib) => lib,
|
||||||
|
Err(e) => return Err(SoftBufferError::PlatformError(Some("Failed to open Xlib".into()), Some(Box::new(e))))
|
||||||
|
};
|
||||||
let screen = (lib.XDefaultScreen)(handle.display as *mut Display);
|
let screen = (lib.XDefaultScreen)(handle.display as *mut Display);
|
||||||
let gc = (lib.XDefaultGC)(handle.display as *mut Display, screen);
|
let gc = (lib.XDefaultGC)(handle.display as *mut Display, screen);
|
||||||
let visual = (lib.XDefaultVisual)(handle.display as *mut Display, screen);
|
let visual = (lib.XDefaultVisual)(handle.display as *mut Display, screen);
|
||||||
let depth = (lib.XDefaultDepth)(handle.display as *mut Display, screen);
|
let depth = (lib.XDefaultDepth)(handle.display as *mut Display, screen);
|
||||||
|
|
||||||
Self{
|
Ok(
|
||||||
handle,
|
Self {
|
||||||
lib,
|
handle,
|
||||||
gc,
|
lib,
|
||||||
visual,
|
gc,
|
||||||
depth
|
visual,
|
||||||
}
|
depth,
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GraphicsContextImpl for X11Impl {
|
impl GraphicsContextImpl for X11Impl {
|
||||||
|
|
||||||
unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) {
|
unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) {
|
||||||
//create image
|
//create image
|
||||||
let image = (self.lib.XCreateImage)(
|
let image = (self.lib.XCreateImage)(
|
||||||
|
|
@ -45,13 +47,9 @@ impl GraphicsContextImpl for X11Impl {
|
||||||
width as u32,
|
width as u32,
|
||||||
height as u32,
|
height as u32,
|
||||||
32,
|
32,
|
||||||
(width*4) as i32
|
(width * 4) as i32,
|
||||||
);
|
);
|
||||||
|
|
||||||
if image.is_null(){
|
|
||||||
panic!("Image is null!");
|
|
||||||
}
|
|
||||||
|
|
||||||
//push image to window
|
//push image to window
|
||||||
(self.lib.XPutImage)(
|
(self.lib.XPutImage)(
|
||||||
self.handle.display as *mut Display,
|
self.handle.display as *mut Display,
|
||||||
|
|
@ -63,11 +61,10 @@ impl GraphicsContextImpl for X11Impl {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
width as c_uint,
|
width as c_uint,
|
||||||
height as c_uint
|
height as c_uint,
|
||||||
);
|
);
|
||||||
|
|
||||||
(*image).data = std::ptr::null_mut();
|
(*image).data = std::ptr::null_mut();
|
||||||
(self.lib.XDestroyImage)(image);
|
(self.lib.XDestroyImage)(image);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue