1
0
Fork 0
forked from wry/wry

autocommit 2022-01-25 16:45:44 CET

This commit is contained in:
Julian Orth 2022-01-25 16:45:44 +01:00
parent 0336bf3bde
commit c340df0d08
59 changed files with 3085 additions and 1710 deletions

28
src/render/mod.rs Normal file
View file

@ -0,0 +1,28 @@
use crate::ifs::wl_buffer::WlBuffer;
use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel;
use crate::ifs::wl_surface::WlSurface;
use crate::tree::ContainerNode;
use crate::tree::{FloatNode, OutputNode, WorkspaceNode};
pub mod pixman;
bitflags::bitflags! {
pub struct Border: u32 {
const NONE = 0b0000;
const LEFT = 0b0001;
const TOP = 0b0010;
const RIGHT = 0b0100;
const BOTTOM = 0b1000;
const ALL = 0b1111;
}
}
pub trait Renderer {
fn render_output(&mut self, output: &OutputNode);
fn render_workspace(&mut self, workspace: &WorkspaceNode);
fn render_container(&mut self, container: &ContainerNode, x: i32, y: i32);
fn render_toplevel(&mut self, toplevel: &XdgToplevel, x: i32, y: i32);
fn render_surface(&mut self, surface: &WlSurface, x: i32, y: i32);
fn render_buffer(&mut self, buffer: &WlBuffer, x: i32, y: i32);
fn render_floating(&mut self, floating: &FloatNode, x: i32, y: i32);
}

203
src/render/pixman.rs Normal file
View file

