Fix all the things

This commit is contained in:
Kenny Levinsen
2019-07-30 16:31:42 +02:00
parent 247286fc5e
commit 9d2dd4ec37
6 changed files with 536 additions and 246 deletions
Generated
+24 -10
View File
@@ -114,6 +114,18 @@ dependencies = [
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nix"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nix"
version = "0.14.1"
@@ -156,6 +168,15 @@ dependencies = [
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "os_pipe"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "0.4.30"
@@ -229,14 +250,6 @@ dependencies = [
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "timerfd"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-xid"
version = "0.1.0"
@@ -344,9 +357,9 @@ dependencies = [
"chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
"os_pipe 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rusttype 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
"smithay-client-toolkit 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"timerfd 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -376,11 +389,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
"checksum line_drawing 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9"
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
"checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b"
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
"checksum os_pipe 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce1d819d394515aae0530eae02156fedfc98b4f0359bf3048a442be89a95157b"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
@@ -389,7 +404,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum smithay-client-toolkit 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8c23093ebdaac1ad67558c7aef153522c6b3be7e0257820909e3a25c4519e78d"
"checksum stb_truetype 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "69b7df505db8e81d54ff8be4693421e5b543e08214bd8d99eb761fcb4d5668ba"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum timerfd 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6c9a7822e546fa39d0b5ae14a93a33903975b62af6597288aea77f0580a6abbe"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
+2 -2
View File
@@ -12,5 +12,5 @@ byteorder = "1.0"
rusttype = "0.7.7"
chrono = "0.4"
nix = "0.14"
timerfd = "1.0"
memmap = "0.7"
memmap = "0.7"
os_pipe = "0.8.1"
+104
View File
@@ -0,0 +1,104 @@
use memmap::MmapMut;
use crate::color::Color;
pub struct Buffer<'a> {
buf: &'a mut MmapMut,
dimensions: (u32, u32),
subdimensions: Option<(u32, u32, u32, u32)>,
}
impl<'a> Buffer<'a> {
pub fn new(buf: &'a mut MmapMut, dimensions: (u32, u32)) -> Buffer {
Buffer {
buf: buf,
dimensions: dimensions,
subdimensions: None,
}
}
pub fn get_bounds(&self) -> (u32, u32, u32, u32) {
if let Some(subdim) = self.subdimensions {
subdim
} else {
(0, 0, self.dimensions.0, self.dimensions.1)
}
}
pub fn subdimensions(&mut self, subdimensions: (u32, u32, u32, u32)) -> Buffer {
let bounds = self.get_bounds();
if subdimensions.0 + subdimensions.2 > bounds.2
|| subdimensions.1 + subdimensions.3 > bounds.3
{
panic!(
"cannot create subdimensions larger than buffer: {:?} > {:?}",
subdimensions, bounds
);
}
Buffer {
buf: self.buf,
dimensions: self.dimensions,
subdimensions: Some((
subdimensions.0 + bounds.0,
subdimensions.1 + bounds.1,
subdimensions.2,
subdimensions.3,
)),
}
}
pub fn memset(&mut self, c: &Color) {
unsafe {
let ptr = self.buf.as_mut_ptr();
for p in 0..(self.dimensions.0 * self.dimensions.1) {
*((ptr as *mut u32).offset(p as isize)) = c.as_argb8888();
}
}
}
pub fn highlight_bounds(&mut self, c: &Color) {
let end = if let Some(subdim) = self.subdimensions {
(subdim.2, subdim.3)
} else {
(self.dimensions.0, self.dimensions.1)
};
for x in 0..end.0 {
self.put((x, 0), c);
self.put((x, end.1 - 1), c);
}
for y in 0..end.1 {
self.put((0, y), c);
self.put((end.0 - 1, y), c);
}
}
pub fn put(&mut self, pos: (u32, u32), c: &Color) {
let true_pos = if let Some(subdim) = self.subdimensions {
if pos.0 > subdim.2 || pos.1 > subdim.3 {
panic!(
"put({:?}) is not within subdimensions of buffer ({:?})",
pos, subdim
);
}
(pos.0 + subdim.0, pos.1 + subdim.1)
} else {
if pos.0 >= self.dimensions.0 || pos.1 >= self.dimensions.1 {
panic!(
"put({:?}) is not within dimensions of buffer ({:?})",
pos, self.dimensions
);
}
pos
};
unsafe {
let ptr = self
.buf
.as_mut_ptr()
.offset(4 * (true_pos.0 + (true_pos.1 * self.dimensions.0)) as isize);
*(ptr as *mut u32) = c.as_argb8888();
}
}
}
+66
View File
@@ -0,0 +1,66 @@
#[derive(Debug)]
pub struct Color {
red: f32,
green: f32,
blue: f32,
opacity: f32,
}
impl Color {
pub fn new(red: f32, green: f32, blue: f32, opacity: f32) -> Color {
Color {
red: if red > 1.0 {
1.0
} else if red < 0.0 {
0.0
} else {
red
},
green: if green > 1.0 {
1.0
} else if green < 0.0 {
0.0
} else {
green
},
blue: if blue > 1.0 {
1.0
} else if blue < 0.0 {
0.0
} else {
blue
},
opacity: if opacity > 1.0 {
1.0
} else if opacity < 0.0 {
0.0
} else {
opacity
},
}
}
pub fn blend(&self, other: &Color, ratio: f32) -> Color {
let ratio = if ratio > 1.0 {
1.0
} else if ratio < 0.0 {
0.0
} else {
ratio
};
Color {
red: self.red + ((other.red - self.red) * ratio),
green: self.green + ((other.green - self.green) * ratio),
blue: self.blue + ((other.blue - self.blue) * ratio),
opacity: self.opacity + ((other.opacity - self.opacity) * ratio),
}
}
pub fn as_argb8888(&self) -> u32 {
((255.0 * self.opacity) as u32) << 24
| ((255.0 * self.red) as u32) << 16
| ((255.0 * self.green) as u32) << 8
| ((255.0 * self.red) as u32)
}
}
+295
View File
@@ -0,0 +1,295 @@
use crate::color::Color;
use crate::buffer::Buffer;
use rusttype::{point, Font, Scale};
use chrono::{Date, DateTime, Datelike, Local, Timelike};
static DEJAVUSANS_MONO: &'static [u8] = include_bytes!("../fonts/dejavu/DejaVuSansMono.ttf");
static ROBOTO_REGULAR: &'static [u8] = include_bytes!("../fonts/Roboto-Regular.ttf");
fn draw_text(
font_data: &'static [u8],
buf: &mut Buffer,
background_color: &Color,
color: &Color,
size: f32,
s: &str,
) -> Result<(), ::std::io::Error> {
// Load the font
// This only succeeds if collection consists of one font
let font = Font::from_bytes(font_data as &[u8]).expect("Error constructing Font");
// The font size to use
let scale = Scale::uniform(size);
let v_metrics = font.v_metrics(scale);
// layout the glyphs in a line with 20 pixels padding
let glyphs: Vec<_> = font
.layout(s, scale, point(20.0, 20.0 + v_metrics.ascent))
.collect();
// Loop through the glyphs in the text, positing each one on a line
for glyph in glyphs {
if let Some(bounding_box) = glyph.pixel_bounding_box() {
// Draw the glyph into the image per-pixel by using the draw closure
glyph.draw(|x, y, o| {
let x = x + bounding_box.min.x as u32;
let y = y + bounding_box.min.y as u32;
let o = if o > 1.0 {
1.0
} else if o < 0.0 {
0.0
} else {
o
};
buf.put((x, y), &background_color.blend(color, o));
});
}
}
Ok(())
}
fn draw_text_fixed_width(
font_data: &'static [u8],
buf: &mut Buffer,
background_color: &Color,
color: &Color,
size: f32,
distances: Vec<u32>,
s: &str,
) -> Result<(), ::std::io::Error> {
// Load the font
// This only succeeds if collection consists of one font
let font = Font::from_bytes(font_data as &[u8]).expect("Error constructing Font");
// The font size to use
let scale = Scale::uniform(size);
let v_metrics = font.v_metrics(scale);
// layout the glyphs in a line with 20 pixels padding
let glyphs: Vec<_> = font
.layout(s, scale, point(20.0, 20.0 + v_metrics.ascent))
.collect();
// Loop through the glyphs in the text, positing each one on a line
let mut x_pos: usize = 0;
let mut x_off: u32 = 0;
for glyph in glyphs {
if let Some(bounding_box) = glyph.pixel_bounding_box() {
let x_dist = distances[x_pos];
let width = (bounding_box.max.x - bounding_box.min.x) as u32;
let offset = (x_dist - width) / 2;
// Draw the glyph into the image per-pixel by using the draw closure
glyph.draw(|x, y, o| {
let off = x_off + offset + 20;
let x = x + off as u32;
let y = y + bounding_box.min.y as u32;
let o = if o > 1.0 {
1.0
} else if o < 0.0 {
0.0
} else {
o
};
buf.put((x, y), &background_color.blend(color, o));
});
x_pos += 1;
x_off += x_dist;
}
}
Ok(())
}
pub fn draw_clock(
buf: &mut Buffer,
background_color: &Color,
time: &DateTime<Local>,
) -> Result<(), ::std::io::Error> {
draw_text(
ROBOTO_REGULAR,
&mut buf.subdimensions((0, 0, 448, 96)),
background_color,
&Color::new(1.0, 1.0, 1.0, 1.0),
64.0,
&format!(
"{:?}, {:02}/{:02}/{:4}",
time.weekday(),
time.day(),
time.month(),
time.year()
),
)?;
draw_text_fixed_width(
ROBOTO_REGULAR,
&mut buf.subdimensions((0, 64, 288*2+64, 256)),
background_color,
&Color::new(1.0, 1.0, 1.0, 1.0),
256.0,
vec![120, 120, 64, 120, 120],
&format!("{:02}:{:02}", time.hour(), time.minute()),
)?;
Ok(())
}
fn draw_month(
buf: &mut Buffer,
background_color: &Color,
orig: &Date<Local>,
time: &Date<Local>,
) -> Result<(), ::std::io::Error> {
let mut time = time.clone();
let mut y_off = 1;
let mut done = false;
let month_str = match time.month() {
1 => "January",
2 => "February",
3 => "March",
4 => "April",
5 => "May",
6 => "June",
7 => "July",
8 => "August",
9 => "September",
10 => "October",
11 => "November",
12 => "December",
_ => panic!("impossible value"),
};
//
// Draw the of the month
//
draw_text(
ROBOTO_REGULAR,
&mut buf.subdimensions((0, 0, 364, 96)),
background_color,
&Color::new(1.0, 1.0, 1.0, 1.0),
68.0,
month_str,
)?;
//
// Draw the week day
//
for idx in 1..8 {
let wk_chr = match idx {
1 => "MON",
2 => "TUE",
3 => "WED",
4 => "THU",
5 => "FRI",
6 => "SUN",
7 => "SAT",
_ => panic!("impossible value"),
};
draw_text(
DEJAVUSANS_MONO,
&mut buf.subdimensions((idx * 48 + 4, (y_off * 32) + 64, 64, 64)),
background_color,
&Color::new(0.75, 0.75, 0.75, 1.0),
16.0,
&wk_chr,
)?;
}
y_off += 1;
while !done {
let mut x_pos = 0;
//
// Find the start of this week
//
let mut wkday = time.weekday();
while wkday != chrono::Weekday::Mon {
x_pos += 1;
wkday = wkday.pred();
}
//
// Draw the week number
//
let wk = time.iso_week();
draw_text(
DEJAVUSANS_MONO,
&mut buf.subdimensions((0 * 48, (y_off * 32) + 64, 64, 64)),
background_color,
&Color::new(0.75, 0.75, 0.75, 1.0),
32.0,
&format!("{:02}", wk.week()),
)?;
x_pos += 1;
//
// Draw the dates
//
while x_pos < 8 {
let c = if time.day() == orig.day() && time.month() == orig.month() {
Color::new(1.0, 1.0, 1.0, 1.0)
} else {
Color::new(0.5, 0.5, 0.5, 1.0)
};
draw_text(
DEJAVUSANS_MONO,
&mut buf.subdimensions((x_pos * 48, (y_off * 32) + 64, 64, 64)),
background_color,
&c,
32.0,
&format!("{:02}", time.day()),
)?;
let t = time.with_day(time.day() + 1);
if t.is_none() {
done = true;
break;
}
time = t.unwrap();
x_pos += 1;
}
y_off += 1;
}
Ok(())
}
pub fn draw_calendar(
buf: &mut Buffer,
background_color: &Color,
time: &Date<Local>,
) -> Result<(), ::std::io::Error> {
// ~1546x384px
let t = time.with_day(1).unwrap();
draw_month(
&mut buf.subdimensions((0, 0, 448, 384)),
background_color,
time,
&t.pred().with_day(1).unwrap(),
)?;
draw_month(
&mut buf.subdimensions((512, 0, 448, 384)),
background_color,
time,
&t,
)?;
let n = if t.month() == 12 {
t.with_year(t.year() + 1).unwrap().with_month(1).unwrap()
} else {
t.with_month(t.month() + 1).unwrap()
};
draw_month(
&mut buf.subdimensions((1024, 0, 448, 384)),
background_color,
time,
&n,
)?;
Ok(())
}
+45 -234
View File
@@ -5,17 +5,14 @@ extern crate chrono;
extern crate smithay_client_toolkit as sctk;
use std::collections::VecDeque;
use std::io::{Read, Write};
use std::os::unix::io::AsRawFd;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use memmap::MmapMut;
use nix::poll::{poll, PollFd, PollFlags};
use os_pipe::pipe;
use chrono::{Date, DateTime, Datelike, Local, Timelike};
use rusttype::{point, Font, Scale};
use chrono::{Duration as ChronoDuration, Local, Timelike};
use sctk::keyboard::{map_keyboard_auto_with_repeat, Event as KbEvent, KeyRepeatKind};
use sctk::reexports::client::protocol::wl_shm;
@@ -24,9 +21,15 @@ use sctk::utils::DoubleMemPool;
use sctk::window::{ConceptFrame, Event as WEvent, Window};
use sctk::Environment;
static DEJAVUSANS_MONO: &'static [u8] = include_bytes!("../fonts/dejavu/DejaVuSansMono.ttf");
static ROBOTO_REGULAR: &'static [u8] = include_bytes!("../fonts/Roboto-Regular.ttf");
mod color;
mod buffer;
mod draw;
use crate::color::Color;
use crate::buffer::Buffer;
use crate::draw::{draw_clock, draw_calendar};
#[derive(Debug)]
enum Cmd {
Exit,
Configure,
@@ -43,207 +46,6 @@ struct App {
dimensions: (u32, u32),
}
fn draw_text(
font_data: &'static [u8],
mmap: &mut MmapMut,
pos: (u32, u32),
dimensions: (u32, u32),
size: f32,
color: (u8, u8, u8),
s: &str,
) -> Result<(), ::std::io::Error> {
// Load the font
// This only succeeds if collection consists of one font
let font = Font::from_bytes(font_data as &[u8]).expect("Error constructing Font");
// The font size to use
let scale = Scale::uniform(size);
let v_metrics = font.v_metrics(scale);
// layout the glyphs in a line with 20 pixels padding
let glyphs: Vec<_> = font
.layout(s, scale, point(20.0, 20.0 + v_metrics.ascent))
.collect();
// Loop through the glyphs in the text, positing each one on a line
for glyph in glyphs {
if let Some(bounding_box) = glyph.pixel_bounding_box() {
// Draw the glyph into the image per-pixel by using the draw closure
glyph.draw(|x, y, o| {
let p = (((pos.1 + y + bounding_box.min.y as u32) * dimensions.0)
+ (pos.0 + x + bounding_box.min.x as u32))
* 4;
let a: u32 = 255 << 24;
let r: u32 = (((color.0 as f32) * o) as u32) << 16;
let g: u32 = (((color.1 as f32) * o) as u32) << 8;
let b: u32 = ((color.2 as f32) * o) as u32;
let v = a | r | g | b;
unsafe {
let ptr = mmap.as_mut_ptr().offset(p as isize);
*(ptr as *mut u32) = v;
}
});
}
}
Ok(())
}
fn draw_clock(
mmap: &mut MmapMut,
time: &DateTime<Local>,
pos: (u32, u32),
dimensions: (u32, u32),
) -> Result<(), ::std::io::Error> {
draw_text(
ROBOTO_REGULAR,
mmap,
pos,
dimensions,
64.0,
(255, 255, 255),
&format!(
"{:?}, {:02}/{:02}/{:4}",
time.weekday(),
time.day(),
time.month(),
time.year()
),
)?;
draw_text(
ROBOTO_REGULAR,
mmap,
(pos.0, pos.1 + 64),
dimensions,
256.0,
(255, 255, 255),
&format!("{:02}", time.hour()),
)?;
draw_text(
ROBOTO_REGULAR,
mmap,
(pos.0 + 256, pos.1 + 64),
dimensions,
256.0,
(255, 255, 255),
":",
)?;
draw_text(
ROBOTO_REGULAR,
mmap,
(pos.0 + 320, pos.1 + 64),
dimensions,
256.0,
(255, 255, 255),
&format!("{:02}", time.minute()),
)?;
Ok(())
}
fn draw_month(
mmap: &mut MmapMut,
orig: &Date<Local>,
time: &Date<Local>,
pos: (u32, u32),
dimensions: (u32, u32),
) -> Result<(), ::std::io::Error> {
let mut time = time.clone();
let mut y_off = 1;
let mut done = false;
let month_str = match time.month() {
1 => "January",
2 => "February",
3 => "March",
4 => "April",
5 => "May",
6 => "June",
7 => "July",
8 => "August",
9 => "September",
10 => "October",
11 => "November",
12 => "December",
_ => panic!("impossible value"),
};
draw_text(
ROBOTO_REGULAR,
mmap,
pos,
dimensions,
68.0,
(255, 255, 255),
month_str,
)?;
while !done {
let mut x_pos = 0;
let mut wk = time.weekday();
while wk != chrono::Weekday::Sun {
x_pos += 1;
wk = wk.pred();
}
while x_pos < 7 {
let c = if time.day() == orig.day() && time.month() == orig.month() {
(255, 255, 255)
} else {
(96, 96, 96)
};
draw_text(
DEJAVUSANS_MONO,
mmap,
(pos.0 + (x_pos * 48), pos.1 + (y_off * 32) + 64),
dimensions,
32.0,
c,
&format!("{:02}", time.day()),
)?;
let t = time.with_day(time.day() + 1);
if t.is_none() {
done = true;
break;
}
time = t.unwrap();
x_pos += 1;
}
y_off += 1;
}
Ok(())
}
fn draw_calendar(
mmap: &mut MmapMut,
time: &Date<Local>,
pos: (u32, u32),
dimensions: (u32, u32),
) -> Result<(), ::std::io::Error> {
// ~1546x384px
let t = time.with_day(1).unwrap();
draw_month(
mmap,
time,
&t.pred().with_day(1).unwrap(),
(pos.0, pos.1),
dimensions,
)?;
draw_month(mmap, time, &t, (pos.0 + 512, pos.1), dimensions)?;
let n = if t.month() == 12 {
t.with_year(t.year() + 1).unwrap().with_month(1).unwrap()
} else {
t.with_month(t.month() + 1).unwrap()
};
draw_month(mmap, time, &n, (pos.0 + 1024, pos.1), dimensions)?;
Ok(())
}
impl App {
fn redraw(&mut self) -> Result<(), ::std::io::Error> {
let pool = match self.pools.pool() {
@@ -259,19 +61,18 @@ impl App {
.expect("Failed to resize the memory pool.");
let mmap = pool.mmap();
{
unsafe {
let ptr = mmap.as_mut_ptr();
for p in 0..(buf_x * buf_y) {
*((ptr as *mut u32).offset(p as isize)) = 0xC0000000;
}
}
}
let mut buf = Buffer::new(mmap, self.dimensions);
let bg = Color::new(0.0, 0.0, 0.0, 0.8);
buf.memset(&bg);
let time = Local::now();
draw_clock(mmap, &time, (0, 0), (buf_x, buf_y))?;
draw_calendar(mmap, &time.date(), (0, 384), (buf_x, buf_y))?;
draw_clock(&mut buf.subdimensions((0, 0, 720, 320)), &bg, &time)?;
draw_calendar(
&mut buf.subdimensions((0, 384, 1472, 384)),
&bg,
&time.date(),
)?;
mmap.flush().unwrap();
@@ -376,18 +177,32 @@ impl App {
}
fn main() {
let mut app = App::new((1408u32, 734u32));
let (mut rx_pipe, mut tx_pipe) = pipe().unwrap();
let mut app = App::new((1600u32, 784u32));
let mut last_time = Local::now();
let mut tfd = timerfd::TimerFd::new_custom(timerfd::ClockId::Monotonic, true, true).unwrap();
tfd.set_state(
timerfd::TimerState::Periodic {
current: Duration::from_millis(2000),
interval: Duration::from_millis(2000),
},
timerfd::SetTimeFlags::Default,
);
let worker_queue = app.cmd_queue();
std::thread::spawn(move || loop {
let n = Local::now();
let target = (n + ChronoDuration::seconds(60))
.with_second(0)
.unwrap()
.with_nanosecond(0)
.unwrap();
let d = target - n;
std::thread::sleep(d.to_std().unwrap());
worker_queue.lock().unwrap().push_back(Cmd::MaybeDraw);
tx_pipe.write_all(&[0x1]).unwrap();
});
let mut fds = [
PollFd::new(app.event_queue().get_connection_fd(), PollFlags::POLLIN),
PollFd::new(rx_pipe.as_raw_fd(), PollFlags::POLLIN),
];
let q = app.cmd_queue();
loop {
@@ -417,10 +232,6 @@ fn main() {
None => {
app.flush_display();
let mut fds = [
PollFd::new(app.event_queue().get_connection_fd(), PollFlags::POLLIN),
PollFd::new(tfd.as_raw_fd(), PollFlags::POLLIN),
];
poll(&mut fds, -1).unwrap();
if fds[0].revents().unwrap().contains(PollFlags::POLLIN) {
@@ -441,8 +252,8 @@ fn main() {
}
if fds[1].revents().unwrap().contains(PollFlags::POLLIN) {
tfd.read();
q.lock().unwrap().push_back(Cmd::MaybeDraw);
let mut v: Vec<u8> = vec![0x00];
rx_pipe.read_exact(&mut v).unwrap();
}
}
}