Merge remote-tracking branch 'origin/master' into damage
This commit is contained in:
commit
1e7b9213d2
13 changed files with 265 additions and 23 deletions
86
src/x11.rs
86
src/x11.rs
|
|
@ -109,6 +109,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,
|
||||
|
||||
|
|
@ -183,11 +186,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
|
||||
|
|
@ -206,9 +224,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 {
|
||||
|
|
@ -227,6 +259,7 @@ impl X11Impl {
|
|||
window,
|
||||
gc,
|
||||
depth: geometry_reply.depth,
|
||||
visual_id,
|
||||
buffer,
|
||||
buffer_presented: false,
|
||||
size: None,
|
||||
|
|
@ -278,6 +311,43 @@ 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);
|
||||
|
||||
let (width, height) = self
|
||||
.size
|
||||
.expect("Must set size of surface before calling `fetch()`");
|
||||
|
||||
// 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,
|
||||
width.get(),
|
||||
height.get(),
|
||||
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