summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-11-11 20:39:00 -0700
committerIrene Knapp <ireneista@irenes.space>2026-11-11 20:39:00 -0700
commit89a6a257f89bba997e778160c53938be371ec6ac (patch)
tree96972e8ebb82cc6363eb8112944bc52c86221755 /src
parentc5f15297d53904ecfb1e2e6e2df915e380eff2e0 (diff)
graphics contexts! with RAII!
much trait refactoring

the way forward to structure this cleanly is clear now, as well, but not implemented yet

Force-Push: yes
Change-Id: Ib3905edcfd49bf19d0fa7e4285f2edfed312d539
Diffstat (limited to 'src')
-rw-r--r--src/main.rs57
-rw-r--r--src/xcontext.rs44
-rw-r--r--src/xtypes.rs29
3 files changed, 113 insertions, 17 deletions
diff --git a/src/main.rs b/src/main.rs
index 2c07e95..57eabf0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,6 @@
 use crate::xtypes::*;
 use crate::xcolor::DisplayColorExt;
+use crate::xcontext::GraphicContext;
 
 use std::sync::Arc;
 
@@ -8,12 +9,16 @@ use xcb::x::{
   self,
   ClientMessageData,
   Cw, CreateWindow,
+  CreateGc, FreeGc,
+  Drawable,
   EventMask,
+  PolyFillRectangle,
   Screen,
   WindowClass
 };
 
 mod xcolor;
+mod xcontext;
 mod xtypes;
 
 
