A cross-platform C++23 library with a platform-neutral public API and runtime-selected backends: - Input: Wayland virtual pointer/keyboard (Hyprland, wlroots), libei via the RemoteDesktop portal (GNOME, KDE), uinput, and Win32 SendInput - Capture: ScreenCast portal + PipeWire, and Win32 GDI - Windows: Hyprland IPC and Win32 enumeration - Monitors via wl_output/xdg-output and EnumDisplayMonitors - Optional OpenCV template matching (alvin::vision) Also adds the `alvin` CLI, Catch2 unit tests, install rules with find_package(Alvin) support, API docs (docs/API.md and the Obsidian vault), and README instructions for both ways of consuming the library. Windows backends are written but not yet compiled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
73 lines
2.1 KiB
C++
73 lines
2.1 KiB
C++
#pragma once
|
|
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <string_view>
|
|
|
|
#include "alvin/error.hpp"
|
|
#include "alvin/frame.hpp"
|
|
#include "alvin/window.hpp"
|
|
|
|
namespace alvin {
|
|
|
|
enum class CaptureBackend {
|
|
Auto,
|
|
Portal, // xdg-desktop-portal ScreenCast + PipeWire (any modern Wayland desktop)
|
|
Gdi, // Win32 BitBlt / PrintWindow
|
|
};
|
|
|
|
std::string_view toString(CaptureBackend backend) noexcept;
|
|
|
|
enum class CaptureSource : std::uint8_t {
|
|
Monitor = 1,
|
|
Window = 2,
|
|
Any = Monitor | Window,
|
|
};
|
|
|
|
struct CaptureOptions {
|
|
CaptureBackend backend = CaptureBackend::Auto;
|
|
|
|
// What the portal picker offers. On Windows, Monitor + monitorIndex or
|
|
// Window + window select the target directly with no dialog.
|
|
CaptureSource source = CaptureSource::Monitor;
|
|
int monitorIndex = 0;
|
|
std::optional<WindowId> window;
|
|
|
|
bool showCursor = false;
|
|
|
|
// Portal only: token from Capture::restoreToken() of an earlier session.
|
|
// Lets the compositor skip the picker and reuse the previous selection.
|
|
std::string restoreToken;
|
|
std::chrono::milliseconds permissionTimeout = std::chrono::minutes(2);
|
|
};
|
|
|
|
// A live capture of one monitor or window.
|
|
class Capture {
|
|
public:
|
|
static Result<std::unique_ptr<Capture>> create(const CaptureOptions& options = {});
|
|
|
|
virtual ~Capture() = default;
|
|
Capture(const Capture&) = delete;
|
|
Capture& operator=(const Capture&) = delete;
|
|
|
|
virtual CaptureBackend backend() const = 0;
|
|
|
|
// Most recent frame. Blocks until the first frame arrives (up to timeout).
|
|
// Streaming backends only deliver frames when the screen changes, so this
|
|
// does not wait for a *new* frame; use nextFrame() for that.
|
|
virtual Result<Frame> grab(std::chrono::milliseconds timeout = std::chrono::seconds(5)) = 0;
|
|
|
|
// Waits for a frame newer than any previously returned one.
|
|
virtual Result<Frame> nextFrame(std::chrono::milliseconds timeout = std::chrono::seconds(5)) = 0;
|
|
|
|
virtual std::string restoreToken() const { return {}; }
|
|
|
|
protected:
|
|
Capture() = default;
|
|
};
|
|
|
|
} // namespace alvin
|