From 7b11acbc46b8d96a521881ccea9b57878210214e Mon Sep 17 00:00:00 2001
From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
Date: Sat, 28 Dec 2024 16:21:36 +0100
Subject: [PATCH 1/2] graphics: Introduce graphics-ipc crate

While for now this for now only includes helpers for the current limited
display interface which is relatively simple to implement manually, in
the future we will likely need a more complex interface with gpu drivers
that would be hard to get right without a common crate proving the
interface.
---
 Cargo.lock                          |  12 +++
 Cargo.toml                          |   1 +
 graphics/fbbootlogd/Cargo.toml      |   1 +
 graphics/fbbootlogd/src/display.rs  | 104 ++++-----------------
 graphics/fbbootlogd/src/text.rs     |   8 +-
 graphics/fbcond/Cargo.toml          |   1 +
 graphics/fbcond/src/display.rs      | 136 +++++-----------------------
 graphics/fbcond/src/scheme.rs       |   6 --
 graphics/fbcond/src/text.rs         |  14 +--
 graphics/graphics-ipc/Cargo.toml    |  11 +++
 graphics/graphics-ipc/src/legacy.rs | 112 +++++++++++++++++++++++
 graphics/graphics-ipc/src/lib.rs    |   1 +
 12 files changed, 190 insertions(+), 217 deletions(-)
 create mode 100644 graphics/graphics-ipc/Cargo.toml
 create mode 100644 graphics/graphics-ipc/src/legacy.rs
 create mode 100644 graphics/graphics-ipc/src/lib.rs

