Files
rustdesk/libs/scrap
Mariano Abad d8535f9a50 drm: close the round-17 review findings
- the scanout dma-buf fd is duplicated with F_DUPFD_CLOEXEC. `dup(2)`
  never copies close-on-exec, so this fd was inherited by every child
  the ROOT service forks (it forks synchronously for the loginctl
  active-uid lookup) - and what this fd names is the live screen
  contents. this is the SAME defect already closed on the `_drm`
  socket fd in ipc/drm.rs; fixing that one and not grepping for the
  siblings is how this survived. there is exactly one dup in the drm
  path now and it is this one, verified by grep. measured that
  F_DUPFD_CLOEXEC sets FD_CLOEXEC and preserves the O_RDONLY access
  mode the read-only export depends on; SCM_RIGHTS delivery is
  unaffected since the receiver gets its own descriptor.
- Desktop::refresh resolves HOME on the login-Wayland path too, since
  the drm build now starts a --server as the greeter uid there and a
  child with no HOME has nowhere to put its config. the compositor
  variables stay blank deliberately: the drm path talks to the root
  service and a render node, never to the compositor or the portal,
  which is why it works at a login screen at all. reasoned, not
  measured: a current GDM runs its greeter as `gdm-greeter`, which
  `is_gdm_user` does not match, so that path is not reachable on our
  hardware - measured there, the greeter server gets a fully populated
  environment through the branch below.
- the glibc-floor step globs into an array and asserts the count, like
  its sibling assert step. that sibling was fixed two rounds ago and
  this one was left behind.
2026-07-30 21:00:33 -03:00
..
2025-01-20 17:59:36 +08:00
2021-03-29 15:59:14 +08:00
2026-06-18 22:37:15 +08:00
2021-07-29 13:33:26 +08:00

Derived from https://github.com/quadrupleslap/scrap

scrap

Scrap records your screen! At least it does if you're on Windows, macOS, or Linux.

Usage

[dependencies]
scrap = "0.5"

Its API is as simple as it gets!

struct Display; /// A screen.
struct Frame; /// An array of the pixels that were on-screen.
struct Capturer; /// A recording instance.

impl Capturer {
    /// Begin recording.
    pub fn new(display: Display) -> io::Result<Capturer>;

    /// Try to get a frame.
    /// Returns WouldBlock if it's not ready yet.
    pub fn frame<'a>(&'a mut self) -> io::Result<Frame<'a>>;

    pub fn width(&self) -> usize;
    pub fn height(&self) -> usize;
}

impl Display {
    /// The primary screen.
    pub fn primary() -> io::Result<Display>;

    /// All the screens.
    pub fn all() -> io::Result<Vec<Display>>;

    pub fn width(&self) -> usize;
    pub fn height(&self) -> usize;
}

impl<'a> ops::Deref for Frame<'a> {
    /// A frame is just an array of bytes.
    type Target = [u8];
}

The Frame Format

  • The frame format is guaranteed to be packed BGRA.
  • The width and height are guaranteed to remain constant.
  • The stride might be greater than the width, and it may also vary between frames.

System Requirements

OS Minimum Requirements
macOS macOS 10.8
Linux XCB + SHM + RandR
Windows DirectX 11.1