mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-23 11:21:30 +11:00
Memory-map the keymap FD on Wayland to fix EOF error (#278)
wlroots based compositors reuse the same FD for keymap, so after a first read is done, the file is seeked to the end and the next read fails, causing the following error: thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: UnexpectedEof, message: "failed to fill whole buffer" }' The Wayland documentation says the FD "can be memory-mapped to provide a keyboard mapping description" and then "From version 7 onwards, the fd must be mapped with MAP_PRIVATE by the recipient, as MAP_SHARED may fail." Although it is not very clear, it probably means that the FD must be memory-mapped.
This commit is contained in:
parent
4962afd3f5
commit
344a1997c7
|
@ -30,9 +30,9 @@ use xkb::keymap::Keymap;
|
|||
use std::cell::RefCell;
|
||||
use std::ffi::c_void;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Seek, SeekFrom, Write};
|
||||
use std::io::{self, Seek, SeekFrom, Write};
|
||||
use std::mem;
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::rc::Rc;
|
||||
use std::slice;
|
||||
use std::sync::mpsc;
|
||||
|
@ -1073,20 +1073,29 @@ impl Window {
|
|||
match keymap {
|
||||
KeymapFormat::XkbV1 => {
|
||||
unsafe {
|
||||
// Read fd content into Vec
|
||||
let mut file = File::from_raw_fd(fd);
|
||||
let mut v = Vec::with_capacity(len as usize);
|
||||
v.set_len(len as usize);
|
||||
file.read_exact(&mut v)?;
|
||||
// The file descriptor must be memory-mapped (with MAP_PRIVATE).
|
||||
let addr = libc::mmap(
|
||||
std::ptr::null_mut(),
|
||||
len as usize,
|
||||
libc::PROT_READ,
|
||||
libc::MAP_PRIVATE,
|
||||
fd,
|
||||
0,
|
||||
);
|
||||
if addr == libc::MAP_FAILED {
|
||||
return Err(std::io::Error::last_os_error());
|
||||
}
|
||||
|
||||
let ctx = xkbcommon_sys::xkb_context_new(0);
|
||||
let kb_map_ptr = xkbcommon_sys::xkb_keymap_new_from_string(
|
||||
ctx,
|
||||
v.as_ptr() as *const _ as *const std::os::raw::c_char,
|
||||
addr as *const i8,
|
||||
xkbcommon_sys::xkb_keymap_format::XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
0,
|
||||
);
|
||||
|
||||
libc::munmap(addr, len as usize);
|
||||
|
||||
// Wrap keymap
|
||||
Ok(Keymap::from_ptr(kb_map_ptr as *mut _ as *mut c_void))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue