Skip to main content

Crate drmkit_session

Crate drmkit_session 

Source
Expand description

Holding devices across a VT switch.

A compositor that owns the display cannot simply open /dev/dri/card0 and keep it: switching to another virtual terminal has to take the display away and give it back. A seat – logind, seatd, or a bare-root fallback – is what arbitrates that, handing out descriptors it can revoke.

What arrives from the seat is two events. Paused: stop touching every descriptor immediately, because the ioctls will start failing. Resumed: here are fresh descriptors, and every per-descriptor kernel object you had – framebuffers, property blobs, client caps, GEM handles – is gone. drmkit_cursor::Paused is the shape that pairs with this on the other side.

§Why the backend is a trait

Because a seat cannot be opened on a machine that has no session. Over SSH, in a container, on a CI runner, logind says the session is busy, seatd is not running, and the builtin backend wants root and a TTY. That is most places this code will be built.

So the sequencing – which devices are held, what happens to them across a pause, when the pause is acknowledged, what a caller is allowed to do while inactive – lives in Session over a Backend, and is tested against a fake. The libseat binding is a thin adapter behind the libseat feature; libseat-log, also on by default, routes libseat’s own diagnostics into the log crate.

§Not here yet

Three things the reference has and this does not.

TakeDeviceOpts::preserve_fd_across_resume asks the seat to hand back the same descriptor rather than a fresh one, on the grounds that the capability-revoking backends leave it valid. Plausible, and it saves a reopen per device per switch, but it is an optimisation over a path that is already correct – and getting it wrong means scanning out through a descriptor the kernel has stopped honoring, on a machine none of the CI lanes resemble. It waits for a device to be proved on.

Seat::input_opener routes libinput’s privileged device opens through the same seat, so input descriptors get the revocable lifetime the DRM one has.

Both halves it needs now exist: this crate opens devices through a seat, and drmkit_input::Seat::open takes any LibinputInterface the caller supplies. What is missing is the piece between them — an implementation of that trait backed by a Session, so an input descriptor is revoked and reissued on a VT switch the way the DRM one is. Until it exists a caller passing their own opener gets input descriptors with an ordinary lifetime, which works and is not what the seat is for.

The reference installs its own handler for libseat’s log, at error level, and sends what arrives to drm::log. Here the binding’s handler sends it at debug level to the log crate, which drmkit-log does not read: a caller with no log logger never sees libseat’s reasons for refusing a seat. Taking it over means a C shim, since libseat hands a handler a va_list, and the binding already builds one.

Structs§

DeviceId
A seat’s handle for one open device.
LibseatBackendlibseat
A session backed by libseat.
Session
Devices held across VT switches.
TakenDevice
A device this session is holding.

Enums§

RawEvent
What a seat says, before the session has made sense of it.
SessionError
What can go wrong holding a session.
SessionEvent
What a caller needs to act on.

Constants§

DEFAULT_ENABLE_TIMEOUTlibseat
How long LibseatBackend::open waits for the seat to activate.

Traits§

Backend
What a seat has to be able to do.