@ -0,0 +1,203 @@
use crate::ifs::wl_buffer::WlBuffer;
use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel;
use crate::ifs::wl_surface::WlSurface;
use crate::pixman::Image;
use crate::render::{Border, Renderer};
use crate::servermem::ServerMem;
use crate::tree::{
ContainerFocus, ContainerNode, ContainerSplit, CONTAINER_BORDER, CONTAINER_TITLE_HEIGHT,
};
use crate::tree::{FloatNode, OutputNode, WorkspaceNode};
use std::ops::Deref;
use std::rc::Rc;
pub struct PixmanRenderer<'a> {
image: &'a Image<Rc<ServerMem>>,
}
const NON_COLOR: (u8, u8, u8) = (100, 100, 100);
const CHILD_COLOR: (u8, u8, u8) = (200, 200, 200);
const YES_COLOR: (u8, u8, u8) = (0, 0, 255);
fn focus_color(focus: ContainerFocus) -> (u8, u8, u8) {
match focus {
ContainerFocus::None => NON_COLOR,
ContainerFocus::Child => CHILD_COLOR,
ContainerFocus::Yes => YES_COLOR,
}
}
impl<'a> PixmanRenderer<'a> {
pub fn new(image: &'a Image<Rc<ServerMem>>) -> Self {
Self { image }
}
}
impl Renderer for PixmanRenderer<'_> {
fn render_output(&mut self, output: &OutputNode) {
if let Some(ws) = output.workspace.get() {
self.render_workspace(&ws);
}
}
fn render_workspace(&mut self, workspace: &WorkspaceNode) {
if let Some(node) = workspace.container.get() {
self.render_container(&node, 0, 0)
}
}
fn render_container(&mut self, container: &ContainerNode, x: i32, y: i32) {
let cwidth = container.width.get();
let cheight = container.height.get();
let num_children = container.num_children();
if let Some(child) = container.mono_child.get() {
let space_per_child = cwidth / num_children as i32;
let mut rem = cwidth % num_children as i32;
let mut pos = x;
for child in container.children.iter() {
let (r, g, b) = focus_color(child.focus.get());
let mut width = space_per_child;
if rem > 0 {
rem -= 1;
width += 1;
}
let _ = self.image.fill_rect(
r,
g,
b,
255,
pos,
y,
pos + width as i32,
y + CONTAINER_TITLE_HEIGHT as i32,
);
pos += width as i32;
}
self.image.with_clip(container.mono_body.get(), || {
let content = container.mono_content.get();
child
.node
.render(self, x + content.x1(), y + content.y1());
});
} else {
let split = container.split.get();
for (i, child) in container.children.iter().enumerate() {
let body = child.body.get();
if body.x1() >= cwidth || body.y1() >= cheight {
break;
}
let (r, g, b) = focus_color(child.focus.get());
let _ = self.image.fill_rect(
r,
g,
b,
255,
x + body.x1(),
y + body.y1() - CONTAINER_TITLE_HEIGHT,
x + body.x2(),
y + body.y1(),
);
{
let mut x1 = x + body.x1();
let mut x2 = x + body.x2();
let mut y2 = y + body.y2();
let mut border = Border::empty();
if i < num_children {
if split == ContainerSplit::Horizontal {
border |= Border::RIGHT;
x2 += CONTAINER_BORDER;
} else if split == ContainerSplit::Vertical {
border |= Border::BOTTOM;
y2 += CONTAINER_BORDER;
}
}
if i > 0 && split == ContainerSplit::Horizontal {
border |= Border::LEFT;
x1 -= CONTAINER_BORDER;
}
let _ = self.image.fill_inner_border(
r,
g,
b,
255,
x1,
y + body.y1() - CONTAINER_TITLE_HEIGHT,
x2,
y2,
CONTAINER_BORDER as i32,
border,
);
}
self.image.with_clip(body, || {
let content = child.content.get();
child.node.render(self, x + content.x1(), y + content.y1());
self.image.fill_inner_border(0, 0, 255, 255, x + body.x1(), y + body.y1(), x + body.x1() + body.width(), y + body.y1() + body.height(), 2, Border::all());
self.image.fill_inner_border(255, 0, 0, 255, x + content.x1(), y + content.y1(), x + content.x1() + content.width(), y + content.y1() + content.height(), 2, Border::all());
});
}
}
}
fn render_toplevel(&mut self, tl: &XdgToplevel, mut x: i32, mut y: i32) {
let surface = &tl.xdg.surface;
if let Some(geo) = tl.xdg.geometry() {
let (xt, yt) = geo.translate(x, y);
x = xt;
y = yt;
}
self.render_surface(surface, x, y);
}
fn render_surface(&mut self, surface: &WlSurface, x: i32, y: i32) {
let children = surface.children.borrow();
let buffer = match surface.buffer.get() {
Some(b) => b,
_ => {
log::warn!("surface has no buffer attached");
return
},
};
if let Some(children) = children.deref() {
macro_rules! render {
($children:expr) => {
for child in $children.rev_iter() {
if child.pending.get() {
continue;
}
let pos = child.sub_surface.position.get();
self.render_surface(&child.sub_surface.surface, x + pos.x1(), y + pos.y1());
}
};
}
render!(&children.above);
self.render_buffer(&buffer, x, y);
render!(&children.below);
} else {
self.render_buffer(&buffer, x, y);
}
let mut fr = surface.frame_requests.borrow_mut();
for cb in fr.drain(..) {
surface.client.dispatch_frame_requests.push(cb);
}
}
fn render_buffer(&mut self, buffer: &WlBuffer, x: i32, y: i32) {
if let Err(e) = self.image.add_image(&buffer.image, x, y) {
let client = &buffer.client;
log::error!("Could not access client {} memory: {:#}", client.id, e);
if let Ok(d) = client.display() {
client.fatal_event(
d.implementation_error(format!("Could not access memory: {:#}", e)),
);
} else {
client.state.clients.kill(client.id);
}
}
}
fn render_floating(&mut self, floating: &FloatNode, x: i32, y: i32) {
if let Some(child) = floating.child.get() {
child.render(self, x, y)
}
}
}

0
src/render/util.rs Normal file
View file