Expand description
Rust bindings to the XCB library.
The X protocol C-language Binding (XCB - https://xcb.freedesktop.org/) is a replacement for Xlib featuring a small footprint, latency hiding, direct access to the protocol, improved threading support, and extensibility.
The communication is established with the X server by the creation of a Connection object.
A client communicates with the server by sending requests. There are 2 types of requests:
- void requests: requests that do not expect an answer (e.g. x::ChangeProperty)
- non-void requests: requests that need a
Reply(e.g. x::GetProperty)
Requests are passed to the server by filling a request structure e.g. x::CreateWindow and passing it to Connection::send_request.
The server can also communicate with clients by sending Events.
The client listens to events with calls such as Connection::wait_for_event
(blocking) or Connection::poll_for_event (non-blocking).
The x module contains definitions of the core X protocol. Each extension is defined in its own module such as xkb or render, and is activated by a cargo feature of the same name.
§Example
Here is a walk-through of a simple xcb client.
// we import the necessary modules (only the core X module in this application).
use xcb::{x};
// we need to import the `Xid` trait for the `resource_id` call down there.
use xcb::{Xid};
// Many xcb functions return a `xcb::Result` or compatible result.
fn main() -> xcb::Result<()> {
// Connect to the X server.
let (conn, screen_num) = xcb::Connection::connect(None)?;
// Fetch the `x::Setup` and get the main `x::Screen` object.
let setup = conn.get_setup();
let screen = setup.roots().nth(screen_num as usize).unwrap();
// Generate an `Xid` for the client window.
// The type inference is needed here.
let window: x::Window = conn.generate_id();
// We can now create a window. For this we pass a `Request`
// object to the `send_request_checked` method. The method
// returns a cookie that will be used to check for success.
let cookie = conn.send_request_checked(&x::CreateWindow {
depth: x::COPY_FROM_PARENT as u8,
wid: window,
parent: screen.root(),
x: 0,
y: 0,
width: 150,
height: 150,
border_width: 0,
class: x::WindowClass::InputOutput,
visual: screen.root_visual(),
// this list must be in same order than `Cw` enum order
value_list: &[
x::Cw::BackPixel(screen.white_pixel()),
x::Cw::EventMask(x::EventMask::EXPOSURE | x::EventMask::KEY_PRESS)
],
});
// We now check if the window creation worked.
// A cookie can't be cloned; it is moved to the function.
conn.check_request(cookie)?;
// Let's change the window title
let cookie = conn.send_request_checked(&x::ChangeProperty {
mode: x::PropMode::Replace,
window,
property: x::ATOM_WM_NAME,
r#type: x::ATOM_STRING,
data: b"My XCB Window",
});
// And check for success again
conn.check_request(cookie)?;
// We now show ("map" in X terminology) the window.
// This time we do not check for success, so we discard the cookie.
conn.send_request(&x::MapWindow {
window,
});
// We need a few atoms for our application.
// We send a few requests in a row and wait for the replies after.
let (wm_protocols, wm_del_window, wm_state, wm_state_maxv, wm_state_maxh) = {
let cookies = (
conn.send_request(&x::InternAtom {
only_if_exists: true,
name: b"WM_PROTOCOLS",
}),
conn.send_request(&x::InternAtom {
only_if_exists: true,
name: b"WM_DELETE_WINDOW",
}),
conn.send_request(&x::InternAtom {
only_if_exists: true,
name: b"_NET_WM_STATE",
}),
conn.send_request(&x::InternAtom {
only_if_exists: true,
name: b"_NET_WM_STATE_MAXIMIZED_VERT",
}),
conn.send_request(&x::InternAtom {
only_if_exists: true,
name: b"_NET_WM_STATE_MAXIMIZED_HORZ",
}),
);
(
conn.wait_for_reply(cookies.0)?.atom(),
conn.wait_for_reply(cookies.1)?.atom(),
conn.wait_for_reply(cookies.2)?.atom(),
conn.wait_for_reply(cookies.3)?.atom(),
conn.wait_for_reply(cookies.4)?.atom(),
)
};
// We now activate the window close event by sending the following request.
// If we don't do this we can still close the window by clicking on the "x" button,
// but the event loop is notified through a connection shutdown error.
conn.check_request(conn.send_request_checked(&x::ChangeProperty {
mode: x::PropMode::Replace,
window,
property: wm_protocols,
r#type: x::ATOM_ATOM,
data: &[wm_del_window],
}))?;
// Previous request was checked, so a flush is not necessary in this case.
// Otherwise, here is how to perform a connection flush.
conn.flush()?;
let mut maximized = false;
// We enter the main event loop
loop {
match conn.wait_for_event()? {
xcb::Event::X(x::Event::KeyPress(ev)) => {
if ev.detail() == 0x3a {
// The M key was pressed
// (M only on qwerty keyboards. Keymap support is done
// with the `xkb` extension and the `xkbcommon-rs` crate)
// We toggle maximized state, for this we send a message
// by building a `x::ClientMessageEvent` with the proper
// atoms and send it to the server.
let data = x::ClientMessageData::Data32([
if maximized { 0 } else { 1 },
wm_state_maxv.resource_id(),
wm_state_maxh.resource_id(),
0,
0,
]);
let event = x::ClientMessageEvent::new(window, wm_state, data);
let cookie = conn.send_request_checked(&x::SendEvent {
propagate: false,
destination: x::SendEventDest::Window(screen.root()),
event_mask: x::EventMask::STRUCTURE_NOTIFY,
event: &event,
});
conn.check_request(cookie)?;
// Same as before, if we don't check for error, we have to flush
// the connection.
// conn.flush()?;
maximized = !maximized;
} else if ev.detail() == 0x18 {
// Q (on qwerty)
// We exit the event loop (and the program)
break Ok(());
}
}
xcb::Event::X(x::Event::ClientMessage(ev)) => {
// We have received a message from the server
if let x::ClientMessageData::Data32([atom, ..]) = ev.data() {
if atom == wm_del_window.resource_id() {
// The received atom is "WM_DELETE_WINDOW".
// We can check here if the user needs to save before
// exit, or in our case, exit right away.
break Ok(());
}
}
}
_ => {}
}
}
}§Cargo features
The following Cargo features are available
§dl
When this feature is activated, libxcb will be loaded dynamically at runtime with dlopen, instead of using dynamic linking.
§xlib_xcb or xlib_xcb_dl
This feature activates the use of xlib::Display to connect to XCB, therefore making
available both Xlib and XCB functions to the same connection.
While XCB is sufficient to handle all communication with the X server, some things can
still only be done by Xlib. E.g. hardware initialization for OpenGL is done by Xlib only.
Use xlib_xcb_dl instead to load the xlib library dynamically with dlopen.
§debug_atom_names
When this feature is activated, the fmt::Debug implementation for x::Atom will print
out the name of the atom in addition to its value.
E.g. the feature would turn Atom { res_id: 303 } into Atom("Abs Pressure" ; 303).
This can be useful in situations where you are not sure which atom you have to intern in order to look up some data in a reply.
It should be noted that the feature sets global variable to have access to
the connection in the fmt::Debug implementation, and that the Debug print
have side effects (x::GetAtomName requests) which can sometimes not be desirable.
The feature should therefore only be activated when needed.
§libxcb_v1_14
This feature is enabled by default and activates the libxcb API version 1.14. To use a version of the libxcb API prior to 1.14, you must disable it.
§Extension features
The following X extensions are activated by a cargo feature:
| Extension name | Cargo feature |
|---|---|
Composite | composite |
DAMAGE | damage |
DPMS | dpms |
DRI2 | dri2 |
DRI3 | dri3 |
Generic Event Extension | ge |
GLX | glx |
Present | present |
RANDR | randr |
RECORD | record |
RENDER | render |
X-Resource | res |
MIT-SCREEN-SAVER | screensaver |
SHAPE | shape |
MIT-SHM | shm |
SYNC | sync |
XEVIE | xevie |
XFree86-DRI | xf86dri |
XFree86-VidModeExtension | xf86vidmode |
XFIXES | xfixes |
XINERAMA | xinerama |
XInputExtension | xinput |
XKEYBOARD | xkb |
XpExtension | xprint |
SELinux | xselinux |
TEST | xtest |
XVideo | xv |
XVideo-MotionCompensation | xvmc |
Modules§
- bigreq
- The
BIG-REQUESTSextension. - composite
- The
CompositeX extension. - damage
- The
DAMAGEX extension. - dpms
- The
DPMSX extension. - dri2
- The
DRI2X extension. - dri3
- The
DRI3X extension. - ffi
- Module for Foreign Function Interface bindings.
- ge
- The
Generic Event ExtensionX extension. - glx
- The
GLXX extension. - present
- The
PresentX extension. - randr
- The
RANDRX extension. - record
- The
RECORDX extension. - render
- The
RENDERX extension. - res
- The
X-ResourceX extension. - screensaver
- The
MIT-SCREEN-SAVERX extension. - shape
- The
SHAPEX extension. - shm
- The
MIT-SHMX extension. - sync
- The
SYNCX extension. - x
- The core X protocol definitions
- xc_misc
- The
XC-MISCextension. - xevie
- The
XEVIEX extension. - xf86dri
- The
XFree86-DRIX extension. - xf86vidmode
- The
XFree86-VidModeExtensionX extension. - xfixes
- The
XFIXESX extension. - xinerama
- The
XINERAMAX extension. - xinput
- The
XInputExtensionX extension. - xkb
- The
XKEYBOARDX extension. - xprint
- The
XpExtensionX extension. - xselinux
- The
SELinuxX extension. - xtest
- The
XTESTX extension. - xv
- The
XVideoX extension. - xvmc
- The
XVideo-MotionCompensationX extension.
Macros§
- atoms_
struct - An helper macro that generate a struct of atoms.
Structs§
- Auth
Info - Container for authentication information to connect to the X server
- Connection
Connectionis the central object of XCB.- Display
Info - Display info returned by
parse_display - Extension
Data - Extension data as returned by each extensions
get_extension_data. - Lat1Str
- A slice to a Latin-1 (aka. ISO 8859-1) string.
- Lat1
StrF - Latin-1 (aka. ISO 8859-1) of fixed size
- Lat1
String - A struct owning a Latin-1 (aka. ISO 8859-1) string.
- Special
Event - A struct that serve as an identifier for internal special queue in XCB
- Special
Event Id Deprecated - A struct that serve as an identifier for internal special queue in XCB
- Unknown
Error - an error that was not recognized as part of the core protocol or any enabled extension
- Unknown
Event - an event was not recognized as part of the core protocol or any enabled extension
- Void
Cookie - The default cookie type returned by void-requests.
- Void
Cookie Checked - The checked cookie type returned by void-requests.
Enums§
- Conn
Error - Error type that is returned by
Connection::has_error. - Error
- The general error type for Rust-XCB.
- Event
- Unified Event type from the X server.
- Event
Queue Owner - Determines whether Xlib or XCB owns the event queue of
Connection. - Extension
- Refers to a X protocol extension.
- Lat1
Error - Error that can produce Latin-1 string operations
- Protocol
Error - A protocol error issued from the X server
Traits§
- Base
Error - A trait to designate base protocol errors.
- Base
Event - Trait for base events (aka. non GE_GENERIC events)
- Cookie
- General trait for cookies returned by requests.
- Cookie
Checked - A marker trait for a cookie that allows synchronized error checking.
- Cookie
With Reply Checked - A trait for checked cookies of requests that send a reply.
- Cookie
With Reply Unchecked - A trait for unchecked cookies of requests that send a reply.
- GeEvent
- A trait for GE_GENERIC events
- Raw
- Trait for types that own a C allocated pointer and are represented by the data pointed to.
- RawRequest
- Trait implemented by all requests to send the serialized data over the wire.
- Reply
- Trait for request replies
- Request
- Trait implemented by requests types.
- Request
With Reply - Trait for requests that return a reply.
- Request
Without Reply - Marker trait for requests that do not return a reply.
- Xid
- A X resource trait
- XidNew
- Trait for X resources that can be created directly from
Connection::generate_id
Functions§
- cache_
extensions_ data - Returns the extension data for the given extensions. This function may block as the data will be queried from the server if not already cached.
- parse_
display - Parses a display string in the form documented by X (7x).
- resolve_
error ⚠ - Resolve an error from the X server
- resolve_
event ⚠ - Resolve an event from the X server
- unload_
libraries - Unloads any cached dynamic libraries loaded by this crate. Doesn’t prevent another open of the libraries, so should be used after no more calls into this crate occurs, if needed.
Type Aliases§
- Conn
Result - The result type associated with ConnError.
- Protocol
Result - The result type associated with ProtocolError.
- Result
- The general result type for Rust-XCB.