-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
X11 backend #371
X11 backend #371
Conversation
libX11 is not thread-safe unless |
src/backend/x11/connection.rs
Outdated
XCBConnection::from_raw_xcb_connection(xcb_connection_t, false) | ||
}; | ||
|
||
if xcb_connection.is_err() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Off topic: I was briefly thinking "how can this be an error?!?". Then I looked at the code and saw that x11rb has to parse the .setup()
that the X11 server sent here and that can go wrong (e.g. the server sent a too short setup claiming to contain 10000 screens). libxcb just does not handle this possibility at all...
Now I am happy about all the safety guarantees that Rust provides.
No one will get this, but since you already wrote on this issue: CC @DemiMarie x11rb is the Rust library I was talking about elsewhere (in case you even care about this - if not, that's totally fine as well).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do care! For one, this means that Smithay has a chance to have XWayland support that is robust against malicious X servers, assuming that the X server someday gets sandboxed. That would allow for per-Flatpak X servers that run in the Flatpak sandbox, for example.
Does x11rb use libxcb internally and then validate its output, or does it do everything itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x11rb I believe decodes the events and encodes requests itself, libxcb only being used to read and write across the socket when the XCBConnection is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does x11rb use libxcb internally and then validate its output, or does it do everything itself?
There are two options in x11rb. There is RustConnection
that is pure rust. If you disable the allow-unsafe-code
feature, then you lose support for FD-passing, but get all of Rust's safety guarantees always.
With the allow-unsafe-code
feature, there is also a XCBConnection
. Just as @i509VCB said, this only uses libxcb to send & receive raw bytes (This uses C APIs like xcb_send_request
and xcb_wait_for_event
/ xcb_wait_for_reply
from libxcb). Since libxcb does not provide an extra length return, the code has to look at something like three bytes of an X11 packet and figure out the length of the packet, then call the unsafe function std::slice::from_raw_parts
. Afterwards, the same safe code is used as with RustConnection
. I am pretty sure that these length calculations are exactly the same math as libxcb does internally, but obviously this is a bit less safe than RustConnection
.
XCBConnection
allows sharing the connection with C code that expects a libxcb xcb_connection_t*
(e.g. cairo or mesa). RustConnection
is a Rust-only thing that cannot be used in this way.
I bet no one cares, but x11rb even works on Windows. Obviously, there is no FD passing there.
src/backend/x11/mod.rs
Outdated
x11::Event::Expose(expose) => { | ||
// TODO: We would ideally use this to determine damage and render more efficiently that way. | ||
// | ||
// Although there is an Expose with damage event somewhere? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the question, but I'll try to answer it anyway:
A expose event contains a rectangle that was exposed (x, y, width, height). If a non-rectangular area is exposed (e.g. Two other windows partially cover your window and now your window is brought to front. Thus, these two rectangles are exposed), then two Expose events are sent. The first one contains .count == 1
to indicate that another event will follow.
(And if there were four rectangles, then the first one would have count = 3
, the next one count = 2
etc...)
XCB FFI is no longer necessary and is now no longer included in the backend. |
|
||
Err(err) => { | ||
if let SwapBuffersError::ContextLost(err) = err { | ||
error!(log, "Critical Rendering Error: {}", err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Errors other than ContextLost
are just silently ignored? Is that right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied from winit is the excuse here, probably not a great thing to copy either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewing my own code 🤔
impl AnvilState<X11Data> { | ||
pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) { | ||
match event { | ||
InputEvent::Keyboard { event } => match self.keyboard_key_to_action::<B>(event) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like this could have some deduplication wrt other backends
Also it looks like this needs a rebase now. |
aed87a4
to
431fdce
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor nitpicks, but wow this PR is clean!
I really like it, thanks a lot.
Also there is some stuff, that should be de-duplicated in the future. E.g. X11's buffers share a lot of code with the GbmBufferedSurface, but we can do that later. This PR has gotten big enough.
This pull request is part of series in #293.
The X11 backend is renderer agnostic and imports a dmabuf for presentation to a window. The X11 backend also supplies input events, and events indicating window exposure, close requests and resizing.
This backend requires the X server to have the Xfixes, DRI3 and Present extensions. Namely the DRI3 extension means proprietary nvidia gpus cannot use the backend as the X server does not supply those when running with nvidia gpus.
FreeBSD and Non-Linux
These platforms should work although these were not tested. The only functionality not implemented is resolving another type of
DrmNode
from an existingDrmNode
. This functionality isn't strictly necessary to run the backend but may mean some hardware configurations won't work.