A couple months ago, I started writing an X11 window manager in C with Xlib and I'm now trying to rewrite it in Rust. (after all, rust is the future, right?)
This is the code from main.rs that segfaults:
// event loop
loop {
let mut event : *mut XEvent = 0 as *mut XEvent;
unsafe {
XNextEvent(DISPLAY, event);
/*match (*event).type_ {
CreateNotify => {
println!("sdfg");
}
_ => {
println!("sdfgsdfg");
}
}*/
}
println!("dsfgsdfg");
}
Using GDB, I was able to narrow it down to XNextEvent inside the unsafe block. I'm not really sure where to go from there, since it's calling a function /use/lib/libX11.so.6 and I can't list the function to see where it quit.
Before you ask about the unsafe block, I can't put Xlib functions outside of unsafe blocks because they are unsafe functions and the compiler will complain.
The project uses the x11
crate on crates.io.
You are passing a pointer to NULL
instead of a pointer to a local variable to be filled by XNextEvent
, just as if your C code did:
XEvent *event = NULL;
XNextEvent(DISPLAY, event); //crash!
In C, you are probably doing:
XEvent event;
XNextEvent(DISPLAY, &event);
But unfortunately you cannot do that directly in Rust because you cannot declare an uninitialized variable:
let mut event: XEvent;
XNextEvent(DISPLAY, &mut event); //error: event is not initialized
If XEvent
implemented Default
you could just default initialize it, but I think it does not.
For these cases you can use MaybeUninit
:
let event = unsafe {
let mut event = MaybeUninit::uninit();
XNextEvent(DISPLAY, event.as_mut_ptr());
event.assume_init()
};