Files
rustdesk/libs/scrap
Mariano Abad 584fac0c6d drm: the same latched-flag bug a fourth time, in my own fix for the third
I built UinputRefreshGuard INSIDE the spawned closure, so it only covered
paths where the closure ran. thread::spawn panics on EAGAIN after the swap,
so no guard existed and the flag stayed set for the process lifetime, which
is the exact failure the guard was introduced to prevent. I then wrote
RefreshSlot correctly - constructed before the spawn, moved in - two hours
later and did not go back to fix its sibling. Both are right now, and the
spawn is fallible in both.

Also from the review:

- DRMTAP_PREBUILT_DIR returned before the EGL-stub assertion, so the check
  only guarded the source build. That is backwards: prebuilt-dir is the
  widest override (no fetch, no sha check, an object this script never sees),
  the likeliest to hand over a stub, and the path our aarch64 cross-build
  actually uses. Verified the assertion accepts a real .so and rejects one
  built with -Degl=disabled.
- convert() bounded only the frame libdrmtap returns, not the descriptor going
  in. offsets/pitches address plane ranges inside the dma-buf, so those are
  what a malformed pair would reach past. Bounded per populated plane, the
  same way the export side is. Defense in depth (the producer is
  root-authenticated and libdrmtap validates against the fd since 0.4.12),
  but the two halves should agree before the C sees the data, not after.
- the flutter patch step used '[[ test ]] && git apply' as its last command,
  so the step would FAIL rather than skip the first time FLUTTER_VERSION
  moves off 3.24.5. Explicit if/else, and the values now come from the
  environment instead of ${{ }} interpolation, which also clears zizmor's
  template-injection warning. Checked both branches.

Declined: the cursor id/cache-key convergence finding. Both accessors use one
selection over one map, so they can only disagree across a publish race, and
state.hcursor is already set to the id ACTUALLY served (drm_served_id), which
is the sync the finding asks for - added in an earlier round.
2026-07-29 21:12:48 -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