diff --git a/Cargo.lock b/Cargo.lock
index 374df5ce..602e6631 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -442,6 +442,7 @@ name = "fbbootlogd"
 version = "0.1.0"
 dependencies = [
  "console-draw",
+ "graphics-ipc",
  "inputd",
  "libredox",
  "orbclient",
@@ -457,6 +458,7 @@ name = "fbcond"
 version = "0.1.0"
 dependencies = [
  "console-draw",
+ "graphics-ipc",
  "inputd",
  "libredox",
  "orbclient",
@@ -602,6 +604,16 @@ dependencies = [
  "uuid",
 ]
 
+[[package]]
+name = "graphics-ipc"
+version = "0.1.0"
+dependencies = [
+ "common",
+ "inputd",
+ "libredox",
+ "log",
+]
+
 [[package]]
 name = "hashbrown"
 version = "0.15.1"
diff --git a/Cargo.toml b/Cargo.toml
index 9fe3ecd2..be9ace45 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,6 +21,7 @@ members = [
     "graphics/fbbootlogd",
     "graphics/driver-graphics",
     "graphics/fbcond",
+    "graphics/graphics-ipc",
     "graphics/vesad",
     "graphics/virtio-gpud",
 
diff --git a/graphics/fbbootlogd/Cargo.toml b/graphics/fbbootlogd/Cargo.toml
index 90862d27..b0597851 100644
--- a/graphics/fbbootlogd/Cargo.toml
+++ b/graphics/fbbootlogd/Cargo.toml
@@ -12,6 +12,7 @@ redox-daemon = "0.1"
 redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
 
 console-draw = { path = "../console-draw" }
+graphics-ipc = { path = "../graphics-ipc" }
 inputd = { path = "../../inputd" }
 libredox = "0.1.3"
 
diff --git a/graphics/fbbootlogd/src/display.rs b/graphics/fbbootlogd/src/display.rs
index ad3b39d4..646d3e4d 100644
--- a/graphics/fbbootlogd/src/display.rs
+++ b/graphics/fbbootlogd/src/display.rs
@@ -1,13 +1,13 @@
 use event::{user_data, EventQueue};
+use graphics_ipc::legacy::LegacyGraphicsHandle;
 use inputd::{ConsumerHandle, Damage};
 use libredox::errno::ESTALE;
-use libredox::flag;
 use orbclient::Event;
 use std::mem;
 use std::os::fd::BorrowedFd;
 use std::sync::mpsc::{self, Receiver, Sender};
 use std::sync::{Arc, Mutex};
-use std::{fs::File, io, os::unix::io::AsRawFd, slice};
+use std::{io, os::unix::io::AsRawFd, slice};
 
 fn read_to_slice<T: Copy>(
     file: BorrowedFd,
@@ -22,46 +22,17 @@ fn read_to_slice<T: Copy>(
     }
 }
 
-fn display_fd_map(width: usize, height: usize, display_file: File) -> syscall::Result<DisplayMap> {
-    unsafe {
-        let display_ptr = libredox::call::mmap(libredox::call::MmapArgs {
-            fd: display_file.as_raw_fd() as usize,
-            offset: 0,
-            length: (width * height * 4),
-            prot: flag::PROT_READ | flag::PROT_WRITE,
-            flags: flag::MAP_SHARED,
-            addr: core::ptr::null_mut(),
-        })?;
-        let display_slice = slice::from_raw_parts_mut(display_ptr as *mut u32, width * height);
-        Ok(DisplayMap {
-            display_file: Arc::new(display_file),
-            offscreen: display_slice,
-            width,
-            height,
-        })
-    }
-}
-
-unsafe fn display_fd_unmap(image: *mut [u32]) {
-    let _ = libredox::call::munmap(image as *mut (), image.len());
+fn display_fd_map(display_handle: LegacyGraphicsHandle) -> io::Result<DisplayMap> {
+    let display_map = display_handle.map_display()?;
+    Ok(DisplayMap {
+        display_handle: Arc::new(display_handle),
+        inner: display_map,
+    })
 }
 
 pub struct DisplayMap {
-    display_file: Arc<File>,
-    pub offscreen: *mut [u32],
-    pub width: usize,
-    pub height: usize,
-}
-
-unsafe impl Send for DisplayMap {}
-unsafe impl Sync for DisplayMap {}
-
-impl Drop for DisplayMap {
-    fn drop(&mut self) {
-        unsafe {
-            display_fd_unmap(self.offscreen);
-        }
-    }
+    display_handle: Arc<LegacyGraphicsHandle>,
+    pub inner: graphics_ipc::legacy::DisplayMap,
 }
 
 enum DisplayCommand {
@@ -77,11 +48,10 @@ impl Display {
     pub fn open_first_vt() -> io::Result<Self> {
         let input_handle = ConsumerHandle::for_vt(1)?;
 
-        let (display_file, width, height) = Self::open_display(&input_handle)?;
+        let display_handle = LegacyGraphicsHandle::from_file(input_handle.open_display()?)?;
 
         let map = Arc::new(Mutex::new(
-            display_fd_map(width, height, display_file)
-                .unwrap_or_else(|e| panic!("failed to map display: {e}")),
+            display_fd_map(display_handle).unwrap_or_else(|e| panic!("failed to map display: {e}")),
         ));
 
         let map_clone = map.clone();
@@ -98,34 +68,6 @@ impl Display {
         Ok(Self { cmd_tx, map })
     }
 
-    fn open_display(input_handle: &ConsumerHandle) -> io::Result<(File, usize, usize)> {
-        let display_file = input_handle.open_display()?;
-
-        let mut buf: [u8; 4096] = [0; 4096];
-        let count = libredox::call::fpath(display_file.as_raw_fd() as usize, &mut buf)
-            .unwrap_or_else(|e| {
-                panic!("Could not read display path with fpath(): {e}");
-            });
-
-        let url =
-            String::from_utf8(Vec::from(&buf[..count])).expect("Could not create Utf8 Url String");
-        let path = url.split(':').nth(1).expect("Could not get path from url");
-
-        let mut path_parts = path.split('/').skip(1);
-        let width = path_parts
-            .next()
-            .unwrap_or("")
-            .parse::<usize>()
-            .unwrap_or(0);
-        let height = path_parts
-            .next()
-            .unwrap_or("")
-            .parse::<usize>()
-            .unwrap_or(0);
-
-        Ok((display_file, width, height))
-    }
-
     fn handle_input_events(map: Arc<Mutex<DisplayMap>>, input_handle: ConsumerHandle) {
         let event_queue = EventQueue::new().expect("fbbootlogd: failed to create event queue");
 
@@ -151,10 +93,11 @@ impl Display {
                 Err(err) if err.errno() == ESTALE => {
                     eprintln!("fbbootlogd: handoff requested");
 
-                    let (new_display_file, width, height) =
-                        Self::open_display(&input_handle).unwrap();
+                    let new_display_handle =
+                        LegacyGraphicsHandle::from_file(input_handle.open_display().unwrap())
+                            .unwrap();
 
-                    match display_fd_map(width, height, new_display_file) {
+                    match display_fd_map(new_display_handle) {
                         Ok(ok) => {
                             *map.lock().unwrap() = ok;
 
@@ -177,19 +120,12 @@ impl Display {
     fn handle_sync_rect(map: Arc<Mutex<DisplayMap>>, cmd_rx: Receiver<DisplayCommand>) {
         while let Ok(cmd) = cmd_rx.recv() {
             match cmd {
-                DisplayCommand::SyncRects(sync_rects) => unsafe {
+                DisplayCommand::SyncRects(sync_rects) => {
                     // We may not hold this lock across the write call to avoid deadlocking if the
                     // graphics driver tries to write to the bootlog.
-                    let display_file = map.lock().unwrap().display_file.clone();
-                    libredox::call::write(
-                        display_file.as_raw_fd() as usize,
-                        slice::from_raw_parts(
-                            sync_rects.as_ptr() as *const u8,
-                            sync_rects.len() * mem::size_of::<Damage>(),
-                        ),
-                    )
-                    .unwrap();
-                },
+                    let display_handle = map.lock().unwrap().display_handle.clone();
+                    display_handle.sync_rects(&sync_rects).unwrap();
+                }
             }
         }
     }
diff --git a/graphics/fbbootlogd/src/text.rs b/graphics/fbbootlogd/src/text.rs
index 5dff07d5..15e34e05 100644
--- a/graphics/fbbootlogd/src/text.rs
+++ b/graphics/fbbootlogd/src/text.rs
@@ -22,12 +22,12 @@ impl TextScreen {
 
 impl TextScreen {
     pub fn write(&mut self, buf: &[u8]) -> Result<usize> {
-        let map = self.display.map.lock().unwrap();
+        let mut map = self.display.map.lock().unwrap();
         let damage = self.inner.write(
             &mut console_draw::DisplayMap {
-                offscreen: map.offscreen,
-                width: map.width,
-                height: map.height,
+                offscreen: map.inner.ptr_mut(),
+                width: map.inner.width(),
+                height: map.inner.height(),
             },
             buf,
             &mut VecDeque::new(),
diff --git a/graphics/fbcond/Cargo.toml b/graphics/fbcond/Cargo.toml
index fffb1a07..10fc0ebf 100644
--- a/graphics/fbcond/Cargo.toml
+++ b/graphics/fbcond/Cargo.toml
@@ -12,6 +12,7 @@ redox-daemon = "0.1"
 redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
 
 console-draw = { path = "../console-draw" }
+graphics-ipc = { path = "../graphics-ipc" }
 inputd = { path = "../../inputd" }
 libredox = "0.1.3"
 
diff --git a/graphics/fbcond/src/display.rs b/graphics/fbcond/src/display.rs
index cf2dbc52..d50ac262 100644
--- a/graphics/fbcond/src/display.rs
+++ b/graphics/fbcond/src/display.rs
@@ -1,57 +1,27 @@
+use graphics_ipc::legacy::{DisplayMap, LegacyGraphicsHandle};
 use inputd::{ConsumerHandle, Damage};
-use libredox::flag;
-use std::fs::File;
-use std::os::unix::io::AsRawFd;
-use std::{io, mem, ptr, slice};
-
-fn display_fd_map(
-    width: usize,
-    height: usize,
-    display_file: &mut File,
-) -> syscall::Result<*mut [u32]> {
-    unsafe {
-        let display_ptr = libredox::call::mmap(libredox::call::MmapArgs {
-            fd: display_file.as_raw_fd() as usize,
-            offset: 0,
-            length: (width * height * 4),
-            prot: flag::PROT_READ | flag::PROT_WRITE,
-            flags: flag::MAP_SHARED,
-            addr: core::ptr::null_mut(),
-        })?;
-        Ok(ptr::slice_from_raw_parts_mut(
-            display_ptr as *mut u32,
-            width * height,
-        ))
-    }
-}
-
-unsafe fn display_fd_unmap(image: *mut [u32]) {
-    let _ = libredox::call::munmap(image as *mut (), image.len());
-}
+use std::io;
 
 pub struct Display {
     pub input_handle: ConsumerHandle,
-    pub display_file: File,
-    pub offscreen: *mut [u32],
-    pub width: usize,
-    pub height: usize,
+    pub display_handle: LegacyGraphicsHandle,
+    pub map: DisplayMap,
 }
 
 impl Display {
     pub fn open_vt(vt: usize) -> io::Result<Self> {
         let input_handle = ConsumerHandle::for_vt(vt)?;
 
-        let (mut display_file, width, height) = Self::open_display(&input_handle)?;
+        let display_handle = Self::open_display(&input_handle)?;
 
-        let offscreen = display_fd_map(width, height, &mut display_file)
+        let map = display_handle
+            .map_display()
             .unwrap_or_else(|e| panic!("failed to map display for VT #{vt}: {e}"));
 
         Ok(Self {
             input_handle,
-            display_file,
-            offscreen,
-            width,
-            height,
+            display_handle,
+            map,
         })
     }
 
@@ -59,92 +29,34 @@ impl Display {
     pub fn reopen_for_handoff(&mut self) {
         eprintln!("fbcond: Performing handoff");
 
-        let (mut new_display_file, width, height) = Self::open_display(&self.input_handle).unwrap();
-
-        eprintln!("fbcond: Opened new display with size {width}x{height}");
+        let new_display_handle = Self::open_display(&self.input_handle).unwrap();
 
-        match display_fd_map(width, height, &mut new_display_file) {
-            Ok(offscreen) => {
-                unsafe {
-                    display_fd_unmap(self.offscreen);
-                }
+        eprintln!("fbcond: Opened new display");
 
-                self.offscreen = offscreen;
-                self.width = width;
-                self.height = height;
-                self.display_file = new_display_file;
+        match new_display_handle.map_display() {
+            Ok(map) => {
+                self.map = map;
+                self.display_handle = new_display_handle;
 
-                eprintln!("fbcond: Mapped new display");
+                eprintln!(
+                    "fbcond: Mapped new display with size {}x{}",
+                    self.map.width(),
+                    self.map.height()
+                );
             }
             Err(err) => {
-                eprintln!("failed to resize display to {}x{}: {}", width, height, err);
+                eprintln!("failed to resize display: {}", err);
             }
         }
     }
 
-    fn open_display(input_handle: &ConsumerHandle) -> io::Result<(File, usize, usize)> {
+    fn open_display(input_handle: &ConsumerHandle) -> io::Result<LegacyGraphicsHandle> {
         let display_file = input_handle.open_display()?;
 
-        let mut buf: [u8; 4096] = [0; 4096];
-        let count = libredox::call::fpath(display_file.as_raw_fd() as usize, &mut buf)
-            .unwrap_or_else(|e| {
-                panic!("Could not read display path with fpath(): {e}");
-            });
-
-        let url =
-            String::from_utf8(Vec::from(&buf[..count])).expect("Could not create Utf8 Url String");
-        let path = url.split(':').nth(1).expect("Could not get path from url");
-
-        let mut path_parts = path.split('/').skip(1);
-        let width = path_parts
-            .next()
-            .unwrap_or("")
-            .parse::<usize>()
-            .unwrap_or(0);
-        let height = path_parts
-            .next()
-            .unwrap_or("")
-            .parse::<usize>()
-            .unwrap_or(0);
-
-        Ok((display_file, width, height))
-    }
-
-    pub fn resize(&mut self, width: usize, height: usize) {
-        match display_fd_map(width, height, &mut self.display_file) {
-            Ok(offscreen) => {
-                unsafe {
-                    display_fd_unmap(self.offscreen);
-                }
-
-                self.offscreen = offscreen;
-                self.width = width;
-                self.height = height;
-            }
-            Err(err) => {
-                eprintln!("failed to resize display to {}x{}: {}", width, height, err);
-            }
-        }
+        LegacyGraphicsHandle::from_file(display_file)
     }
 
     pub fn sync_rects(&mut self, sync_rects: Vec<Damage>) {
-        unsafe {
-            libredox::call::write(
-                self.display_file.as_raw_fd() as usize,
-                slice::from_raw_parts(
-                    sync_rects.as_ptr() as *const u8,
-                    sync_rects.len() * mem::size_of::<Damage>(),
-                ),
-            )
-            .unwrap();
-        }
-    }
-}
-
-impl Drop for Display {
-    fn drop(&mut self) {
-        unsafe {
-            display_fd_unmap(self.offscreen);
-        }
+        self.display_handle.sync_rects(&sync_rects).unwrap();
     }
 }
diff --git a/graphics/fbcond/src/scheme.rs b/graphics/fbcond/src/scheme.rs
index dd667cbf..0643b112 100644
--- a/graphics/fbcond/src/scheme.rs
+++ b/graphics/fbcond/src/scheme.rs
@@ -60,12 +60,6 @@ impl FbconScheme {
             handles: BTreeMap::new(),
         }
     }
-
-    fn resize(&mut self, width: usize, height: usize, stride: usize) {
-        for console in self.vts.values_mut() {
-            console.resize(width, height);
-        }
-    }
 }
 
 impl SchemeBlock for FbconScheme {
diff --git a/graphics/fbcond/src/text.rs b/graphics/fbcond/src/text.rs
index e01dab8a..02f36377 100644
--- a/graphics/fbcond/src/text.rs
+++ b/graphics/fbcond/src/text.rs
@@ -1,7 +1,4 @@
-extern crate ransid;
-
 use std::collections::VecDeque;
-use std::convert::TryInto;
 
 use orbclient::{Event, EventOption};
 use syscall::error::*;
@@ -29,11 +26,6 @@ impl TextScreen {
         self.display.reopen_for_handoff();
     }
 
-    pub fn resize(&mut self, width: usize, height: usize) {
-        self.display
-            .resize(width.try_into().unwrap(), height.try_into().unwrap());
-    }
-
     pub fn input(&mut self, event: &Event) {
         let mut buf = vec![];
 
@@ -130,9 +122,9 @@ impl TextScreen {
     pub fn write(&mut self, buf: &[u8]) -> Result<usize> {
         let damage = self.inner.write(
             &mut console_draw::DisplayMap {
-                offscreen: self.display.offscreen,
-                width: self.display.width,
-                height: self.display.height,
+                offscreen: self.display.map.ptr_mut(),
+                width: self.display.map.width(),
+                height: self.display.map.height(),
             },
             buf,
             &mut self.input,
diff --git a/graphics/graphics-ipc/Cargo.toml b/graphics/graphics-ipc/Cargo.toml
new file mode 100644
index 00000000..61298ced
--- /dev/null
+++ b/graphics/graphics-ipc/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "graphics-ipc"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+log = "0.4"
+libredox = "0.1.3"
+
+common = { path = "../../common" }
+inputd = { path = "../../inputd" }
diff --git a/graphics/graphics-ipc/src/legacy.rs b/graphics/graphics-ipc/src/legacy.rs
new file mode 100644
index 00000000..6d039f8f
--- /dev/null
+++ b/graphics/graphics-ipc/src/legacy.rs
@@ -0,0 +1,112 @@
+use std::fs::File;
+use std::os::unix::io::AsRawFd;
+use std::{io, mem, ptr, slice};
+
+use inputd::Damage;
+use libredox::flag;
+
+/// A graphics handle using the legacy graphics API.
+///
+/// The legacy graphics API only allows a single framebuffer for each VT and supports neither page
+/// flipping nor cursor planes.
+pub struct LegacyGraphicsHandle {
+    file: File,
+}
+
+impl LegacyGraphicsHandle {
+    pub fn from_file(file: File) -> io::Result<Self> {
+        Ok(LegacyGraphicsHandle { file })
+    }
+
+    pub fn map_display(&self) -> io::Result<DisplayMap> {
+        let mut buf: [u8; 4096] = [0; 4096];
+        let count =
+            libredox::call::fpath(self.file.as_raw_fd() as usize, &mut buf).unwrap_or_else(|e| {
+                panic!("Could not read display path with fpath(): {e}");
+            });
+
+        let url =
+            String::from_utf8(Vec::from(&buf[..count])).expect("Could not create Utf8 Url String");
+        let path = url.split(':').nth(1).expect("Could not get path from url");
+
+        let mut path_parts = path.split('/').skip(1);
+        let width = path_parts
+            .next()
+            .unwrap_or("")
+            .parse::<usize>()
+            .unwrap_or(0);
+        let height = path_parts
+            .next()
+            .unwrap_or("")
+            .parse::<usize>()
+            .unwrap_or(0);
+
+        let display_ptr = unsafe {
+            libredox::call::mmap(libredox::call::MmapArgs {
+                fd: self.file.as_raw_fd() as usize,
+                offset: 0,
+                length: (width * height * 4),
+                prot: flag::PROT_READ | flag::PROT_WRITE,
+                flags: flag::MAP_SHARED,
+                addr: core::ptr::null_mut(),
+            })?
+        };
+        let offscreen = ptr::slice_from_raw_parts_mut(display_ptr as *mut u32, width * height);
+
+        Ok(DisplayMap {
+            offscreen,
+            width,
+            height,
+        })
+    }
+
+    pub fn sync_full_screen(&self) -> io::Result<()> {
+        libredox::call::fsync(self.file.as_raw_fd() as usize)?;
+        Ok(())
+    }
+
+    pub fn sync_rects(&self, sync_rects: &[Damage]) -> io::Result<()> {
+        libredox::call::write(self.file.as_raw_fd() as usize, unsafe {
+            slice::from_raw_parts(
+                sync_rects.as_ptr() as *const u8,
+                sync_rects.len() * mem::size_of::<Damage>(),
+            )
+        })?;
+        Ok(())
+    }
+}
+
+pub struct DisplayMap {
+    offscreen: *mut [u32],
+    width: usize,
+    height: usize,
+}
+
+impl DisplayMap {
+    pub fn ptr(&self) -> *const [u32] {
+        self.offscreen
+    }
+
+    pub fn ptr_mut(&mut self) -> *mut [u32] {
+        self.offscreen
+    }
+
+    pub fn width(&self) -> usize {
+        self.width
+    }
+
+    pub fn height(&self) -> usize {
+        self.height
+    }
+}
+
+unsafe impl Send for DisplayMap {}
+unsafe impl Sync for DisplayMap {}
+
+impl Drop for DisplayMap {
+    fn drop(&mut self) {
+        unsafe {
+            let _ = libredox::call::munmap(self.offscreen as *mut (), self.offscreen.len());
+        }
+    }
+}
diff --git a/graphics/graphics-ipc/src/lib.rs b/graphics/graphics-ipc/src/lib.rs
new file mode 100644
index 00000000..d0b03667
--- /dev/null
+++ b/graphics/graphics-ipc/src/lib.rs
@@ -0,0 +1 @@
+pub mod legacy;
-- 
GitLab


From 5fc04c332d5e889d3cc94f557b5309dcdd6fdb17 Mon Sep 17 00:00:00 2001
From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
Date: Sat, 28 Dec 2024 16:26:18 +0100
Subject: [PATCH 2/2] graphics: Move Damage from inputd to graphics-ipc

---
 Cargo.lock                          |  6 ++++--
 graphics/console-draw/Cargo.toml    |  2 +-
 graphics/console-draw/src/lib.rs    |  2 +-
 graphics/driver-graphics/Cargo.toml |  1 +
 graphics/driver-graphics/src/lib.rs |  3 ++-
 graphics/fbbootlogd/src/display.rs  |  4 ++--
 graphics/fbcond/src/display.rs      |  4 ++--
 graphics/graphics-ipc/Cargo.toml    |  1 -
 graphics/graphics-ipc/src/legacy.rs | 29 +++++++++++++++++++++++++++--
 graphics/vesad/Cargo.toml           |  1 +
 graphics/vesad/src/scheme.rs        |  3 ++-
 graphics/vesad/src/screen.rs        |  2 +-
 graphics/virtio-gpud/Cargo.toml     |  1 +
 graphics/virtio-gpud/src/scheme.rs  |  3 ++-
 inputd/src/lib.rs                   | 29 -----------------------------
 15 files changed, 47 insertions(+), 44 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 602e6631..145efadb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -326,7 +326,7 @@ dependencies = [
 name = "console-draw"
 version = "0.1.0"
 dependencies = [
- "inputd",
+ "graphics-ipc",
  "orbclient",
  "ransid",
 ]
@@ -401,6 +401,7 @@ name = "driver-graphics"
 version = "0.1.0"
 dependencies = [
  "common",
+ "graphics-ipc",
  "inputd",
  "libredox",
  "log",
@@ -609,7 +610,6 @@ name = "graphics-ipc"
 version = "0.1.0"
 dependencies = [
  "common",
- "inputd",
  "libredox",
  "log",
 ]
@@ -1725,6 +1725,7 @@ version = "0.1.0"
 dependencies = [
  "common",
  "driver-graphics",
+ "graphics-ipc",
  "inputd",
  "libredox",
  "orbclient",
@@ -1780,6 +1781,7 @@ dependencies = [
  "common",
  "driver-graphics",
  "futures",
+ "graphics-ipc",
  "inputd",
  "libredox",
  "log",
diff --git a/graphics/console-draw/Cargo.toml b/graphics/console-draw/Cargo.toml
index 56d8d985..6153d614 100644
--- a/graphics/console-draw/Cargo.toml
+++ b/graphics/console-draw/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
 orbclient = "0.3.27"
 ransid = "0.4"
 
-inputd = { path = "../../inputd" }
+graphics-ipc = { path = "../graphics-ipc" }
 
 [features]
 default = []
diff --git a/graphics/console-draw/src/lib.rs b/graphics/console-draw/src/lib.rs
index 729cbd74..bbd2d4fd 100644
--- a/graphics/console-draw/src/lib.rs
+++ b/graphics/console-draw/src/lib.rs
@@ -4,7 +4,7 @@ use std::collections::{BTreeSet, VecDeque};
 use std::convert::{TryFrom, TryInto};
 use std::{cmp, ptr};
 
-use inputd::Damage;
+use graphics_ipc::legacy::Damage;
 use orbclient::FONT;
 
 pub struct DisplayMap {
diff --git a/graphics/driver-graphics/Cargo.toml b/graphics/driver-graphics/Cargo.toml
index c7cd6f9d..6ad15add 100644
--- a/graphics/driver-graphics/Cargo.toml
+++ b/graphics/driver-graphics/Cargo.toml
@@ -10,4 +10,5 @@ redox_syscall = "0.5"
 libredox = "0.1.3"
 
 common = { path = "../../common" }
+graphics-ipc = { path = "../graphics-ipc" }
 inputd = { path = "../../inputd" }
diff --git a/graphics/driver-graphics/src/lib.rs b/graphics/driver-graphics/src/lib.rs
index 33c92520..147802dc 100644
--- a/graphics/driver-graphics/src/lib.rs
+++ b/graphics/driver-graphics/src/lib.rs
@@ -1,7 +1,8 @@
 use std::collections::{BTreeMap, HashMap};
 use std::io;
 
-use inputd::{Damage, VtEvent, VtEventKind};
+use graphics_ipc::legacy::Damage;
+use inputd::{VtEvent, VtEventKind};
 use libredox::errno::EOPNOTSUPP;
 use libredox::Fd;
 use redox_scheme::{RequestKind, Response, Scheme, SignalBehavior, Socket};
diff --git a/graphics/fbbootlogd/src/display.rs b/graphics/fbbootlogd/src/display.rs
index 646d3e4d..4fa9d532 100644
--- a/graphics/fbbootlogd/src/display.rs
+++ b/graphics/fbbootlogd/src/display.rs
@@ -1,6 +1,6 @@
 use event::{user_data, EventQueue};
-use graphics_ipc::legacy::LegacyGraphicsHandle;
-use inputd::{ConsumerHandle, Damage};
+use graphics_ipc::legacy::{Damage, LegacyGraphicsHandle};
+use inputd::ConsumerHandle;
 use libredox::errno::ESTALE;
 use orbclient::Event;
 use std::mem;
diff --git a/graphics/fbcond/src/display.rs b/graphics/fbcond/src/display.rs
index d50ac262..8595ec6e 100644
--- a/graphics/fbcond/src/display.rs
+++ b/graphics/fbcond/src/display.rs
@@ -1,5 +1,5 @@
-use graphics_ipc::legacy::{DisplayMap, LegacyGraphicsHandle};
-use inputd::{ConsumerHandle, Damage};
+use graphics_ipc::legacy::{Damage, DisplayMap, LegacyGraphicsHandle};
+use inputd::ConsumerHandle;
 use std::io;
 
 pub struct Display {
diff --git a/graphics/graphics-ipc/Cargo.toml b/graphics/graphics-ipc/Cargo.toml
index 61298ced..7491222b 100644
--- a/graphics/graphics-ipc/Cargo.toml
+++ b/graphics/graphics-ipc/Cargo.toml
@@ -8,4 +8,3 @@ log = "0.4"
 libredox = "0.1.3"
 
 common = { path = "../../common" }
-inputd = { path = "../../inputd" }
diff --git a/graphics/graphics-ipc/src/legacy.rs b/graphics/graphics-ipc/src/legacy.rs
index 6d039f8f..2bfb4f2c 100644
--- a/graphics/graphics-ipc/src/legacy.rs
+++ b/graphics/graphics-ipc/src/legacy.rs
@@ -1,8 +1,7 @@
 use std::fs::File;
 use std::os::unix::io::AsRawFd;
-use std::{io, mem, ptr, slice};
+use std::{cmp, io, mem, ptr, slice};
 
-use inputd::Damage;
 use libredox::flag;
 
 /// A graphics handle using the legacy graphics API.
@@ -110,3 +109,29 @@ impl Drop for DisplayMap {
         }
     }
 }
+
+// Keep synced with orbital's SyncRect
+#[derive(Debug, Copy, Clone)]
+#[repr(packed)]
+pub struct Damage {
+    pub x: i32,
+    pub y: i32,
+    pub width: i32,
+    pub height: i32,
+}
+
+impl Damage {
+    #[must_use]
+    pub fn clip(mut self, width: i32, height: i32) -> Self {
+        // Clip damage
+        self.x = cmp::min(self.x, width);
+        if self.x + self.width > width {
+            self.width -= cmp::min(self.width, width - self.x);
+        }
+        self.y = cmp::min(self.y, height);
+        if self.y + self.height > height {
+            self.height = cmp::min(self.height, height - self.y);
+        }
+        self
+    }
+}
diff --git a/graphics/vesad/Cargo.toml b/graphics/vesad/Cargo.toml
index 8106dbca..fd983213 100644
--- a/graphics/vesad/Cargo.toml
+++ b/graphics/vesad/Cargo.toml
@@ -12,6 +12,7 @@ redox_event = "0.4.1"
 
 common = { path = "../../common" }
 driver-graphics = { path = "../driver-graphics" }
+graphics-ipc = { path = "../graphics-ipc" }
 inputd = { path = "../../inputd" }
 libredox = "0.1.3"
 
diff --git a/graphics/vesad/src/scheme.rs b/graphics/vesad/src/scheme.rs
index 15d7f286..51a3712e 100644
--- a/graphics/vesad/src/scheme.rs
+++ b/graphics/vesad/src/scheme.rs
@@ -1,4 +1,5 @@
 use driver_graphics::GraphicsAdapter;
+use graphics_ipc::legacy::Damage;
 
 use crate::{framebuffer::FrameBuffer, screen::GraphicScreen};
 
@@ -36,7 +37,7 @@ impl GraphicsAdapter for FbAdapter {
         &mut self,
         display_id: usize,
         resource: &Self::Resource,
-        damage: Option<&[inputd::Damage]>,
+        damage: Option<&[Damage]>,
     ) {
         if let Some(damage) = damage {
             resource.sync(&mut self.framebuffers[display_id], damage)
diff --git a/graphics/vesad/src/screen.rs b/graphics/vesad/src/screen.rs
index e90a4b39..8460ffbb 100644
--- a/graphics/vesad/src/screen.rs
+++ b/graphics/vesad/src/screen.rs
@@ -3,7 +3,7 @@ use std::convert::TryInto;
 use std::ptr::{self, NonNull};
 
 use driver_graphics::Resource;
-use inputd::Damage;
+use graphics_ipc::legacy::Damage;
 use syscall::PAGE_SIZE;
 
 use crate::framebuffer::FrameBuffer;
diff --git a/graphics/virtio-gpud/Cargo.toml b/graphics/virtio-gpud/Cargo.toml
index a8cf34ed..ae340bc3 100644
--- a/graphics/virtio-gpud/Cargo.toml
+++ b/graphics/virtio-gpud/Cargo.toml
@@ -12,6 +12,7 @@ anyhow = "1.0.71"
 
 common = { path = "../../common" }
 driver-graphics = { path = "../driver-graphics" }
+graphics-ipc = { path = "../graphics-ipc" }
 virtio-core = { path = "../../virtio-core" }
 pcid = { path = "../../pcid" }
 inputd = { path = "../../inputd" }
diff --git a/graphics/virtio-gpud/src/scheme.rs b/graphics/virtio-gpud/src/scheme.rs
index 3f140fb8..d80f45bb 100644
--- a/graphics/virtio-gpud/src/scheme.rs
+++ b/graphics/virtio-gpud/src/scheme.rs
@@ -2,7 +2,8 @@ use std::sync::Arc;
 
 use common::{dma::Dma, sgl};
 use driver_graphics::{GraphicsAdapter, GraphicsScheme, Resource};
-use inputd::{Damage, DisplayHandle};
+use graphics_ipc::legacy::Damage;
+use inputd::DisplayHandle;
 
 use syscall::PAGE_SIZE;
 
diff --git a/inputd/src/lib.rs b/inputd/src/lib.rs
index 4bc019d4..877e3f31 100644
--- a/inputd/src/lib.rs
+++ b/inputd/src/lib.rs
@@ -1,6 +1,3 @@
-#![feature(iter_next_chunk)]
-
-use std::cmp;
 use std::fs::{File, OpenOptions};
 use std::io::{Error, Read, Write};
 use std::mem::size_of;
@@ -137,32 +134,6 @@ pub struct VtEvent {
     pub stride: u32,
 }
 
-// Keep synced with orbital's SyncRect
-#[derive(Debug, Copy, Clone)]
-#[repr(packed)]
-pub struct Damage {
-    pub x: i32,
-    pub y: i32,
-    pub width: i32,
-    pub height: i32,
-}
-
-impl Damage {
-    #[must_use]
-    pub fn clip(mut self, width: i32, height: i32) -> Self {
-        // Clip damage
-        self.x = cmp::min(self.x, width);
-        if self.x + self.width > width {
-            self.width -= cmp::min(self.width, width - self.x);
-        }
-        self.y = cmp::min(self.y, height);
-        if self.y + self.height > height {
-            self.height = cmp::min(self.height, height - self.y);
-        }
-        self
-    }
-}
-
 pub struct ProducerHandle(File);
 
 impl ProducerHandle {
-- 
GitLab