blob: 0bde48a2716913a2d4c03df33b1d3bc4d4b75ad8 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_HOST_LINUX_PIPEWIRE_MOUSE_CURSOR_CAPTURER_H_
#define REMOTING_HOST_LINUX_PIPEWIRE_MOUSE_CURSOR_CAPTURER_H_
#include <memory>
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/thread_annotations.h"
#include "remoting/host/linux/gnome_display_config_monitor.h"
#include "remoting/host/linux/pipewire_capture_stream_manager.h"
#include "remoting/protocol/mouse_cursor_monitor.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
#include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h"
#include "third_party/webrtc/modules/desktop_capture/shared_desktop_frame.h"
namespace remoting {
// A class that allows incarnations of PipewireMouseCursorMonitor to capture
// mouse cursor shapes and positions, and get the latest cursor shape before
// it is created. The interface of this class pretty much mirrors
// MouseCursorMonitor.
class PipewireMouseCursorCapturer {
public:
using Callback = MouseCursorMonitor::Callback;
using Mode = MouseCursorMonitor::Mode;
explicit PipewireMouseCursorCapturer(
base::WeakPtr<GnomeDisplayConfigMonitor> display_config_monitor,
base::WeakPtr<PipewireCaptureStreamManager> stream_manager);
~PipewireMouseCursorCapturer();
// Sets a callback and the monitor mode. Pass nullptr to prevent the
// previously set callback from being called.
void SetCallback(Callback* callback, Mode mode);
// Attempts to capture the current mouse cursor and position and calls the
// corresponding methods on the callback. OnMouseCursor() will be called iff
// the cursor has changed, or, this is the first call of Capture() since
// SetCallback() and the latest cursor is available. No-op if callback is
// nullptr.
void Capture();
base::WeakPtr<PipewireMouseCursorCapturer> GetWeakPtr();
private:
struct MonitorInfo {
int dpi;
int width;
int height;
};
void OnDisplayConfig(const GnomeDisplayConfig& config);
std::unique_ptr<webrtc::MouseCursor> ShareLatestCursor();
raw_ptr<Callback> callback_ GUARDED_BY_CONTEXT(sequence_checker_);
bool report_position_ GUARDED_BY_CONTEXT(sequence_checker_);
// If this is set to true, the Capture() call will supply the latest cursor
// when stream->CaptureCursor() returns nullptr (i.e. cursor is unchanged).
// This is set to true in SetCallback() and is set to false at the end of the
// Capture() call.
bool want_latest_cursor_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
std::unique_ptr<webrtc::SharedDesktopFrame> latest_cursor_frame_
GUARDED_BY_CONTEXT(sequence_checker_);
webrtc::DesktopVector latest_cursor_hotspot_
GUARDED_BY_CONTEXT(sequence_checker_);
base::WeakPtr<PipewireCaptureStreamManager> stream_manager_
GUARDED_BY_CONTEXT(sequence_checker_);
std::unique_ptr<GnomeDisplayConfigMonitor::Subscription>
display_config_subscription_ GUARDED_BY_CONTEXT(sequence_checker_);
base::flat_map<webrtc::ScreenId, MonitorInfo> monitors_
GUARDED_BY_CONTEXT(sequence_checker_);
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<PipewireMouseCursorCapturer> weak_ptr_factory_{this};
};
} // namespace remoting
#endif // REMOTING_HOST_LINUX_PIPEWIRE_MOUSE_CURSOR_CAPTURER_H_