@@ -29,6 +34,7 @@ struct DockConfiguration {
 struct Dock {
   configuration: DockConfiguration,
   window: Window,
+  bounds: Arc<Rectangle<u16>>,
 }
 
 impl HasWindow for Dock {
@@ -52,7 +58,7 @@ fn main() -> xcb::Result<()> {
   // #d4ffcc
   let background_pixel = display.allocate_color(54484, 65535, 52428)?;
 
-  let _dock = Dock::new(Arc::clone(&display), DockConfiguration {
+  let dock = Dock::new(Arc::clone(&display), DockConfiguration {
     thickness: 50,
     side: ScreenSide::Bottom,
     background_pixel,
@@ -60,6 +66,10 @@ fn main() -> xcb::Result<()> {
 
   loop {
     match display.wait_for_event()? {
+      xcb::Event::X(x::Event::Expose(_event)) => {
+	let _ = dock.redraw(); // TODO
+      }
+
       xcb::Event::X(x::Event::ButtonPress(event)) => {
         println!("click {:?}", event);
       }
@@ -88,7 +98,6 @@ impl Dock {
 
     let dock_bounds = Dock::compute_bounds(&screen, &configuration);
 
-    println!("back pixel {:?}", configuration.background_pixel);
     let window = Window::new(Arc::clone(&display), &mut CreateWindow {
       depth: x::COPY_FROM_PARENT as u8,
       wid: x::Window::none(),
@@ -105,15 +114,15 @@ impl Dock {
         Cw::EventMask(EventMask::EXPOSURE | EventMask::BUTTON_PRESS),
       ],
     })?;
-    let dock = Dock { window, configuration };
+    let dock = Dock { window, configuration, bounds: Arc::new(dock_bounds) };
 
-    dock.set_string_property(&x::ATOM_WM_NAME, b"grass bar")?;
+    dock.set_string_property(&x::ATOM_WM_NAME, b"sandbar")?;
 
-    dock.set_atom_property(&display.atoms().wm_protocols,
-                           &[display.atoms().wm_delete_window])?;
+    dock.set_atom_property(&dock.atoms().wm_protocols,
+                           &[dock.atoms().wm_delete_window])?;
 
-    dock.set_atom_property(&display.atoms().wm_type,
-                           &[display.atoms().wm_type_dock])?;
+    dock.set_atom_property(&dock.atoms().wm_type,
+                           &[dock.atoms().wm_type_dock])?;
 
     dock.set_strut_properties(&screen)?;
 
@@ -197,5 +206,37 @@ impl Dock {
       Rectangle { left, top, width, height }
     }
   }
+
+
+  fn redraw(&self) -> xcb::Result<()> {
+    println!("redraw");
+
+    let drawable = Drawable::Window(self.window_id());
+    let _context = GraphicContext::new(Arc::clone(self.display()),
+				       drawable);
+
+    /*
+    let black = self.screen().black_pixel();
+
+    let cookie = connection.send_request_checked(&PolyFillRectangle {
+      drawable: Drawable::Window(self.window_id()),
+      property: *property,
+      r#type: x::ATOM_CARDINAL,
+      data: values,
+    });
+    connection.check_request(cookie)?;
+    */
+
+    Ok(())
+  }
+}
+
+impl HasDisplay for Dock {
+  fn display(&self) -> &Arc<Display> { self.window.display() }
 }
 
+impl HasConnection for Dock {
+  fn connection(&self) -> &Connection { self.window.connection() }
+}
+
+
diff --git a/src/xcontext.rs b/src/xcontext.rs
new file mode 100644
index 0000000..d9543f7
--- /dev/null
+++ b/src/xcontext.rs
@@ -0,0 +1,44 @@
+use crate::xtypes::*;
+
+use std::sync::Arc;
+
+use xcb::x::{ self, Drawable, CreateGc, FreeGc };
+
+
+pub struct GraphicContext {
+  display: Arc<Display>,
+  context_id: x::Gcontext,
+}
+
+
+impl GraphicContext {
+  pub fn new(display: Arc<Display>, drawable: Drawable)
+    -> xcb::Result<Self>
+  {
+    let context_id: x::Gcontext = display.generate_id();
+    let cookie = display.send_request_checked(&CreateGc {
+      cid: context_id,
+      drawable,
+      value_list: &[],
+    });
+    display.check_request(cookie)?;
+
+    Ok(GraphicContext { display, context_id })
+  }
+}
+
+impl Drop for GraphicContext {
+  fn drop(&mut self) {
+    let cookie = self.send_request_checked(&FreeGc { gc: self.context_id });
+    let _ = self.check_request(cookie); // TODO
+  }
+}
+
+impl HasDisplay for GraphicContext {
+  fn display(&self) -> &Arc<Display> { &self.display }
+}
+
+impl HasConnection for GraphicContext {
+  fn connection(&self) -> &Connection { self.display.connection() }
+}
+
diff --git a/src/xtypes.rs b/src/xtypes.rs
index 3f67e58..89bb622 100644
--- a/src/xtypes.rs
+++ b/src/xtypes.rs
@@ -2,6 +2,7 @@ use std::borrow::Borrow;
 use std::sync::Arc;
 use std::ops::Deref;
 
+use xcb::XidNew;
 use xcb::x::{
   self,
   Atom,
@@ -10,7 +11,7 @@ use xcb::x::{
   InternAtom,
   MapWindow,
   PropMode,
-  Screen
+  Screen,
 };
 
 
@@ -72,7 +73,7 @@ impl Window {
     let display_ref: &Display = display.borrow();
     let connection: &Connection = &display_ref.connection;
 
-    let window_id: x::Window = connection.0.generate_id();
+    let window_id: x::Window = connection.generate_id();
 
     create_window.wid = window_id;
     let cookie = connection.send_request_checked(create_window);
@@ -136,27 +137,37 @@ impl HasConnection for Connection {
   fn connection(&self) -> &Connection { self }
 }
 
-impl<T: HasDisplay> HasConnection for T {
-  fn connection(&self) -> &Connection { &self.display().connection }
+impl HasConnection for Arc<Display> {
+  fn connection(&self) -> &Connection { &self.connection }
+}
+
+impl HasConnection for Window {
+  fn connection(&self) -> &Connection { &self.display.connection }
 }
 
 
 pub trait HasDisplay {
-  fn display(&self) -> &Display;
+  fn display(&self) -> &Arc<Display>;
 
   fn atoms(&self) -> &Atoms { &self.display().atoms }
 }
 
-impl HasDisplay for Display {
-  fn display(&self) -> &Display { self }
+impl HasDisplay for Arc<Display> {
+  fn display(&self) -> &Arc<Display> { self }
 }
 
-impl<T: HasWindow> HasDisplay for T {
-  fn display(&self) -> &Display { self.window().display.borrow() }
+impl HasDisplay for Window {
+  fn display(&self) -> &Arc<Display> { &self.display }
 }
 
 
 pub trait ConnectionExt: HasConnection {
+  fn generate_id<T: XidNew>(&self) -> T {
+    let connection = self.connection();
+
+    connection.0.generate_id()
+  }
+
   fn get_atom(&self, name: &[u8]) -> xcb::Result<Atom> {
     let connection = self.connection();