|
|
|
@ -24,19 +24,21 @@ use std::sync::Arc; |
|
|
|
use std::ptr; //::{null, null_mut};
|
|
|
|
use std::thread;
|
|
|
|
use std::sync::mpsc;
|
|
|
|
use std::ops::{Add, Sub, Div};
|
|
|
|
|
|
|
|
use crate::easel::{Easel, Canvas, Drawable, Coordinate, Coordinates};
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct XcbEasel (Arc<xcb::Connection>, i32);
|
|
|
|
|
|
|
|
pub struct XcbCanvas<'a> { conn :Arc<xcb::Connection>
|
|
|
|
, width :u16 |
|
|
|
, height :u16 |
|
|
|
, window :u32 |
|
|
|
, pixmap :u32 |
|
|
|
, gc :u32 |
|
|
|
, shm :Box<&'a mut [u32]> }
|
|
|
|
pub struct XcbCanvas<'a, T> { conn :Arc<xcb::Connection>
|
|
|
|
, width :u16 |
|
|
|
, height :u16 |
|
|
|
, window :u32 |
|
|
|
, pixmap :u32 |
|
|
|
, gc :u32 |
|
|
|
, zbuf :Vec<T>
|
|
|
|
, shm :Box<&'a mut [u32]> }
|
|
|
|
|
|
|
|
impl XcbEasel {
|
|
|
|
pub fn new() -> Result<XcbEasel, xcb::ConnError> {
|
|
|
|
@ -55,7 +57,10 @@ impl XcbEasel { |
|
|
|
self.setup().roots().nth(*num as usize)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn canvas<'a>(&self, width :u16, height :u16) -> Option<XcbCanvas<'a>> {
|
|
|
|
pub fn canvas<'a, T>( &self
|
|
|
|
, width :u16 |
|
|
|
, height :u16) -> Option<XcbCanvas<'a, T>>
|
|
|
|
where T: Clone + From<i32> {
|
|
|
|
let Self(conn, _) = self;
|
|
|
|
let conn = conn.clone();
|
|
|
|
let screen = match self.screen() {
|
|
|
|
@ -80,6 +85,7 @@ impl XcbEasel { |
|
|
|
, &[ (xcb::GC_FOREGROUND, screen.white_pixel())
|
|
|
|
, (xcb::GC_GRAPHICS_EXPOSURES, 0) ] );
|
|
|
|
|
|
|
|
let zbuf :Vec<T> = vec!(0.into(); (width * height) as usize);
|
|
|
|
let (shmid, shm) = getshm((width * height) as usize);
|
|
|
|
xcb::shm::attach(&conn, shmseg, shmid as u32, false);
|
|
|
|
unsafe { libc::shmctl(shmid, libc::IPC_RMID, ptr::null_mut()); }
|
|
|
|
@ -96,11 +102,12 @@ impl XcbEasel { |
|
|
|
, window: window
|
|
|
|
, pixmap: pixmap
|
|
|
|
, gc: gc
|
|
|
|
, zbuf: zbuf
|
|
|
|
, shm: Box::new(shm) } )
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> XcbCanvas<'a> {
|
|
|
|
impl<'a, T> XcbCanvas<'a, T> {
|
|
|
|
pub fn set_title(&self, title :&str) {
|
|
|
|
let c = xcb::change_property_checked( &self.conn
|
|
|
|
, xcb::PROP_MODE_REPLACE as u8
|
|
|
|
@ -129,7 +136,9 @@ fn getshm<'a>(size :usize) -> (i32, &'a mut [u32]) { |
|
|
|
|
|
|
|
impl Easel for XcbEasel {}
|
|
|
|
|
|
|
|
impl<'a,T> Canvas<T> for XcbCanvas<'a> {
|
|
|
|
impl<'a, T> Canvas<T> for XcbCanvas<'a, T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Div<Output = T>
|
|
|
|
+ Copy + From<i32> + PartialOrd {
|
|
|
|
fn init_events(&self) {
|
|
|
|
let mask = [( xcb::CW_EVENT_MASK, xcb::EVENT_MASK_EXPOSURE
|
|
|
|
| xcb::EVENT_MASK_KEY_PRESS
|
|
|
|
@ -216,6 +225,7 @@ impl<'a,T> Canvas<T> for XcbCanvas<'a> { |
|
|
|
}
|
|
|
|
|
|
|
|
fn clear(&mut self) {
|
|
|
|
self.zbuf = vec!(0.into(); self.zbuf.len());
|
|
|
|
unsafe {
|
|
|
|
let ptr = self.shm.as_mut_ptr();
|
|
|
|
ptr::write_bytes( ptr, 0
|
|
|
|
@ -227,9 +237,12 @@ impl<'a,T> Canvas<T> for XcbCanvas<'a> { |
|
|
|
let Coordinates(c) = d.plot();
|
|
|
|
let Coordinate(xofs, yofs, _) = ofs;
|
|
|
|
|
|
|
|
for Coordinate(x, y, _) in c {
|
|
|
|
for Coordinate(x, y, zr) in c {
|
|
|
|
let idx :usize = ((y+yofs)*(self.width as i32)+x+xofs) as usize;
|
|
|
|
self.shm[idx] = color;
|
|
|
|
if self.zbuf[idx] < zr {
|
|
|
|
self.zbuf[idx] = zr;
|
|
|
|
self.shm[idx] = color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@ -241,11 +254,13 @@ impl<'a,T> Canvas<T> for XcbCanvas<'a> { |
|
|
|
}
|
|
|
|
|
|
|
|
fn set_pixel(&mut self, c :Coordinate<T>, color :u32) {
|
|
|
|
let Coordinate(x, y, _) = c;
|
|
|
|
let Coordinate(x, y, zr) = c;
|
|
|
|
let idx :usize = (y * (self.width as i32) + x) as usize;
|
|
|
|
|
|
|
|
//print!("({}, {})", idx, color);
|
|
|
|
self.shm[idx] = color;
|
|
|
|
if self.zbuf[idx] < zr {
|
|
|
|
self.zbuf[idx] = zr;
|
|
|
|
self.shm[idx] = color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn show(&self) {
|
|
|
|
|