feat: Add a function for retrieving the window contents
This function is useful for testing the window contents in certain cases. In addition, this means that we can now have reliable tests for softbuffer's actual functionality. Signed-off-by: John Nunley <jtnunley01@gmail.com> Co-authored-by: dAxpeDDa <daxpedda@gmail.com>
This commit is contained in:
parent
daf304adf9
commit
44248477be
12 changed files with 258 additions and 22 deletions
82
src/x11.rs
82
src/x11.rs
|
|
@ -104,6 +104,9 @@ pub struct X11Impl {
|
|||
/// The depth (bits per pixel) of the drawing context.
|
||||
depth: u8,
|
||||
|
||||
/// The visual ID of the drawing context.
|
||||
visual_id: u32,
|
||||
|
||||
/// The buffer we draw to.
|
||||
buffer: Buffer,
|
||||
|
||||
|
|
@ -178,11 +181,26 @@ impl X11Impl {
|
|||
|
||||
let window = window_handle.window;
|
||||
|
||||
// Run in parallel: start getting the window depth.
|
||||
let geometry_token = display
|
||||
.connection
|
||||
.get_geometry(window)
|
||||
.swbuf_err("Failed to send geometry request")?;
|
||||
// Run in parallel: start getting the window depth and (if necessary) visual.
|
||||
let display2 = display.clone();
|
||||
let tokens = {
|
||||
let geometry_token = display2
|
||||
.connection
|
||||
.get_geometry(window)
|
||||
.swbuf_err("Failed to send geometry request")?;
|
||||
let window_attrs_token = if window_handle.visual_id == 0 {
|
||||
Some(
|
||||
display2
|
||||
.connection
|
||||
.get_window_attributes(window)
|
||||
.swbuf_err("Failed to send window attributes request")?,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
(geometry_token, window_attrs_token)
|
||||
};
|
||||
|
||||
// Create a new graphics context to draw to.
|
||||
let gc = display
|
||||
|
|
@ -201,9 +219,23 @@ impl X11Impl {
|
|||
.swbuf_err("Failed to create GC")?;
|
||||
|
||||
// Finish getting the depth of the window.
|
||||
let geometry_reply = geometry_token
|
||||
.reply()
|
||||
.swbuf_err("Failed to get geometry reply")?;
|
||||
let (geometry_reply, visual_id) = {
|
||||
let (geometry_token, window_attrs_token) = tokens;
|
||||
let geometry_reply = geometry_token
|
||||
.reply()
|
||||
.swbuf_err("Failed to get geometry reply")?;
|
||||
let visual_id = match window_attrs_token {
|
||||
None => window_handle.visual_id,
|
||||
Some(window_attrs) => {
|
||||
window_attrs
|
||||
.reply()
|
||||
.swbuf_err("Failed to get window attributes reply")?
|
||||
.visual
|
||||
}
|
||||
};
|
||||
|
||||
(geometry_reply, visual_id)
|
||||
};
|
||||
|
||||
// See if SHM is available.
|
||||
let buffer = if display.is_shm_available {
|
||||
|
|
@ -222,6 +254,7 @@ impl X11Impl {
|
|||
window,
|
||||
gc,
|
||||
depth: geometry_reply.depth,
|
||||
visual_id,
|
||||
buffer,
|
||||
width: 0,
|
||||
height: 0,
|
||||
|
|
@ -277,6 +310,39 @@ impl X11Impl {
|
|||
// We can now safely call `buffer_mut` on the buffer.
|
||||
Ok(BufferImpl(self))
|
||||
}
|
||||
|
||||
/// Fetch the buffer from the window.
|
||||
pub fn fetch(&mut self) -> Result<Vec<u32>, SoftBufferError> {
|
||||
log::trace!("fetch: window={:X}", self.window);
|
||||
|
||||
// TODO: Is it worth it to do SHM here? Probably not.
|
||||
let reply = self
|
||||
.display
|
||||
.connection
|
||||
.get_image(
|
||||
xproto::ImageFormat::Z_PIXMAP,
|
||||
self.window,
|
||||
0,
|
||||
0,
|
||||
self.width,
|
||||
self.height,
|
||||
u32::MAX,
|
||||
)
|
||||
.swbuf_err("Failed to send image fetching request")?
|
||||
.reply()
|
||||
.swbuf_err("Failed to fetch image from window")?;
|
||||
|
||||
if reply.depth == self.depth && reply.visual == self.visual_id {
|
||||
let mut out = vec![0u32; reply.data.len() / 4];
|
||||
bytemuck::cast_slice_mut::<u32, u8>(&mut out).copy_from_slice(&reply.data);
|
||||
Ok(out)
|
||||
} else {
|
||||
Err(SoftBufferError::PlatformError(
|
||||
Some("Mismatch between reply and window data".into()),
|
||||
None,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BufferImpl<'a>(&'a mut X11Impl);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue